Wikipedia scnwiki https://scn.wikipedia.org/wiki/P%C3%A0ggina_principali MediaWiki 1.47.0-wmf.1 first-letter Mèdia Spiciali Discussioni Utenti Discussioni utenti Wikipedia Discussioni Wikipedia File Discussioni file MediaWiki Discussioni MediaWiki Template Discussioni template Aiutu Discussioni aiutu Catigurìa Discussioni catigurìa Purtali Discussioni purtali Pruggettu Discussioni pruggettu TimedText TimedText talk Mòdulu Discussioni mòdulu Evento Discussioni evento Sarausa 0 190 782039 776272 2026-05-13T10:45:48Z GiovanniPen 22308 Rimossa la protezione da "[[Sarausa]]" 776272 wikitext text/x-wiki {{Cumuni| nomucumuni=Sarausa| mmaggini=Siracusa-Stemma.png| muttu=&nbsp;| nomuufficiali=Siracusa| pruvincia=[[Pruvincia di Sarausa|Sarausa]] (SR)| superfici=204| abbitanti=123.595| dinsita=623| cumunilimitrofi=[[Avula]], [[Janiattini]], [[Ciuriddia]], [[Miliddi]], [[Nuotu]], [[Palazzolu Acrèidi]], [[Priolu]], [[San Pàulu (SR)|San Paulu]]| cap=96100| prifissutelefonicu=0931 }} '''Sarausa''' è na cità di 123.595 abbitanti<ref name = abitanti>Dati Istat al 1 gennaio 2008:[http://demo.istat.it/]</ref> ca si trova nta l'est dâ [[Sicilia]], e capulocu dâ stissa [[Pruvincia di Sarausa|pruvincia]]. == Storia == A cità pigghiau u nomu dâ vicina paludi ''Syraka'' nnô [[sèculu VIII a.C.]], quannu a funnaru i Corinzi. Doppu a [[guerra dû Peloponnesu]] sutta [[Dionisiu lu vecchiu]], Sarausa addivintau a cità cchiù mpurtanti dî culonî uccidintali dâ [[Magna Grecia]], arrivannu ad aviri un miliuni d'abbitanti. A mpurtanza dâ cità criscìu macari grazzi ô particulari gurfu chiusu ca nni fa nu portu naturali. [[File:Siracusa-cattedrale.jpg|thumb|left|300px|La cattiddrali di S. Lucia, custruita supra li pilastri grechi dû tempiu di Atena.]] U pirìudu di grannizza dâ cità durau nzinu â fini dâ [[secunna guerra punica]] quannu ntô [[212 a.C.]] Sarausa fu cunquistata dî [[rumani]] cumannati di [[Marcellu]]. <br /> Nni l'èbbica paliucristiana, fu una dî primi cità a siri cristianizzata. Nnô primu sèculu [[Paulu di Tarsu|San Paulu]] passau di Sarausa e â fini dû terzu sèculu nasci a Sarausa [[Santa Lucia]], ca tanta parti appi ntâ [[cristiani]]zzazzioni dô [[mpiru rumanu]]. Nni l'èbbica bizzantina, ntra u [[663]] e u [[668]], Sarausa fu capitali di lu [[mperu bizzantinu]] sutta [[Custanti II]]. Nnô [[768]] u sarausanu [[Stefanu III]] addivintau papa, comu tri autri siciliani prima di iddu ntra u VII e l'uttavu sèculu. Nnô [[827]] appi a subbiri nu primu assediu àrabbu dî truppi di [[Asad al Furat]], ca pirò morsi duranti l'assediu e a cità putìu pi chissu cuntrastari stu primu attaccu. Nnô [[878]] appi a subbìri n'autru assediu tràggicu, ca si cunchiudìu câ cunquista àrabba dâ cità. Sarausa fu allibbirtata dî truppi [[Sicilia (ebbica nurmanna)|nurmanni]] sulu nnô [[1088]]. Versu lu [[1200]] pi quarchi annu fu puru ginuvisi. Cu la fini dû [[mediuevu]] e la prugrissiva mpurtanza ecunòmica e cummirciali di [[Palermu]] comu la storia dâ cità si cunfunni cu la storia dâ Sicilia. U [[tirrimotu dû 11 di jinnaru 1693]] ca nni l'[[Sicilia (èbbica spagnola)|èbbica spagnola]] distrudìu a cità, pirmisi la ricustruzzioni cô stili [[baroccu sicilianu|baroccu]]. Cu l'unità d'Italia e la nnustrializzazzioni purtata avanti nnô vintìsimu sèculu a cità addivintau na cità purtuaria muderna e grazzi ê siti archiulòggichi unu dî siti turistichi cchiù mpurtanti dâ Sicilia. Sarausa è ricanasciuta patrimoniu munniali di valuri ùnicu di l'[[UNESCU]]. {{vidipuru|Storia di Sarausa}} == Munumenta principali == * Lu tiatru grecu di Sarausa chi è unu dî cchiù granni tiatra antichi dû munnu, l'anfitiatru rumanu; l'aricchiu di [[Dionisiu]] fannu parti di lu [[Parcu Archiòloggicu dâ Neapolis di Sarausa]] * l'ìsula di [[Ortiggia]], * lu santuariu dâ Madonna dî làcrimi, * la chiesa di Santa Lucia; * li [[Catacummi di Sarausa|Catacummi]]; * la chiesa di San Giuvanni. == Festi e abbinimenti == {{vidipuru|Festa di Santa Lucia a Sarausa}} Li sarausani sunnu divoti a [[Santa Lucia]], fistiggiata lu [[13 di dicèmmiru]] cu na gran festa e macari lu jocu di focu. La prima Dumìnica di Maiu c'è la festa di [[Santa Lucìa]] dê quagghi, pi ricurdari nu miràculu dâ Santa. Ci fu na [[caristìa]] e li genti murìanu di fami, si mìsiru a prijari ntâ cattidrali e tutta nta na vota trasìu nta chiesa na [[quagghia]] ca purtava na spica di granu nta lu beccu, pirchì ntô portu avìa arrivatu na navi china di [[frumentu]], ca fu a sarvizza dî Sarausani. * 20 jinnaru, Festa di San Bastianu Martiri. * 03 frivaru, Festa di San Blasi. Fistiggiamenti. * Prucissioni dî misteri.<ref>{{Cita|ARCHIVIO STORICO SICILIANO|pp. 173}}.</ref> * 13 dicèmmiru, Festa 'rî Santa Lucia, festa 'râ Patrona. == Pirsunaggi llustri == Pirsunaggi llustri di Sarausa hannu statu [[Archimedi]], [[Giluni]], [[Teocritu]], [[Dionisiu lu vecchiu]], [[Santa Lucia]], [[Giuliu Firmicu Maternu]], [[Papa Stefanu III]], lu patriarca di Costantinòpuli [[San Metodiu di Sarausa|Metodiu di Sarausa]], [[Eliu Vittorini]]. == Parrata == {{vidipuru|Parrata rausana}} Ntâ zona sud dâ pruvincia di Sarausa e ntâ pruvincia di [[Rausa]], tutti li paroli ccâ "ch" si prunùnciunu senza la "h". Accussì avemu: "accianari" nveci di "acchianari", "cciù ssai" nveci di "cchiù ssai", ecc. == Giamillaggi == *[[Image:Flag of Italy.svg|20px|border]] '''[[Erchie]]''' - [[Talia]] *[[Image:Flag of Italy.svg|20px|border]] '''[[Pirùggia]]''' - [[Talia]] *[[Image:Flag of Sweden.svg|20px|border]] '''[[Stoccolma]]''' - [[Svezzia]] *[[Image:Flag of Germany.svg|20px|border]] '''[[Amburgu]]''' - [[Girmania]] *[[Image:Flag of Greece.svg|20px|border]] '''[[Corintu]]''' - [[Grecia]] == Frazzioni == * [[Funtani Janchi]] * [[Cassìbbili (frazzioni)|Cassibbili]] * [[Bedduvidìri]] == Bibliografia == * {{Cita libro |titolo = "''ARCHIVIO STORICO SICILIANO - SOCIETA' SICILIANA DI STORIA PATRIA''" |autore = |url = https://www.google.it/books/edition/Archivio_storico_siciliano/GPZ_dmVh4m8C? |editore = Stabilimento Tipografico di B. Virzì, via Cintorinai, n° 62 |città = Palermo |anno = 1876 |volume = ANNO I, FASCICOLO I |cid = ARCHIVIO STORICO SICILIANO }} == Noti == <references/> == Talìa puru == * [[Museu Bellomu]] * [[Museu archiulòggicu riggiunali Paolo Orsi]] * [[Ànapu]] * [[Killichirioi]] [[Catigurìa:Sarausa| ]] [[Catigurìa:Cità custeri]] 36ly4a5xrsxi8zsl86x4i2inr69dftc 782040 782039 2026-05-13T10:46:58Z GiovanniPen 22308 782040 wikitext text/x-wiki {{Cumuni|nomucumuni=Sarausa|nomuufficiali=Siracusa |pruvincia=[[Pruvincia di Sarausa|Sarausa]] (SR) |superfici=204 |abbitanti=123.595 |dinsita=623 |cumunilimitrofi=[[Avula]], [[Janiattini]], [[Ciuriddia]], [[Miliddi]], [[Nuotu]], [[Palazzolu Acrèidi]], [[Priolu]], [[San Pàulu (SR)|San Paulu]] |cap=96100 |prifissutelefonicu=0931 }} '''Sarausa''' è na cità di 123.595 abbitanti<ref name = abitanti>Dati Istat al 1 gennaio 2008:[http://demo.istat.it/]</ref> ca si trova nta l'est dâ [[Sicilia]], e capulocu dâ stissa [[Pruvincia di Sarausa|pruvincia]]. == Storia == A cità pigghiau u nomu dâ vicina paludi ''Syraka'' nnô [[sèculu VIII a.C.]], quannu a funnaru i Corinzi. Doppu a [[guerra dû Peloponnesu]] sutta [[Dionisiu lu vecchiu]], Sarausa addivintau a cità cchiù mpurtanti dî culonî uccidintali dâ [[Magna Grecia]], arrivannu ad aviri un miliuni d'abbitanti. A mpurtanza dâ cità criscìu macari grazzi ô particulari gurfu chiusu ca nni fa nu portu naturali. [[File:Siracusa-cattedrale.jpg|thumb|La cattiddrali di S. Lucia, custruita supra li pilastri grechi dû tempiu di Atena.]] U pirìudu di grannizza dâ cità durau nzinu â fini dâ [[secunna guerra punica]] quannu ntô [[212 a.C.]] Sarausa fu cunquistata dî [[rumani]] cumannati di [[Marcellu]]. Nni l'èbbica paliucristiana, fu una dî primi cità a siri cristianizzata. Nnô primu sèculu [[Paulu di Tarsu|San Paulu]] passau di Sarausa e â fini dû terzu sèculu nasci a Sarausa [[Santa Lucia]], ca tanta parti appi ntâ [[cristiani]]zzazzioni dô [[mpiru rumanu]]. Nni l'èbbica bizzantina, ntra u [[663]] e u [[668]], Sarausa fu capitali di lu [[mperu bizzantinu]] sutta [[Custanti II]]. Nnô [[768]] u sarausanu [[Stefanu III]] addivintau papa, comu tri autri siciliani prima di iddu ntra u VII e l'uttavu sèculu. Nnô [[827]] appi a subbiri nu primu assediu àrabbu dî truppi di [[Asad al Furat]], ca pirò morsi duranti l'assediu e a cità putìu pi chissu cuntrastari stu primu attaccu. Nnô [[878]] appi a subbìri n'autru assediu tràggicu, ca si cunchiudìu câ cunquista àrabba dâ cità. Sarausa fu allibbirtata dî truppi [[Sicilia (ebbica nurmanna)|nurmanni]] sulu nnô [[1088]]. Versu lu [[1200]] pi quarchi annu fu puru ginuvisi. Cu la fini dû [[mediuevu]] e la prugrissiva mpurtanza ecunòmica e cummirciali di [[Palermu]] comu la storia dâ cità si cunfunni cu la storia dâ Sicilia. U [[tirrimotu dû 11 di jinnaru 1693]] ca nni l'[[Sicilia (èbbica spagnola)|èbbica spagnola]] distrudìu a cità, pirmisi la ricustruzzioni cô stili [[baroccu sicilianu|baroccu]]. Cu l'unità d'Italia e la nnustrializzazzioni purtata avanti nnô vintìsimu sèculu a cità addivintau na cità purtuaria muderna e grazzi ê siti archiulòggichi unu dî siti turistichi cchiù mpurtanti dâ Sicilia. Sarausa è ricanasciuta patrimoniu munniali di valuri ùnicu di l'[[UNESCU]]. {{vidipuru|Storia di Sarausa}} == Munumenta principali == * Lu tiatru grecu di Sarausa chi è unu dî cchiù granni tiatra antichi dû munnu, l'anfitiatru rumanu; l'aricchiu di [[Dionisiu]] fannu parti di lu [[Parcu Archiòloggicu dâ Neapolis di Sarausa]] * l'ìsula di [[Ortiggia]], * lu santuariu dâ Madonna dî làcrimi, * la chiesa di Santa Lucia; * li [[Catacummi di Sarausa|Catacummi]]; * la chiesa di San Giuvanni. == Festi e abbinimenti == {{vidipuru|Festa di Santa Lucia a Sarausa}} Li sarausani sunnu divoti a [[Santa Lucia]], fistiggiata lu [[13 di dicèmmiru]] cu na gran festa e macari lu jocu di focu. La prima Dumìnica di Maiu c'è la festa di [[Santa Lucìa]] dê quagghi, pi ricurdari nu miràculu dâ Santa. Ci fu na [[caristìa]] e li genti murìanu di fami, si mìsiru a prijari ntâ cattidrali e tutta nta na vota trasìu nta chiesa na [[quagghia]] ca purtava na spica di granu nta lu beccu, pirchì ntô portu avìa arrivatu na navi china di [[frumentu]], ca fu a sarvizza dî Sarausani. * 20 jinnaru, Festa di San Bastianu Martiri. * 03 frivaru, Festa di San Blasi. Fistiggiamenti. * Prucissioni dî misteri.<ref>{{Cita|ARCHIVIO STORICO SICILIANO|pp. 173}}.</ref> * 13 dicèmmiru, Festa 'rî Santa Lucia, festa 'râ Patrona. == Pirsunaggi llustri == Pirsunaggi llustri di Sarausa hannu statu [[Archimedi]], [[Giluni]], [[Teocritu]], [[Dionisiu lu vecchiu]], [[Santa Lucia]], [[Giuliu Firmicu Maternu]], [[Papa Stefanu III]], lu patriarca di Costantinòpuli [[San Metodiu di Sarausa|Metodiu di Sarausa]], [[Eliu Vittorini]]. == Parrata == {{vidipuru|Parrata rausana}} Ntâ zona sud dâ pruvincia di Sarausa e ntâ pruvincia di [[Rausa]], tutti li paroli ccâ "ch" si prunùnciunu senza la "h". Accussì avemu: "accianari" nveci di "acchianari", "cciù ssai" nveci di "cchiù ssai", ecc. == Giamillaggi == *[[Image:Flag of Italy.svg|20px|border]] '''[[Erchie]]''' - [[Talia]] *[[Image:Flag of Italy.svg|20px|border]] '''[[Pirùggia]]''' - [[Talia]] *[[Image:Flag of Sweden.svg|20px|border]] '''[[Stoccolma]]''' - [[Svezzia]] *[[Image:Flag of Germany.svg|20px|border]] '''[[Amburgu]]''' - [[Girmania]] *[[Image:Flag of Greece.svg|20px|border]] '''[[Corintu]]''' - [[Grecia]] == Frazzioni == * [[Funtani Janchi]] * [[Cassìbbili (frazzioni)|Cassibbili]] * [[Bedduvidìri]] == Talìa puru == * [[Museu Bellomu]] * [[Museu archiulòggicu riggiunali Paolo Orsi]] * [[Ànapu]] * [[Killichirioi]] == Noti == <references/> == Bibliografia == * {{Cita libro |titolo = "''ARCHIVIO STORICO SICILIANO - SOCIETA' SICILIANA DI STORIA PATRIA''" |autore = |url = https://www.google.it/books/edition/Archivio_storico_siciliano/GPZ_dmVh4m8C? |editore = Stabilimento Tipografico di B. Virzì, via Cintorinai, n° 62 |città = Palermo |anno = 1876 |volume = ANNO I, FASCICOLO I |cid = ARCHIVIO STORICO SICILIANO }} [[Catigurìa:Sarausa| ]] [[Catigurìa:Cità custeri]] 9hq38p7rc4lwr4c1bma6mjpzyjwnhjm Catania 0 296 782032 777277 2026-05-13T10:37:05Z GiovanniPen 22308 782032 wikitext text/x-wiki {{Cumuni|nomucumuni=Catania|nomuufficiali=Catania |muttu=[[Noli offendere Patria Agathae quia ultrix iniuriarum est]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=180 |abbitanti=314.571 |dinsita=1.719,91 |cumunilimitrofi=[[Jaci Casteddu]], [[Belpassu]], [[Carruntini]], [[Gravina di Catania]], [[Lintini]], [[Mascalucìa]], [[Mustarjancu]], [[Motta Sant'Anastasia]], [[San Grigoriu (Catania)|San Grigoriu]], [[San Petru Clarenza]], [[Sant'Àgata li Battiati]], [[Trimmisteri]] |cap=95100 |prifissutelefonicu=095 |riggiuni=[[Sicilia]] }} {{quote|Megghiu di prima rinàsciu di li me cìnniri|Nntistazioni supra la [[Porta Firdinàndia]]|Melior de cinere surgo|lingua=la}} ---- '''''Catania''''' è na cità di 314.571 abbitanti, capulocu di la [[pruvincia di Catania|pruvincia]] ca havi lu sò nomu, e secunna cità dâ [[Sicilia]] pi dinzitati abbitativa; l'abbitanti si chiàmanu '''catanisi'''. Catania è situata ntâ costa urientali dâ Sicilia, bagnata dô [[mari Joniu]], ntô centru di na fertilìssima [[Chiana di Catania|chianura]] curtivata cu agrumi, a mitati strata tra [[Missina]] e [[Sarausa]], ê pedi di l'[[Etna]]. [[{{ns:6}}:Art84.gif|thumb|left|190px|Lu liafanti ([[Lu Liotru|Liotru]]) è lu sìmbulu dâ cità]] S’attrova ntâ fascia dê crimi timpirati e havi nu crima ùnicu ntô munnu cu li nverni miti e li timpiraturi dâ stati ca arrìvanu ntê misi di Lugliu e Austu tra 29&nbsp;°C. e 38&nbsp;°C., ma, siguennu la tindenza ginirali di àutri àrii giugràfichi, nta l’ùrtimi anni s’hà arrivatu chiù spissu a tuccari macari î 48&nbsp;°C. Tuttu lu liturali catanisi è furmatu versu sud, ô latu di Sarausa, di na nfinita spiaggia di [[rina]] chiamata “[[La praja di Catania|praja]]”, ca si stenni pi chilòmitri; è fattu, nveci, di roccia làvica ntâ parti chiù a nord, dâ stazzioni cintrali versu [[Jaciriali]]. Lu funnu dû mari è pulitìssimu e piscusu; pô picca ventu e lu crima miti di tuttu l’annu è, pi l’appassiunati di pisca, pî subbàcquii e pi tutti l'amanti dû mari, nu paradisu. Ntô nvernu si ponnu fari li tradizziunali sports nvirnali ntâ l’Etna, unni ci sunnu dui stazzioni sciìstici a [[Niculosi]]/Chianu Pruvinzali e a [[Linguarossa]]. L’Etna, chê sò 3.269 m. di autizza, è lu chiù àutu vurcanu di l’[[Europa]] e, chî sò 250 coni eruttivi e li sò dui crateri, attrai appassiunati dâ muntagna e studiusi e scinziati ca vèninu pi studiari l’attività vurcànica sempri cuntìnua. == Clima e Sucità == [[{{ns:6}}:Catania Plaja.jpg|thumb|right|220px|Catania ntô nvernu havi nu clima miti e di sòlitu havi picca brutti jurnati]] [[{{ns:6}}:Catania-Etna-Sicilia-Italy-Castielli CC0 HQ1.JPG|thumb|right|220px|Catania vista di l'aèriu]] [[{{ns:6}}:Catania-via etnea.jpg|thumb|right|220px|Â via Etnea]] Catania ntô nvernu havi nu clima miti e di sòlitu havi picca tinti jurnati di [[ghioggia]]; la timpirutura di jornu si manteni ntornu a 14&nbsp;°C. e non è diffìcili ca arriva macari a 20&nbsp;°C.; ntâ stati la timpiratura duranti lu jornu pò superari li 40&nbsp;°C, ma, pi furtuna, di sira l’ària arrifrisca. Di stati si pò attruvari rifriggèriu chî bagni a mari a la scugghera o a la praja: la scugghera è di furmazzioni làvica e ncuminza di Catania cità nzinu a [[Ripostu]], mentri la [[La praja di Catania|praja]] è fatta di na vintina di chilòmitri di [[rina]], ca parti di Catania e và ammeri [[Sarausa]]. Ntô lungumari di Catania, furmatu di scugghera, lu cumuni ci misi tanti passarelli ca pòrtunu ntâ piattafurmi, ditti “solarium ” (sunnu quarchi sei nta tuttu û lungumari,) unni cù egghè si pò mèttiri a pigghiari û suli; c’è misa na scaletta ca dô “sularium” porta rittu-rittu a mari, a mmoddu a l’acqua. Nta un paiseddu nicu-nicu, misu nta ssu lungomari, e ca si chiama San Giuvanni Li Cuti (na vota era un paisinu di piscatura), lu cumuni ci fici na spiaggia câ terra ca cascò ntâ citati quarchi annu fa dô vurcanu. (Tutta la pruvinza fu jincuta di na pòlviri suttilìssima di terra nìura ca vinìa mannata nta l’àutu a ogni sprusioni dâ vucca di l’[[Etna]] e î cristiani caminàvanu ntê strati, ntâ stati, cû l’umbrella). Nunca, nta stu paiseddu, ci fu misa tutta ssa terra e ci fìciru na bedda e suggistiva spiaggia di rina nìura. Sempri a la scugghera, si pò jiri nta unu dê tantìssimi lidi (stabbilimenti barniari) ca jìnchinu tutta la costa, di Catania nzinu ô [[Jaci Casteddu|Casteddu]] o â [[Aci Trizza|Trizza]]. Si non si sapi annatari bonu, oppuru si ssi voli jucari a [[Tammureddu (sport)|tambureddu]], a palla a volu, o nta n’àutru modu pi ngannari û tempu ntra nu bagnu e l’àutru, allura si va â [[La praja di Catania|praja]]. Chista, ncuminzannu di Catania e finu a lu [[Simetu]], è china-china pi quarchi deci chilòmitri di stabbilimenti barneari. Di sira, Catania, arifrisca! Allura, ognunu nesci dâ casa e si va “a pigghiari û friscu”: Cù voli fari na cosa viloci, si nni va ô lungumari, passìa, ncontra n’amicu e si fa quattru chiàcchiri, si pigghia un gilatu ntî Ernestu, ntô Cafe De Paris o a Tavirnetta, oppuru si l’accatta ntô gilataru cû carrittinu; si pò fari macari na passiata 'n centru, a Via Etnea, a pigghiari na vippita ô [[cioscu]]; oppuru si pò jiri a l'arena (cìnima apertu) a vidiri nu firm; Si ssi havi cchiù tempu, si va câ màchina o a parti di mari, agghiri ô [[Jaci Casteddu|Casteddu]], â [[Aci Trizza|Trizza]] o a [[Aciriali|Jaci]], unni ci sunnu na grannìssima quantità di pizzerìi, gilaterìi, risturanti, discutechi a l’apertu, oppuru si pò jiri versu li paisi etnei, a [[Gravina di Catania|Gravina]], [[Mascalucia]], [[Trimmisteri]], [[Niculosi]], [[Pirara]], a [[Zafferana Etnea|Zafirana]], unni macari chisti sunnu chini di gilaterìi, pizzerìi, risturanti, e tantìssimi chiazzi pi stari ddà a “pigghiari friscu”. Ppi tuttu l’annu, Catania è arrusbigghiata macari di notti: lu centru stòricu è sempri chinu di genti ca affudda na grannìssima quantità di pizzerìi e pub, unni si esibbìscinu tantìssimi gruppi musicali, ca hannu fattu ri-battizzari Catania “la Seattle di l’Italia”. Oltri a jiri a manciari quarchi cosa ntê pub e sèntiri nu pocu di mùsica, ci sunnu tantìssimi tiatri, unni si esibbìscinu tutti li maggiuri cumpagnìi tiatrali taliani e tiatri unni dùnunu cummedi dialittali, o tiatru d’avanguardia, o avan-spittàculu, o cabaret; ci sunnu tantìssimi cìnima; ci sunnu dui bowling; ci sunnu pisti di pattinaggiu; ci sunnu tantìssimi discutechi; ci sunnu assai pizzerìi e risturanti câ pista pi l’abballu oppuru cû pianu-bar; ci sunnu cìrculi curturali; cineforum….. A Catania, si pò nèsciri dâ casa e èssiri sicuri d’accuntrari quarchi amicu cu cui passari la sirata. == Stòria == ==== Èbbica pri-greca ==== [[File:OldCatania.png|200px|thumb|right|Catania ndô [[XVI sèculu]]]] '''''2000 a.C. - Li Sicani / XI sec. a.C. - Li Siculi''''' :La prima pupulazioni ca si stabbilìu nta vari punti dû tirritoriu etneu fu chidda dê Sicani. :Versu lu XI sec. a.C. arrivaru macari li Sìculi, ca vinìanu di l'Italia cintrali, e scacciaru li Sicani. ==== Èbbica greca ==== '''''729/278 A.c.''''' - Secunnu nzoccu scrissi lu stòricu grecu [[Tuciditi]], Catania la funnaru nta lu [[VIII sèculu a.C.]] culoni greci ca vìnniru dâ Calcidia, nta l'Eubbea, guidati di Evarcu: chissi, doppu ca funnaru Naxos ntô 734 a.C., cuntinuaru la caminata agghiri sud e, battagghia dopu battagghia, sguminaru li Sìculi criannu li dui cità di Liontini e di Catania. Chiamaru sta cità "Catania" dô grecu "Ka Etnea" (zoè "suttu l'Etna") o, comu dici n'àutra vuci (secunnu lu stòricu grecu Plutarcu), "Katene" (ca 'n grecu anticu significava "grattarola" - zoè "grattuggia" 'n talianu - pirchì lu tirrenu unni idda fu custruita, pi causanza dâ sciara di l'Etna, è aspru e gratta propriu comu na grattarola): di st'èbbica ricurdamu [[Caronda]], chi fu nu cèlibbri liggislaturi. Dô 476 a.C. nfinu ô 278 a.C., Katene è quasi sempri sutta lu dumìniu di Sarausa, ca havi addivintatu nà putenza militari. ==== Èbbica rumana ==== '''''263 a.C. – 476 d.C.''''' - Cu la cunquista rumana dò 263 a.C., a li nizzi dâ prima guerra pùnica, ncuminzò pi Catania n’èbbica di quarchi setti sèculi unni idda pigghiò granni mpurtanza e pristiggiu, finu a lu puntu ca ntô IV sèculu d.C. lu pueta gàllicu Ausoniu, paragunànnula a Sarausa, la metti ntra li primi centri dô mperu rumanu. Catania diventa cità decumana, suggetta a pagari la dècima parti dê sò produzzioni; appoi, ntô 21 a.C., pi vuluntà dû stissu mpiraturi Augustu, comu segnu d'arricunuscenza pi l'ajutu ricivutu quannu chistu havìa luttatu contru Sistu Pumpeu, Catania divintò culonia Rumana. Fu dutata di tiatru e di termi, dô foru e dô circu, dû ginnasiu e di l´anfitiatru, e macari di nu granniusu acquiduttu; ntô mentri si abbissàvanu li difici dû pirìudu grecu, ca avìanu statu danniggiati di tanti guerri e tanti dispatti avuti cu li sarausani. Tra li tracci ancora visibbili ci sunnu li ruvini dû [[foru romanu (Catania)|foru romanu]]. {{vidipuru1|Storia di Catania}} == Eruzzioni e trimoti di Catania == Catania è la citati di l'[[Etna|Èttina]], senza di chista, Catania nun fussi idda, ma n’àutra citati, cu n’àutra stòria, cu n’àutra cultura e àutri abbitanti. L’Ettina ô spissu hà traditu la sò cità facennu scìnniri ciumi di lava nfucata finu a intra li sò mura, s’hà ripigghiatu li tirritori, hà scancillatu nta nenti zoccu l’òmini avianu apprima fabbricatu; ma Catania non s’hà arrinnutu e ogni vota hà rifabbricatu chiddu ca la [[Etna|muntagna]] s’hava pigghiatu, e anzi chiossai. Di l'èbbica di quannu s'hannu avutu tistimunianzi stòrichi nzinu a oggi, l’Èttina appi quarchi 150 granni eruzzioni, e di chissi 6 arrivaru intra li mura dâ cità; àutri danni s’èppiru pî trimoti ntô [[1169]] quannu nu trimotu (e marimatu) fici trimari tutta la Sicilia urientali, facennu danni assai ntê cità di Catania, [[Mòdica]], [[Lintini]] e [[Chiazza Armerina]] e ntô [[1693]], quannu nu [[Tirrimotu dû 11 di jinnaru 1693|granni trimotu]] sdirubbò cumpretamenti, ortri a Catania, menza Sicilia; àutri danni ci foru ntô[[1818]] pri nu trimotu dû vurcanu. {{vidipuru1|L'ùrtima distruzzioni di Catania}} {{vidipuru1|Trimotu di l'Etna dô 1818}} === Li culati làvichi === [[{{ns:6}}:Etna eruzione.jpg|thumb|right|200px|Èttina - Na ricenti eruzzioni]] [[{{ns:6}}:Etna_eruzione_1669_platania.jpg‎|thumb|right|200px|L'eruzzioni dû 1669 nta na stampa di l'èbbica.]] Ntô 693 a. C. na culata làvica distruggiu l'antica Katane; <br /> ntô 475 a.C., s’eppi ancora na scinnuta di lava nzinu a Catania: lu fattu veni arricurdatu nta [[la liggenna di li frati pii]], unni dui frati, Anfinomu e Anapia, mìsiru 'n salvu li ginitura paralìtichi, purtànnuli ntê spaddi ammenza la lava ca, ô passaggiu d’iddi, s’arritirava pri miràculu;<br /> ntô 396 a. C. n’àutra eruzzioni fici arrivari la lava nzinu o mari mpidènnucci ê cartagginisi, cumannati dô cundutteru Imilconi, di navicari pô liturali jônicu p’agghicari a Catania, vinnenu di [[Naxos]];<br /> ci fu, appoi, l'eruzzioni dô [[1381]], unni lu ciumi di lava agghicau ntâ citati, nzinu a intra û mari di Ògnina, cummigghiannu lu stòricu [[Portu Ulissi (Ògnina)|portu di Ulissi]] (scalu di l’Ògnina); <br /> n'eruzzioni ntô [[1444]] minazzò Catania tantu era abbunnanti la culata di la lava: pi miràculu, la culata si frimmò d’avanti a lu velu di [[Sant'Àita]] purtatu 'n prucissioni ntê vicinanzi di la culata, 'n cuntrata " [[Sant'Àgata li Battiati#Nàscita di lu nomu ntra storia e liggenna|"Terra di S. Àjta"]];<br /> chidda ca fu la culata cchiù disastrusa pi Catania, s’eppi ntô [[1669]]: tanti paisi foru distrutti, lu primu fu [[Niculosi]], appoi [[Belpassu]], [[Mumpileri]], [[Mascalucia]], [[Campurutunnu]], [[San Giuvanni Galermu]], [[San Petru Clarenza]]. Dopu di chissi, lu ciumi di lava si jttau apprima ntâ l'abbitatu di [[Misterbianco|Mustarijancu]] e di ddocu calau pi Catania, dô latu dû punenti. Lu 15 d’aprili trasìu ntâ valli di Anìcitu (oggi Nìcitu) e ntô lacu umònimu (lacu di Nìcitu) ca era ô centru. La lava continuau pâ sò caminata scavarcannu li mura dâ cità, cummigghiau li Vastiuni di S. Giorgiu e di S. Cruci, li fussati dô casteddu Ursinu, vurricau li 36 canali dô ciumi [[Amenanu]] e agghiuncìu lu mari, caminannu pi quarchi dui chilòmitri d’intra a iddu. Catania si spopulò e di li 20.000 abbitanti n’arristaru ntâ cità sulu 3.000, mentri ca l'àutri, urmai senza cchiù casa, circaru rifuggiu nta àutri lochi. {{vidipuru1|L'ùrtima distruzzioni di Catania pi lava}} === La ricustruzzioni doppu lu tirrimotu dû 1693 === [[{{ns:6}}:Catane Université.jpg|thumb|left|120px|Catania - Universitati - Barcuni Baroccu]] Dopu lu trimotu dû [[11 di jinnaru]] dû [[1693]] a Catania sùbbitu si metti manu a la [[ricustruzzioni]]. Lu viciré ci detti la nùmina a vicàriu ginirali pi la “Val Demone” e doppu macari pi la “Val di Notu”, cu putiri chini, a [[Giuseppi Lanza]], duca di Camastra, ca s'attrovò accussì cô còmpitu di ricustruiri 77 cità distrutti dô trimotu, e una di chisti era Catania. Ntô [[1694]] priparau “û pianu ginirali” . Foru pruggittati chiazzi novi, strati larghi, e, ''“li citatini facìanu la gara pi ricustruiri casi e palazzi pi tuttu lu tracciatu ca l’auturità avìanu signatu”'', comu lassau scrittu lu stòricu binidittinu [[Vitu Amicu]]. Pi tutto lu '700 la citati è nu granni canteri, ca attrai populazioni e travagghiatura, ca rimetti n motu l’ecunumìa, ca pirmetti a tanti architetti di l’èbbica di spirimintari novi tècnichi e novi stili (l’architetti catanisi Alonzo di Benedetto e Francesco Battaglia, Girolamo Palazzotto di Messina, lu palermitanu [[Giuvan Battista Vaccarini]], e appoi lu tuscanu [[Stefanu Ittar]] e tanti àutri). Ntra tutti chissi Vaccarini è chiddu ca lassau l’òpiri chiù beddi. {{vidipuru1|Ricustruzzioni di Catania doppu lu tirrimotu dû 1693}} === L'Antichità === {|width=200 style="clear:right;float:right; margin: 0em 0em 1em 1.5em; border:1px solid #000000;" |-style="text-align:center; font-size: 80%;" |[[{{ns:6}}:Anfitiatru Catania.jpg|190px]] |- | style="text-align:center;" | <font size="3">'''[[Antichità di Catania]]'''</font> |- style="border-bottom:1px solid; background: #EEE; font-size: 90%; text-align:center;" |-style="font-size: 85%;" | style="text-align:center;" | [[Siti anchiològgichi di Catania#Anfitiatru rumanu di Catania|Anfitiatru rumanu di Catania]]<br /> [[Siti anchiològgichi di Catania#Tiatru rumanu di Catania|Tiatru rumanu di Catania]]<br /> [[Siti anchiològgichi di Catania#Odeon|Odeon]]<br /> [[Siti anchiològgichi di Catania#Termi Achilliani|Termi Achilliani]]<br /> [[Foru rumanu (Catania)|Foru rumanu]] |} Dâ sò funnazzioni la cità di Catania hà statu distruggiuta dâ lava pi setti voti ntâ storia, e sutta la cità di oggi, s'attròvanu la cità [[Mperu Bizantinu|Bizzantina]], la cità [[Mperu Rumanu|Rumana]] chi la pricedi e chidda [[Grecia antica|Greca]], ancora prima. Ricenti scavi fatti d’intra a lu Casteddu Ursinu, ca n èbbica antica era assai cchiù vicinu ô mari di quantu è oggi, attruvaru strutturi e matiriali grechi antichi, ca hannu statu datati tra la fini di lu VIII e l’inizzi dô VII sèculu a.C., e si poti attribbuìrili a la nàscita di la culonia greca di Catania.<br /> Accussì comu a ssi ritruvamenti, macari 'n cima a l’acròpuli – unni c’è oggi la chiazza Danti e lu granni munasteru binidittinu di San Nicolò l’Arena – s’attruvaru strutturi e matiriali grechi dô VII sèculu a.C.<br /> C’è di diri, ancora, ca, sempri nta li stissi scavi, supra la cullina di l’acròpuli, s’attruvaru tanti tracci di prisenza di òmini duranti lu pirìudu preistòricu, spiciarmenti a l’etati di lu neulìticu e dô rami.<br /> Trasennu di l' [[Anfitiatru rumanu di Catania|Anfitiatru]], â chiazza [[Stesìcuru]], si pò visitari, scinnennu ntô sottasolu, na parti dâ cità rumana, ca, partennu dâ stissa chiazza, si stenni pi tanti strati dâ cità muderna e nta tanti posti dâ cità è pussìbbili scìnniri ntô sottasolu, ca diciunu fu tistimoni di ntrichi amurusi tra sori e frati, postu bonu p'ammucciàrisi li bricanti e trisoru pi l'amanti dî cosi d'arti Sutta lu solu lâvicu citatinu s'attrova ancora oggi la cità dô cincucentu, chê sò strati, li cresî, li termi, li palazzi e macari li targhi chê noma dê strati, ca la lava dô [[1693]] vurricò, sarvànnula pi cu è ca la voli attruvari ntô futuru. == Econumìa == Catania havi nu [[portu]] cummirciali, n'[[àriuportu]] ntirnazziunali (ca era saputu sèntiri comu Fontanarossa comu a lu nomi dû quarteri unni s'attrova, mentri la nova àriustazzioni, 'n unuri a lu "cignu di Catania" si chiama "[[Vincenzu Bellini]]"), [[stazzioni firroviaria|stazzioni firruviari]] statali (lìnia [[Missina]]-[[Sarausa]], Catania-[[Gela]], Catania-[[Palermu]]) e non, comu la ''[[Firrovia Circumetnea|Circumetnea]]'', lìnia a [[Ferrovia a scartamentu ridottu|scartamentu ridottu]] chi gira pi 110&nbsp;km tornu tornu a l'[[Etna]] agghicannu a 976 m s.l.m. pi poi scìnniri, e truvari la costa n'àutra vota a [[Giarri]]-[[Ripostu]] ô nord. == Cultura == L'[[università di Catania]] è la prima [[università]] dâ [[Sicilia]] e vinni funnata ntô [[1434]] grazzi a [[Alfonso V d'Aragona]]. Accamora è una di li cchiù granni e mpurtanti d'Italia: ci studìanu 66.000 carusi, chi vèninu di tutta la [[Sicilia]], ma assai vèninu puru dû cuntinenti, dâ [[Grecia]] e dô [[mediu orienti]]. [[File:Catani6.jpg|thumb|left|200px|Lu domu di Sant'Àita a Catania.]] [[File:Cataniateatrobelliini1893.jpg|left|thumb|200px|Lu Tiatru Bellini versu lu 1893]] A Catania nasceru [[Giuvanni Verga]], [[Luiggi Capuana]] e [[Federico De Roberto]], ntra li megghiu scrittura taliani dû [[sèculu XIX]]. Verga fu lu megghiu scritturi [[verismu|verista]], cu lu rumanzu ''I Malavoglia''. Ntra li pueti ca usaru lu [[lingua siciliana|sicilianu]], ci sù [[Bartolomeo Asmundo]], [[Domenico Tempio]] e [[Ninu Martoglio]]. N'àutru scritturi veru mpurtanti fu [[Vitalianu Brancati]] ca scrivìu macari lu libru "Il bell'Antonio"; ntô 1960 lu riggista [[Mauro Bolognini]] fici un film supra sta storia cu [[Marcello Mastroianni]] e [[Claudia Cardinale]]. Chissa fu a primu pillìcula girata tutta a Catania unni si pò vìdiri la città com'era ntî l'anni sissanta. Catania è macari la patria di [[Vicenzu Bellini]], auturi di ''La Norma'' e àutri cumpunimenti musicali. Li cantanti [[Franco Battiato]], [[Carmen Consoli]], [[Gianni Bella]], [[Marcella Bella]], [[Mario Venuti]], Vincenzu Spampinato, Mariu Biondi, [[Gerardina Trovato]], Umbertu Balsamo e I Beans (Pier Paolo Cristaldi, Carmelo Morgia, Pippo Panascì, Tony Ranno e lu novu ca trasìvu Alex Magrì) sù tutti catanisi. N'àutru granni dâ mùsica catanisi è [[Brigantony]], ca è lu patri dâ mùsica pupulari doppu l'anni '70/'80. Appressu a iddu arrivaru [[Giuseppe Castiglia]], li [[Brigantini]] e àutri novi gruppi: Sugarfree, Lautari e Archinue'. Lu gruppu musicali [[Uzeda]] nascìu macari iddu a Catania e addivinìu lu gruppu europeu cchiù mpurtanti dâ scena nnipinnenti a [[Seattle]] duranti la mità di l'anni nuvanta, cammora dui di li membri origginali dô gruppu nni fìciru n'àutru ca si chiama Bellini, macari iddu veru famusu ntô cuntinenti e 'n [[Amèrica]] macari, pi fàrici omaggiu ô granni cumpusituri catanisi. È la cità a cchiù àuta [[Tiatri di Catania|dinzitati tiatrali]] dâ [[Sicilia]]. Diversi cumpagnìi tiatrali òpiranu, travàgghianu e si fannu canùsciri ntô cuntinenti. == Tradizzioni == [[{{ns:6}}:Sagata ct.jpg|thumb|right|200px|La ''"vara"'' di [[Sant'Àita]].]] Catania è puru la patria di [[Sant'Aita|Sant'Àita]], vissuta ntô [[sèculu III]], assicutata dî rumani prima di l'[[Edittu di Custantinu]] e oi patrona dâ cità. Ogni annu, a [[frivaru]] è festa granni cu cirimoni, prucissioni e manifistazzioni vari. La citati di Catania nun è carattirizzata sulu ppi la prisenza di l’[[Etna]], ca la si vidi custantimenti di unni egghè cu lu sò granni conu, ca si nni senti sempri la cumunioni nta tutti li cosi: ntê casi fatti cu la sò petra, ntê strati fatti chî bàsuli di lava, nta costa uni lu mari addisegna scurturi nta li scogghi nìuri di petra lava. Catania è macari la citati di la [[Sant'Àita|'''Santuzza''']], di [[Sant'Àita|'''Sant’Àita''']] e a idda li [[catanisi]] ci fannu granni fistiggiamenti tutti l’anni dô 3 o 5 di frivaru, e chista è tra li cchiù pittureschi festi di l’[[Italia]]: pi tri jorna la citati si scorda tutti li cosi e tutti l’affanni e si cuncentra sulu pi la festa a [[Sant'Àita|'''Sant’Àituzza''']]: î cannalori, àuti e granni ciri di lignu ntagghiati, 'n prucissioni furianu pi tutti li strati e unni ci sparunu la [[muschittaria]] e ci fannu lu focu, si fèrmanu e appoi ci fannu ''l’annacata'' (ca è na speci d’abballata); pi tutta la citati si vìdunu assai divoti vistuti cu lu saccu jancu; si vìdunu cintinara di migghiara di cristiani ca vènunu di tutti î gnuni, tutta la citati veni addubbata a festa: luminara nta tutti li strati, tutti li chiesi venunu nciùrati, î nuciddara chî carrittini acculurati, î picciriddi chî palluncini, î granni cu l’abbiti novi, î carusi comu ègghè, cu ncùnatizzi e cu tutti puliti, î gilatara nta ogni chiazza; e appoi li fochi ô chianu e la ''vara'' di [[Sant'Àita|'''Sant’Aita''']] ca veni purtata 'n prucissioni pi la cità e, tra li spari e li fraguri di li fochi artificiali, tutti s’arricordunu ca idda, martirizzata nta la braci, vìgila sempri supra lu focu di la [[Etna|Muntagna]]. Mmènzu a la fudda ca si mungi nta li strati e nta li chiazzi, i “citatini” tirannu lu curduni, guidanu la ''vara'' di [[Sant'Àita|'''Sant’Aita''']], e sunnu chiù assai di quattru mila tutti cu lu saccu jancu e ogni tantu, mmenzu a chisti, si senti na vuci forti ca grida '''''citatini, tutti divoti tutti!''''' e tutti arrispunnunu comu na sula vuci: '''''"Viva Sant'Àita, viva Sant'Àita"'''''. == La parrata catanisa == {{vidipuru1|Parrata catanisa}} La [[parrata catanisa]] si distingui nun sulu pi na ntunazzioni tìpica ca la fa arricanusciri e distinguiri tra àutri parrati dû sicilianu, ma pi paroli tìpichi comu ''annunca''. Na variazzioni tipica dâ parrata catanisa arrispettu a àutri è ca la cunzunanti doppu na ''r'' veni radduppiata: * “articulu” veni prununzatu “atticulu” * “corda” veni prununzata “codda” * “ carta” veni prununzata “catta” == Giamillaggi == *[[Image:Flag of United States.svg|20px|border]] '''[[Phoenix]]''' - [[Stati Uniti di Mèrica]] *[[Image:Flag of France.svg|20px|border]] '''[[Grenoble]]''' - [[Francia]] *[[Image:Flag of Canada.svg|20px|border]] '''[[Ottawa]]''' - [[Canadà]] *[[Image:Flag of Poland.svg|20px|border]] '''[[Oświęcim]]''' - [[Pulonia]] *[[Image:Flag of England.svg|20px|border]] '''[[Oxford]]''' - [[Nglaterra]] *[[Image:Flag of Tanzania.svg|20px|border]] '''[[Migole]]''' - [[Tanzania]] == Talìa puru == * [[Liggenni, pirsunaggi, stori e cunti e cosi di Catania.]] * [[Casteddu Ursinu]] * [[Cumuni dâ pruvincia di Catania]] * [[Etna]] * [[Calciu Catania]] * [[Museu Emiliu Grecu (Catania)|Museu Emiliu Grecu]] {{Commons|Catania}} [[Catigurìa:Cumuni dâ pruvincia di Catania]] [[Catigurìa:Storia siciliana]] [[Catigurìa:Cità custeri]] [[Catigurìa:Catania| ]] gix08f4xzwtnntmu8wjhzu9fhqjfpui Ciumifriddu 0 2208 782033 775891 2026-05-13T10:38:33Z GiovanniPen 22308 782033 wikitext text/x-wiki {{Cumuni|nomucumuni=Ciumifriddu|nomuufficiali=Fiumefreddo di Sicilia |articulustemma=[[Stemma cità di Ciumifriddu|Stemma di Ciumifriddu]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=12 |abbitanti=9.581 |dinsita=798 |cumunilimitrofi=[[Calatabianu]], [[Màscali]], [[Piadimunti]] |cap=95013<ref>[https://www.ilcapdi.it/catania/fiumefreddo-di-sicilia CAP di Ciumifriddu, Catania]</ref> |prifissutelefonicu=095 }} '''Ciumifriddu''' è un cumuni di 9.581 abbitanti dâ [[pruvincia di Catania]]. Lu cumuni di Ciumifriddu, pigghia lu sò nomu di l'ômonimu ciumi appressu lu paisi. S'attrova vicinu li centri turistici di [[Etna (vurcanu)]], [[Giardini-Naxos]] e [[Taormina]], e cummirciali di [[Giarri]], [[Ripostu]] e [[Aciriali]]. Lu tirritoriu di Ciumifriddu apprisenta n'area di 12,05 Kmq (1205 ettari). Cunfina a l'Est cû [[mari Ioniu]], a l'Ovest cû cumuni di [[Piemunti]], ô Nord cu chiddu di [[Calatabianu]] e ô Sud cu chiddu di [[Mascali]]. [[File:Castello degli schiavi.jpg|350px|right|thumb|Lu Casteddu dî schiavi: unni veni ricurdata quarchi scena famusa dâ pillicula, ''Lu Patruni''.]] == Tradizzioni == * 20 jinnaru, Festa di San Bastianu Martiri, festeggiamenti. == Note == <references /> [[Catigurìa:Cumuni dâ pruvincia di Catania]] mp9bbb2tork7ob36d6kniyhywsub49i Jaci Bonaccossi 0 2274 782035 775288 2026-05-13T10:40:34Z GiovanniPen 22308 782035 wikitext text/x-wiki {{Cumuni|nomucumuni=Jaci Bonaccossi|nomuufficiali=Aci Bonaccorsi |articulustemma=[[Stemma dê citati dâ Terra di Aci|Stemma di Jaci Bonaccossi]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=1 |abbitanti=2.536 |dinsita=2.536 |cumunilimitrofi=[[Jaci Sant'Antoniu]], [[San Giuvanni la Punta]], [[Bedduvirdi]], [[Varanni]] |cap=95020 |prifissutelefonicu=095 }} '''Jaci Bonaccossi''' (o '''Aci Bonaccossi''' e chiamatu simpricimenti '''Bunaccursi''' ntâ parrata lucali) è un cumuni di 2.536 abbitanti dâ [[pruvincia di Catania]]. Jaci Bonaccossi assetta 211 Km. di [[Girgenti]] (Agrigento), 139 Km. di [[Nissa]] (Caltanissetta), 12 Km. di [[Catania]], di quali pruvìncia apparteni, 108 Km. di [[Castrugiuvanni]] (Enna), 84 Km. di [[Missina]], 261 Km. di [[Palermu]], 116 Km. di [[Rausa|Raùsa]], 70 Km. di [[Sarausa|Saraùsa]] (Siracusa), e 368 Km. di [[Trapani|Tràpani]]. Lu cumuni avi n'aria di 170 ettari e la dinzitati d'abbitazzioni fa 1.470 abbitanti pi chilòmitru quadratu. Si nni acchiana inta na zona di coddi custali e posta a 362 metri supra lu liveddu di lu mari. Jaci Bonaccossi è nu centru pasturali e avanta na pruduzzioni di li citrati e li racini. Nutàbbuli è la pruduzzioni di li tìpici tumazzi siciliani ca si pòtinu tastari duranti l'annuali "Sagra della Ricotta." Ogni annu nna li misi d'aprili e maiu cc'è puru nu spittàculu intirissanti di li chianti e di li ciuri. Lu nomu Aci Bonaccorsi veni di l'antica cuntrata di Bonaccorsi ca nzèmmula cu li paisi di Paoli, Leoni e Battiati, detti l'orìggini di lu territtoriu prisenti nna lu XVI sèculu. Nun cc'è nuddu [[infurmazzioni]] di stu burgu prima lu [[1170]]. Di lu [[XIV seculu]] lu burgu appartinni a li Prìncipi di Campofiorito. Circa lu [[1625]] fu tinutu di la famigghia nòbbili Diana pi lu tìtulu di marchisi. Cci ristetti sinu a l'abbulizzioni di li diritti fiuali. Tra li tanti beddi munumenti è la Chiesa della Consolazione, ricca d'affrischi di li [[1700]]. Si trova puru la Funtana frabbicata nna lu [[1952]] ca teni la scrizzioni in rilevu li "Scogli dei Ciclopi" ca signìfica li "scogghi di li Ciclopi." == Tradizzioni == * 26 dicèmmiru, Festa dî Santu Stefanu, festa dû Patronu. [[Catigurìa:Cumuni dâ pruvincia di Catania]] 4h29ue5aupg9467275lfyttj1j4ui0s Jaciriali 0 2348 782037 776485 2026-05-13T10:43:42Z GiovanniPen 22308 782037 wikitext text/x-wiki {{Cumuni|nomucumuni=Jaciriali|nomuufficiali=Acireale |articulustemma=[[Stemma cità di Aci Riali|Stemma di Jaciriali]] |pruvincia=[[Pruvincia di Catania|Catania]] (CT) |superfici=39 |abbitanti=51.601 |dinsita=1.246 |cumunilimitrofi=[[Jaci Casteddu]], [[Jaci Catena]], [[Jaci Sant'Antoniu]], [[Giarri]], [[Ripostu]], [[Santa Vinirina]], [[Zafarana Etnea]] |cap=95024 |prifissutelefonicu=095 }} '''Jaciriali''' (o '''Aciriali''' spissu accurzatu n '''Jaci''' o '''Aci''') è un cumuni di 51.601 abbitanti dâ [[pruvincia di Catania]]. == Giugrafia == Jaciriali assetta 215 km di [[Girgenti]] (Agrigento), 143 km di [[Nissa]] (Caltanissetta), 16 km di [[Catania]], di quali pruvincia apparteni, 108 km di [[Castrugiuvanni]] (Enna), 80 km di [[Missina]], 265 km di [[Palermu]], 120 km di [[Rausa|Raùsa]], 74 km di [[Sarausa|Saraùsa]] (Siracusa), e 372 km di [[Trapani|Tràpani]]. Lu cumuni havi n'aria di 3.996 èttari e la denzitati d'abbitazzioni fa 1.290 abbitanti pi chilòmitru quadratu. Si nni acchiana inta na zona di coddi costali e posta a 302 metri supra lu liveddu di lu mari. Jaciriali pruduci n'[[abbunnanza]] robbusta di citrati, ciriali, virdura, e frutta. Assai sviluppata è la criscenza di vacchi e pècura. Si pòtinu gòdiri li prudotti lucali nna l'annuali “Fiera del Bestiame” di giugnettu. Na specialitati di l'artiggiani è chidda fatta n ferru di bàttiri e n petra làvica, a causa di lu locu supra nu territoriu làvicu. Li raccami fatti a manu sunnu puru di mpurtanza notàbbili. Lu nomu '''Aci''' veni di la palora greca '''Akus'''. Signìfica "penitranti" e fa riferimentu a la friggidizza di lu ciumi di lu stissu nomu, chiddu ca fu cuvertu di na ciumara làvica. Duranti l'èbbica rumana fu chiamatu '''Aquilia'''. Fu distruttu di nu terrimotu nna lu 1169 e tannu rifabbricatu cu lu nomu '''Aquilia Nuova'''. [[Mmàggini:Acireale.jpg|left|Jaciriali ntî na viduta storica.]] Nna lu 1326 lu paìsi fu trasutu e bruciatu di lu rei Robertu di Nàpuli. Li citatini scapparu nta na cullina vicina unni fu funnatu lu prisenti centru. Nna lu 1642 fu battizzatu di lu rei Filippo IV "Città Regia" d'unni vinni lu propiu nomu '''Jaciriali'''. Fu distruttu arreri di nu terrimotu nna lu 1693. Doppu, si sviluppau assai e criscìu cchiù granni cu la fabbricazzioni di tanti monumenti e centri culturali. Cci sunnu tanti esempii di particulari intiressi architettònici. Lu rumànicu-gòticu Duomo di lu [[sèculu XIV]] cunzerva la cappella di Santa Venera e la so statua d'argentu. La Chiesa di San Sebastiano teni na facciata di tìpicu stilu baroccu di lu [[sèculu XVII]]. Cc'è puru La Basilica dei Santi Pietro e Paolo di lu 1600. Li cchiù nottàbbili struttura nta lu centru urbanu sunnu lu Palazzo comunali di lu [[1659]], quali cunzerva nu riccu portali, e lu Palazzo Modò cu maravigghiusi mènzuli illustrati. Lu stabbilimentu di li Termi di Santa Venera offri na facciata niuclàssica di lu [[1873]]. L'abbitanti sunnu chiamati "[[Acitanu|acitani]]" o "[[Jacitanu|jacitani]]" 'n sicilianu e "acesi" (o "acitani") 'n talianu. '''[[Aci Plàtani]]''' (o '''Jaci Plàtani''') è na frazzioni di Jaciriali. Jaciriali si dici "Jaci" n dialettu catanisi. N'do 2008 [[Miriam Leone]], na picciotta ca a "Jaci" sta n'do centru storicu, vinni eletta Miss Italia. Prima ancora idda ava statu a regina du [[Cannaluvari]] di Acireale, lu cchiu famusu di Sicilia Jaci veni muntuata pi dû mutivi: # U cannaluvari pû quali fannu na festa ca è bedda assai; # Li Termi, unni li genti si nni vannu pi fàrisi u bagnu di fangu. == Tradizzioni e manifestazzioni == * 20 jinnaru, Festa di San Bastianu Martiri, festa liturgica e prucissiunali. * 03 frivaru, Festa 'rî San Blasi. Fisteggiamenti. * Carnalivari di Jaciriali. Sfilati di carri e corsi mascarati. * Rappresentazzioni pasquali ducumintati.<ref>{{Cita|Giuseppe Pitrè|pp. 19}}.</ref> * 13 giugnu, Festa di Sant'Antoniu di Pàduva. Fistiggiamenti. * 29 sittèmmiru, Festa di San Michele Arcanciulu. Fistiggiamenti. == Gimillaggi == * [[Image:Flag of Argentina.svg|20px|border]] '''[[Mar del Plata]]''' - [[Argintina]] * [[Image:Flag of Italy.svg|20px|border]] '''[[Viareggiu]]''' - [[Talia]] == Talìa puru == * [[Aci e Galatea]] liggenna Jacitana * [[Pietru Paulu Vasta]], pitturi acisi == Note == <references/> == Bibliografia == * {{Cita libro |titolo = "''DELLE SACRE RAPPRESENTAZIONI POPOLARI IN SICILIA MEMORIA DI GIUSEPPE PITRE' ''" |autore = Giuseppe Pitrè |url = https://www.google.it/books/edition/Delle_sacre_rappresentazioni_popolari_in/Ije64-yk-vEC |editore = Stabilimento Tipografico di B, Virzì |città = Palermo |anno = 1876 |volume = Unico |cid = Giuseppe Pitrè }} [[Catigurìa:Cumuni dâ pruvincia di Catania]] llc9ise4otq3oq9ogwndfq6acxejrwz Catigurìa:Cumuni dâ pruvincia di Catania 14 2552 782031 756864 2026-05-13T10:35:04Z GiovanniPen 22308 added [[Category:Pruvincia di Catania]] using [[Help:Gadget-HotCat|HotCat]] 782031 wikitext text/x-wiki Elencu dî 58 '''cumuni dâ [[pruvincia di Catania]]''' [[Catigurìa:Cumuni dâ Sicilia|Catania]] [[Catigurìa:Pruvincia di Catania]] gmd5diawpbno1ae76g3ahk96dptysyr Jaci Casteddu 0 2553 782041 775648 2026-05-13T10:47:53Z GiovanniPen 22308 782041 wikitext text/x-wiki {{Cumuni|nomucumuni=Casteddu|nomuufficiali=Aci Castello |articulustemma=[[Stemma dê citati dâ Terra di Aci|Stemma dô Casteddu]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=8 |abbitanti=17.854 |dinsita=2232 |cumunilimitrofi=[[Jaci Catena]], [[Aciriali]], [[Catania]], [[San Grigoriu]], [[Bedduvirdi]] |cap=95021<ref>[https://www.ilcapdi.it/catania/aci-castello CAP di Aci Castello, Catania]</ref> |prifissutelefonicu=095 }} [[{{ns:6}}:Castello_aci.jpg|thumb|Lu casteddu di Jaci]] '''Casteddu di Jaci''' (o '''Aci Casteddu''' e chiamatu simpricimenti '''Casteddu''' ntâ parrata lucali) è un cumuni di 19.122 abbitanti dâ [[pruvincia di Catania]]. L'abbitanti si chiamanu ''castiddisi''. Casteddu di Iaci assetta 208 km. di [[Girgenti]] (Agrigento), 136 km di [[Nissa]] (Caltanissetta), 9 km di [[Catania]], di quali pruvincia apparteni, 105 km. di [[Castrugiuvanni]] (Enna), 87 km di [[Missina]], 258 km di [[Palermu]], 113 km di [[Raùsa]], 67 km di [[Saraùsa]] (Siracusa), e 365 km di [[Tràpani]]. Lu cumuni havi n'aria di 865 èttari e la dinzitati d'abbitazzioni fa 2.210 abbitanti pi chilòmitru quatratu. Si nni acchiana nta na zona chiana e posta a 15 metri supra lu liveddu di lu mari. È na stazzioni mpurtanti marìttima pupulari pi lu turìsimu. Casteddu di Iaci avanta na ricca pruduzzioni di citrati, alivi, racini, mènnuli, e ciriali. Assai sviluppata è la criscenza di vacchi comu cunziquenza di l’abbunnanza di pàsculu. Na spicialitati di l’artiggiani lucali è chidda fatta di lignu. Lu nomu Casteddu di Iaci veni di lu stissu casteddu assittatu supra na vicina cullina di petra làvica. Fu fabbricatu nna lu [[1076]] di li Nurmanni. Lu primu burgu si sviluppau ntornu a lu casteddu e fu traslucatu di lu conti Ruggeru a li vìscuvi di Catania. Circa lu [[1170]] fu cumpritamenti disruggiutu di nu tirrimotu. Nun prima di lu [[1530]] fu ripupulatu cu l’annissioni di li vicini paìsi di Ficarazzi e [[Aci Trizza]]. Nna lu [[1647]] appartinni a la famigghia nòbbili Massa, unni ristetti sinu l’abbulizzioni di li diritti fiudali. La Cresia Matri è di particulari ntiressi architittònicu a causa di li nutàbbili affreschi òpiri di Pietro Vasta (1697-1760). Lu Casteddu nurmannu alluggia nu museu fabbricatu cu petra làvica pruvinenti di lu [[Etna (vurcanu)|Muncibbeddu]]. Na nota ntirissanti è ca lu primu cafè littirariu di tutta [[Europa]] si grapìu in [[Francia]] e vinni funnatu nna lu [[1686]] di ''Procopio dei Coltelli'', nativu di Aci Trezza, òi nu quarteri di Castiddu di Iaci. Si chiamau ''Cafè Procope'' pi fari canùsciri nni ddi banni lu megghiu megghiu gilatu sicilianu. L'affascinanti paìsi di Aci Trezza è puru mpurtanti di lu puntu di vista littirariu. Fu misu nni lu granni rumanzu di [[Giuvanni Verga]] "I Malavoglia". L'abbitanti sunnu chiamati "[[castiddisi]]" 'n sicilianu e "castellesi" 'n talianu. [[{{ns:6}}:Acicastello 900.JPG|thumb|center|790px|Jaci Casteddu a l'inizzi dô '900]] == Noti == <references/> [[Catigurìa:Cumuni dâ pruvincia di Catania]] m6296ak9tle7xuq3je2l6mhrvoz7yks Jaci Sant'Antoniu 0 2555 782042 776254 2026-05-13T10:48:57Z GiovanniPen 22308 782042 wikitext text/x-wiki {{Cumuni|nomucumuni=Jaci Sant'Antoniu|nomuufficiali=Aci Sant'Antonio |articulustemma=[[Stemma cità di Aci Sant'Antoniu|Stemma Aci Sant'Antoniu]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=14 |abbitanti=15.664 |dinsita=1119 |cumunilimitrofi=[[Jaci Bonaccossi]], [[Jaci Catena]], [[Aciriali]], [[Bedduvirdi]], [[Varanni]], [[Zafarana]] |cap=95025 |prifissutelefonicu=095 }} '''Jaci Sant'Antoniu''' (o '''Aci Sant'Antoniu''' e chiamatu simpricimenti '''Sant'Antoni''' 'ntâ parrata lucali) è un cumuni di 15.664 abbitanti dâ [[pruvincia di Catania]]. Jaci Sant'Antoniu assetta 212 km di [[Girgenti]] (Agrigento), 140 km di [[Nissa]] (Caltanissetta), 13 km di [[Catania]], di quali pruvincia apparteni, 105 km di [[Castrugiuvanni]] (Enna), 83 km di [[Missina]], 262 km di [[Palermu]], 117 km di [[Raùsa]], 71 km di [[Saraùsa]] (Siracusa), e 369 km di [[Tràpani]]. Lu cumuni avi n'aria di 1.427 èttari e la denzitati d'abbitazzioni fa 1.074 abbitanti 'ppî chilòmitru quadratu. Si 'nni acchiana 'ntâ nâ zona di coḍḍi costali e posta a 302 metri supra lu liveddu di lu mari. [[File:Sicilian artigiana 2.jpg|thumb|left|Una giovane artigiana siciliana prepara la scena di un presepe vivente a Santa Maria La Stella, Antichi Mestiere, 2005.]] È nu granni centru d'agricultura, famusu 'ppî la ricca pruduzzioni di citrati, olivi, e frutta. Pruduci l'òttimi racina e duranti lu misi d'augustu si poti tastari li prudotti 'nna l'annuali Mostra di li vini tìpici siciliani. Assai sviluppatu è la criscenza di vacchi e cavaddi. 'Nâ specialitati di l'artiggiani locali è la fabbricazzioni di li famusi “Carretti Siciliani” e di li “Sponde” cu vignetti di li battagghi e li successi di li paladini francisi. Lu nomu Aci Sant'Antoniu veni di l'antica Chiesa ca nun cc'è 'cchiù, dedicata a lu santu di lu stissu nomu. Lu primu centru nascìu duranti l'èbbica mediuevali. Fu distruttu di li ciumara làvichi di lu Muncibeddu nna li 1169, 1329, e 1408. Fu rifabbricatu adaciu adaciu e fu tenutu prima di li nòbbili Platamonte, e tannu di la famigghia Moncada. Lu propiu centru d'abbitazzioni vinni funnatu nna lu 1672 tra la voluntati di lu prìncipi Luigi Riggio. Lu burgu fu danniggiatu arreri di nu terrimotu nna lu 1693 e soffrìu di n'autru lentu rinascimentu. Cc'è qualchi monumentu 'ntâ lu cumuni, lu Duomo rifabbricatu doppu lu 1693 cu 'na facciata di stilu baroccu, e la Chiesa di San Michele quali cunzerva diversi òperi di l'artista Vasta (1697-1760). Lu Palazzo Riggio e lu Palazzo Spitaleri, tutti dui fabbricati nna lu 1700, sunnu di notàbbili 'ntiressi architettònici. Tra li pirsunaggi distinti santantonisi è lu mèdicu Antonio Musumeci (1876-1964) cui ricivìu e detti assistenza a li vìttimi nna lu terrimotu di lu 1908 nta la vicina Missina. == Tradizzioni == * 03 frivaru, Festa 'rî San Blasi. Fisteggiamenti. * 29 sittèmmiru, Festa dî San Michele Arcanciulu. Fisteggiamenti. [[Catigurìa:Cumuni dâ pruvincia di Catania]] leudz136qzgy4hepeirlzj8x0rc5qbo Biancavilla 0 2558 782043 750348 2026-05-13T10:49:36Z GiovanniPen 22308 782043 wikitext text/x-wiki {{Cumuni|nomucumuni=Biancavilla|nomuufficiali=Biancavilla |articulustemma=[[Stemma cità di Biancavilla|Stemma di Biancavilla]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=70 |abbitanti=21.846 |dinsita=312 |cumunilimitrofi=[[Adranu]], [[Belpassu]], [[Bronti]], [[Castigghiuni di Sicilia]], [[Centorbi]], [[Malettu]], [[Niculusi]], [[Patennò]], [[Ragalna]], [[Rannazzu]], [[Sant'Arfiu]], [[Santa Marìa di Licuddìa]], [[Zafarana]] |cap=95033 |prifissutelefonicu=095 }} '''Biancavilla''' (o '''Biancavidda''' nta àutri parrati siciliani) è un cumuni di 21.846 abbitanti dâ [[pruvincia di Catania]]. L'abbitanti sunnu chiamati "[[biancavilloti]]" ntâ parrata siciliana lucali mentri sunnu chiamati "biancaviddoti" a [[Catania]]. == Storia == Ntô passatu lu paisi aera canusciuta cû nomu di "Callicari". Quannu funnarunu lu paisi, u ficiru picchi era na bona zona e macari picchi fu lu signu divinu dilla Madunnuzza da Limosina, che si rici se impigghio nterra. Iennu avanti li rifugiati ficiru un paisi, ca poi vinni sutta lu baruni Moncada. Lu baruni manu manu canciò li tempi e la barunia di li terri vinni a li viddani quannu Santapau e Centelli fimmarunu li carti da "licenzia populandi". Lu nomi do paisi vinni in Callicari, e dopu Casali de greci ma sulu dopu a dedica a Rigina Ianca di Navarru pigghiau lu nomi di Biancavidda, ù chiù sicuru toponimu do paisi. [[Catigurìa:Cumuni dâ pruvincia di Catania]] l5fok0ztr0eu4l45kbvsqtcul38283h Bronti 0 2559 782045 754181 2026-05-13T10:52:57Z GiovanniPen 22308 782045 wikitext text/x-wiki {{Cumuni|nomucumuni=Bronti|nomuufficiali=Bronte |articulustemma=[[Stemma cità di Bronti|Stemma di Bronti]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=249 |abbitanti=18.496 |dinsita=74 |cumunilimitrofi=[[Adranu]], [[Belpassu]], [[Biancavilla]], [[Castigghiuni di Sicilia]], [[Centorbi]], [[Risarò]], [[Lonci]], [[Malettu]], [[Maniàci]], [[Niculusi]], [[Rannazzu]], [[Sant'Arfiu]], [[Turturici]] (ME), [[Truina]] (EN), [[Zafarana]] |cap=95034 |prifissutelefonicu=095 }} '''Bronti''' è un cumuni di 18.496 abbitanti dâ [[pruvincia di Catania]]. L'abbitanti sunnu chiamati "[[bruntisi]]" 'n sicilianu e "brontesi" 'n talianu. == Storia == All'èbbica svevu-nurmanna, la citâ uspitau nu munasteru basilianu ca chê sêculi addivintau unu dî munumenti cchiû mpurtanti dâ zona. Ntô [[1798]], lu ''casteddu'' di Brotni vinni datu a [[Horatio Nelson]] pi li sô sirvizza ô re [[Firdinannu IV di Burboni|Firdinannu]]. Nelson stissu fu numinatu [[duca di Bronti]]. U paisi è appoi canusciutu pi n'episodiu controversu dâ storia dô [[Risorgimentu]], la rivolta di Bronti. === La rivolta di Bronti === Lu [[8 di austu]] [[1860]] li cuntadini di Bronti, capiggiati di Nicola Lombardu, si ribbillarunu occupannu li terri dê latifonnisti. Nonostanti la ripartizzioni equa dê terri avia statu prumittuta di [[Giuseppi Garibbaldi|Garibbaldi]], la rivolta fu riprimuta di [[Ninu Bixiu]]; Lombardu e autri participanti forru ammazzati di Bixiu stissu. == Econumìa == L'econumia di Bronti, comu chidda dî centri dâ riggiuni, si basa n parti supra l'agricultura. Bronti è canusciutu ntî tuttu lu munnu pi la produzzioni dû [[pistacchiu]], riputatu pi essiri di una dî megghiu qualitati, pi li fichi r'india grossi e i castagni. [[Catigurìa:Cumuni dâ pruvincia di Catania]] ipmqmsoe9jl5fo5lufqk7i8gb03fikv Cattabbianu 0 2560 782046 750629 2026-05-13T10:54:09Z GiovanniPen 22308 782046 wikitext text/x-wiki {{Cumuni|nomucumuni=Cattabbianu|nomuufficiali=Calatabiano |articulustemma=[[Stemma cità di Cattabbianu|Stemma di Cattabbianu]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=26 |abbitanti=5.197 |dinsita=200 |cumunilimitrofi=[[Castigghiuni di Sicilia]], [[Ciumifriddu]], [[Giardini-Naxos]], [[Linguarossa]], [[Piemunti]], [[Taormina]] |cap=95011 |prifissutelefonicu=095 }} '''Cattabbianu''' è nu cumuni talianu di 5.197 abbitanti dâ [[pruvincia di Catania]]. Cattabbianu s'attrova nnâ parti sittintriunali di la pruvincia di Catania vicinu lu ciumi [[Alcantara]], unni chissu arriva ntô mari. Lu paisi è a picca chilòmitri di [[Taurmina]]. Li sò orìgini sunnu àrabbi: chissi funnaru Cattabianu supra lu monti Casteddu, ca dòmina l'abbitatu. Vìnniru poi li [[Nurmanni]], li Spagnoli e li [[Borbone]]. Doppu lu tirrìbbili tirrimotu di lu [[1693]], lu casteddu venni abbannunatu e la pupulazzioni detti orìggini a un novu paisi nnâ chiana. Li maggiuri risorsi di Cattabianu sunnu l'agricultura e lu turismu. [[File:Calatabiano 01.jpg|thumb|Panurama di Cattabbianu]] [[Catigurìa:Cumuni dâ pruvincia di Catania]] b0qc1uw7bl446uzi3cu5lud42h8zzgt Caltaggiruni 0 2561 782047 775665 2026-05-13T10:57:06Z GiovanniPen 22308 782047 wikitext text/x-wiki {{Cumuni|nomucumuni=Caltaggiruni|nomuufficiali=Caltagirone |articulustemma=[[Stemma cità di Caltaggiruni|Stemma di Caltaggiruni]] |muttu=''Urbs Gratissima'' (''Città bonu vuluta''), ''La Rîna dî Munti Erei'' |riggiuni=[[Sicilia]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=383,38 |abbitanti=35 709 |dinsita=93,14 |cumunilimitrofi=[[Acati|Vischiri]], [[Gela]], [[Grammicheli]], [[Licuddìa]], [[Mazzarinu]], [[Mazzarruni]], [[Miniu]], [[Mirabella Imbaccari|Li Maccara]], [[Niscemi]], [[Chiazza]] , [[Sammicheli]] |cap=95041 |prifissutelefonicu=0933 }} '''Caltaggiruni''' (''Caltagirone'' nnû talianu) è nu cumuni di 35 709 abbitanti dâ [[Pruvincia di Catania|Città metrupolitana di Catania]]. È luntana 68 km dû sò capulocu pruvinciali Catania e 195 km dû sò capulocu riggiunali [[Palermu]]. È lu quintu cumuni cchiù populatu dâ Città metrupolitana catanisi e lu primu pi grandizza tirritoriali. Caltaggiruni è ntrê 25 cumuna dâ Sicilia pi pupulazziuni e lu quintu pi grandizza dû sò tirritoriu. A liveḍḍu riliggiusu, specialmenti pi zoccu cuncerni la riliggiuni cristiano-cattòlica, Caltaggiruni è sedi piscupali (Piscupatu di Caltaggiruni, nnû talianu ''Diocesi di Caltagirone'') dû 1816. È storicamenti capulocu di'n grandi cumprinsoriu tirrituriali, chiamatu nnû talianu ''Calatino e Sud-Simeto'' (macari canusciuti comu li ''paisa caltaggirunisa''), chi è nnâ parti miridiunali di l'enti metrupolitanu di oji. [[File:Chiesa di San Francesco d'Assisi all'Immacolata (1535729032).jpg|miniatura|Chiesa di San Francescu â Mmaculata]] [[File:Countryside between Caltagirone and Piazza Armerina, Sicily, Italy.jpg|miniatura|Paisaggiu di campagna ntra Caltaggiruni e [[Ciazza (Enna)|Chiazza]]]] Centru urbanu misu cintralmenti ntrâ Sicilia cintrali, chiḍḍa urîntali e lu liturali miridiunali, è celebbri pâ pruduzziuni dâ ciramica, la quali la renni lu majuri centru riggiunali e unu dî cchiù mpurtanti d’Italia. Fu pi ultra dui millenni nu puntu stratèggicu di cuntrollu pi assai populi chi contrullavanu li chiana di Catania e Gela, ntra di cui li greci, li bizzantini, l'arabbi, li ginuvisa, li ràunisa e li nurmanni. È vidè nu mpurtanti centru agriculu, pî so grandi campagni, comu Chianu Sampòlu, Costabbaira, lu Nuci, lu Mazzuni, Racineci e Rannasìa. Lu centru storicu avi lu titulu di Patrimoniu di l’umanità UNESCO dû 2002, facenti parti dû consorziu du Vaḍḍ'i Notu, nzemmula ê città di [[Catania]], [[Militeddu (Catania)|Militeḍḍu]], [[Scicli]], [[Modica]], [[Rausa]], [[Notu (Sarausa)|Notu]] e [[Palazzolu Acrèidi]]. {{vidipuru1|Cullina di Sant'Ippòlitu (Caltaggiruni)}} == Etimoluggia dû nomu == L'etimoluggìa dû nomu diriva di l'àrabbu: si sapi chi la prima parola significa ''casteḍḍu'' (qal'at), ma l'àutra parti è di etimoluggia chi nun è canusciuta, e nun si sapi pi certu zoccu putissi significari; pi chistu mutivu, li studiusi, cchiù o menu titulati, ànu prupunutu assai significati, chi ponu purtari â storia greca (picciò Casteḍḍ'i Gela o Casteḍḍ'i gilisi), â storia midîvali (Casteḍḍ'i ginuvisi) u ô tirritoriu 'n quantu tali (Casteḍḍ'i grutti, Casteḍḍ'i cignali, Casteḍḍ'i quartari, ecc.) === Lu paisi oji === [[File:Piazza Bellini, Caltagirone (CT).jpeg|sinistra|miniatura|Chiazza Bellini, unu dî posta cchiù canusciuti dû centru novu di Caltaggiruni, nfacci ô viali Mariu Milazzu]] Oji, ultra lu celebbri centru storicu, la città avi vidè n'area abbitata di età recenti, misa a sud-ovest, unni putemu truvari alcuni mpurtanti vî, palazzi, lochi e chiazzi centrali dâ città. Chista parti dâ città è oji lu cori urbanu dû cumuni, unni a majurìa dî pirsuni abbitanu (quasi 20 000 ncapu picca cchiù di 35 000 pirsuni). La città, nnâ sò storia ricenti, mustràu sempri l'ambizziuni di essiri capulocu di na sò pruvincia chi fussi cchiù o menu lu tirritoriu dî paisa caltaggirunisi (''Calatino e Sud-Simeto'' nnâ lingua taliana), accussì comu la vicina Gela chî sò paisi di l'area gilisi. È lu secundu centru dâ Sicilia cintrali cu cchiù abbitanti, dopu Cartanissetta e davanzi cumuna comu [[Caniattì]], [[Adranu|Dirnò]] e [[Castrugiuvanni|Castruggiuvanni]]. == Frazziuna == Pâ grandizza dû sò tirritoriu, Cartaggiruni avi diversi frazziuna, arcuni di chisti sunu luntani dicina di chilometri dâ città. Li cchiù canusciuti e mpurtanti sunu: * [[Granieri]] (frazziuni li cui abbitanti veninu dê cumuna dâ pruvincia di [[Rausa|Ràusa]]) * [[Santu Petru (frazzioni)|Santu Petru]] (frazziuni ca si sviluppàu 'n facci ô boscu omonimu) * Chianu Sampòlu (frazziuni agricula a quarcu chilometru dû paisi) * Favareḍḍa (frazziuni li cui abbitanti sunu [[Grammicheli|grammichilisi]]) == Giamillaggi == Ntrî parentisi sunu scritti o la riggiuni (nnû casu dâ Talia) o l'unità amministrativi fidirali si nnû paisi adintificatu asisti. *[[Image:Flag of Venezuela.svg|20px|border]] '''San Diego''' - [[Venezzuela|Vinizzuèla]] (Carabobo) *[[Image:Flag of Greece.svg|20px|border]] '''Kallikrateia''' - [[Grecia]] *[[Image:Flag of United States.svg|20px|border]] '''[[San Franciscu]]''' - [[Stati Uniti di Mèrica|Stati Uniti dâ Mèrica]] (Califurnia) *[[Image:Flag of Germany.svg|20px|border]] '''Arnsberg''' - [[Girmania]] (Nord Renu-Vistifalia) *[[Image:Flag of Malta.svg|20px|border]] '''Mdina''' - [[Malta]] *[[Image:Flag of Palestine.svg|20px|border]] '''Bittilemmi''' - [[Palistina|Autorità Nazziunali Palistinisi]] *[[Image:Flag of Italy.svg|20px|border]] '''Abbadìa Larana''' - [[Talia]] (Lummardìa) == Nasciuti a Caltaggiruni == Chista è na lista nun cumpleta di pirsuni chi nàppiru o crisciru a Caltaggiruni: * Don [[Luiggi Sturzu]], parrinu, funnaturi dû Partitu Pupulari Talianu, sinaturi a vita dâ Ripubblica Taliana *Mariu Sturzu, frati di Luiggi Sturzu, piscupu di [[Ciazza (Enna)|Chiazza]] *Carmelu Carìstia, diputatu dâ Ripubblica Taliana pâ Dimucrazzia Cristiana *Giambattista Fanales, diputatu dâ Ripubblica Taliana pû Partitu Comunista Talianu *Gnaziu Muntimagnu, piscupu di Girgenti *Juseppi Missina, riggista cinematograficu *Nnucenzu Marcinnò, riliggiusu *Francescu Parisi, senaturi dâ Ripubblica Taliana * [[Domenicu Semineriu|Duminicu Semineriu]], scritturi *Antuninu Raguna o Ràuna, studiusu dâ ciramica *Nicola Longubardi, gisuita missiunariu â Cina *[[Silvio Milazzo|Silviu Milazzu]], puliticu già presidenti dâ [[Riggiuni Siciliana]] e funnaturi dâ Uniuni Siciliana Cristianu Suciali *[[Mariu Scelba]], puliticu già presidenti dû [[Prisidenti dû Cunsigghiu dî Ministri Italiani|Cunsigghiu dî Ministri]] dâ Rippubblica Taliana e vidè già Ministru dô Ntiriuri. *Gisualdu Climenti, medicu e prufissuri, già Magnificu Ritturi dâ [[Univirsitati di Catania]] *Saveriu Fragapani o Frâpani, architettu *Gualteru di Caltaggiruni, nobbili e puliticu dû periudu dî [[Vespri siciliani|Vespri Siciliani]] *Ottavia Pinna Buscemi, pulitica, diputata dâ Assemblea Costituenti dâ Ripubblica Taliana pû Fronte dell'Uomo Qualunque *Salvaturi Castagna, ginirali militari *Paulu Ciuḍḍa, fàusaru di muneta *Marianu Giaquinta o Jaquinta, matimaticu *Jacupu Rannazzu, diriggenti sportivu, già presidenti dâ [[Atalanta Bergamasca Calcio|Atalanta Bergamasca]] *Alessiu Narbuni, gisuita e storicu *Mariu Sampirisi, jucaturi di [[Palluni (sport)|palluni]], difinsuri dû Monza *Nicole Grimàudu, attrici pû cinema e la televisiuni == Dialettu == [[File:Piazza Umberto (1495440361).jpg|miniatura|232x232px|Chiazza Umbertu I: si vidi la Cattidrali e lu Munti di Pietà]] A Caltaggiruni, ntrê secula [[Seculu XIX|XIX]] e [[Seculu XX|XX]], in virtù di l’[[Risurgimentu|unificazziuni nazziunali]] e dâ diffusiuni di menza di communicazziuni di massa visiva e stampata, l’usu dâ [[lingua taliana]] si allargàu in quasi tutti l'abbitanti e vidé in registra diversi di chiḍḍi furmali. La [[lingua siciliana]] pirò è vidè presenti, nnâ sò varianti cittatina. La so varietà lucali, lu '''''caltaggirunisi''''', è 'n dialettu di transizziuni, chi avi elementa urîntali ( cunzidirati comu lìati ô catanisi, ma pigghiati dû missinisi) e èlimenta cintrali (famigghia di dialetta a unni appirtenunu chiḍḍi di [[Castruggiuvanni]] e [[Nissa]]). Avi forti nfluenza ligguri (prubabbilmenti [[Savuna|savunisi]]). Comu'n autri dialetta dû sicilianu, sunu prisenti nfluenzi dî lingui [[Lingua spagnola|castigghiana]], [[Lingua catalana|catalana]], [[Lingua occitana|pruvinzali]], bèrbira, tuscana e [[Lingua greca|greca]], ultra a prestiti dû talianu e vidè du [[Lingua ngrisa|nglisi]]. === Asempi scritti === Sutta ci stanu arcuni asempi scritti, lu primu è lu primu articulu da Dichiarazziuni Universali dî diritta di l'Omu dî Nazziuna Uniti, lu secunnu è lu prìara cristiana dû [[Patri nostru|Patri Nostru]], lu terzu è la fabbula dû Lupu e l'Agneḍḍu dû scritturi di fabbuli grecu Èsupu: '''Dichiarazziuni Universali di li diritti di l'Omu''' ''"Ì crìstijani nasciunu tutti lìbbiri e tutti ì stìssi, pi dignità e dirìtti.'' ''C'ànu u stìssu ciribeḍḍu e cuscienza, e s'han'a cumpurtari 'ntra ri ìḍḍi comu si fussuru frati râ stìssa matri."'' ==== Patri nostru ==== ''Patri nostru, chi sï ndû cełu,'' ''Santiffijatu vè u nommu tò,'' ''vinìssi prestu u tò regnu,'' ''sempri fatta vè a tò vułuntà,'' ''comu ndû cełu accussi 'n terra.'' ''Danni oggi u nostru pani cutidijànu,'' ''e levini ì nostri debbita'' ''<nowiki/>'ccussï comu nuatri ì tugghìmu'' ''ê debbitura nostri.'' ''E nun ni bbannunari ndâ tentazzijoni,'' ''ma lìbbirini dû màłi, AMEN.'' '''Lu lupu e l'agneḍḍu di Ésupu''' ''Un lupu e nu gneḍḍu, morti di sìti, jungìru a bìviri ô stìssu sciumi.'' ''Ncapu v'era u lupu, cchiù sutta v'era u gneḍḍu.'' ''Ḍḍura, ḍḍu disgranijatu dû lupu, chi c'avìa a panza vacanti, si circà a sciarra cû gneḍḍu e c'à dìttu:'' ''-Disgranijatu, ti lèvi di ḍḍocu chi mi sta lurdannu tutta l'acqua!'' ''E u gneḍḍu ci rispunnï:'' ''-'Un ti siḍḍijari, vìri chi tò mi sta lurdannu l'acqua, chi passa prìma di tìa!'' ''U lupu, ch'ava caputu chi v'era 'dû tortu, c'à dittu:'' ''- He sintutu chi sï mìsi fa m'à sparratu cu l'ammìci!'' ''E u gneḍḍu contrubbattï:'' ''- Ma ìu sï mìsi fa mancu ava natu, chi mi sta dicennu?'' ''E câ raggia dâ fami, prima di bbirarissìllu, c'à dittu:'' ''- E ḍḍura à statu ḍḍu porch'i tò pa' a sparrarimi.'' ''E dopu, senza mancu vìririci si l'à bbiratu e si l'à spurpatu tuttu sanu.'' ''Sti paroli l'àn'a sentiri tutti i crìstijani chi cunnannunu ì nnucenti gnustamenti.'' == Tradizzioni == * '''Giunta''.<ref>{{Cita|ARCHIVIO STORICO SICILIANO|pp. 170}}.</ref> * 26 dicèmmiru, Festa dî Santu Stefanu, fisteggiamenti citàdini. == Noti == <references/> == Bibliografia == * {{Cita libro |titolo = "''ARCHIVIO STORICO SICILIANO - SOCIETA' SICILIANA DI STORIA PATRIA''" |autore = |url = https://www.google.it/books/edition/Archivio_storico_siciliano/GPZ_dmVh4m8C? |editore = Stabilimento Tipografico di B. Virzì, via Cintorinai, n° 62 |città = Palermo |anno = 1876 |volume = ANNO I, FASCICOLO I |cid = ARCHIVIO STORICO SICILIANO }} [[Catigurìa:Cumuni dâ pruvincia di Catania]] pfsoxrfh6qeq0hp2mdhxuevwlfp7zbn Campurutunnu Etneu 0 2562 782048 750488 2026-05-13T10:57:53Z GiovanniPen 22308 782048 wikitext text/x-wiki {{Cumuni|nomucumuni=Campurutunnu Etneu|nomuufficiali=Camporotondo Etneo |articulustemma=[[Stemma cità di Campurutunnu Etneu|Stemma di Campurutunnu]] |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=6 |abbitanti=2.937 |dinsita=490 |cumunilimitrofi=[[Belpassu]], [[Mustarjancu]], [[Motta Sant'Anastasia]], [[San Petru Clarenza]] |cap=95040 |prifissutelefonicu=095 }} '''Campurutunnu Etneu''' (dittu '''Campurrutunnu''' ntâ parrata lucali) è un cumuni di 2.937 abbitanti dâ [[pruvincia di Catania]], havi na supirfici di 638 èttari cu na dinzità abbitativa di 490 abbitanti pi chilòmitru quatratu. E' misu ntâ cullina a 450 metri supra lu livedu dû mari e pigghia lu sò nomu dâ furma rutunniggianti dû tirritoriu stissu ( ntô [[1863]], si cci agghiunciu "''Etneu''" pri la vicinanza câ muntagna [[Èttina]]). == Stòria == Li primi nutizzî stòrichi supra a Campurutunnu, s'attròvanu ntô XVI seculu; tannu, iddu era unu dê tanti casali sparpagghiati ntornu ô tirritoriu catanisi e, accussì comu a tanti àutri casali, quannu, p’aggiustari li finanzi di la curuna spagnola, lu re [[Fulippu IV]] detti a vìnniri beni dû dimaniu riggiu ca avìa ntâ Sicilia (nzèmula ô pussidimentu, a cu accattava, vinìa datu macari nu tìtulu nubbiliari di prìncipi o di marchisi), macari Campurutunnu s'attruvau ô centru di nu cumpressu mircatu d'accatta e vinni. La corti ci detti ô ginuvisi Andria Massa l'autoritati di putiri accattari "pi cuntu" lu nùmmiru di Casali ca iddu cunziddirava nicissariu, p'appoi vinnilli 'n modu cchìu vantaggiusu. Fu accussì ca Antoniu Reitanu si l'accattau ntô [[1649]] pajannu 2.800 onzi e appoi ntô [[1654]] passau a Diegu Reitanu, ca appi l'annu dopu lu titulu di marchisi. A marzu dû [[1669]] l'abbitatu fu distruggiutu dâ culata làvica di l'[[Èttina]] e tannu tanti dê risidenti s'arifuggiaru a [[Catania]], unni assai aristaru senza cchiù turnari ô paisi. N'àutru disastru, lu trimotu dû [[1693]], fici calari ancora cchiù assai la sò populazzioni. Ntô [[1730]] lu pussessu feudali dû marchisatu passau, pi via matrimoniali, â famigghia Natòli. Ntô [[1812]], chê rifurmi amministativi borbònichi e l'abbullizzioni dâ feudalitati, '''Campurutunnu''' addivinatau cumuni autònimu. [[Catigurìa:Cumuni dâ pruvincia di Catania]] tt2gvk0wazqxwteu5ssldjiz8gr5d1m Giarri 0 2565 782049 775876 2026-05-13T10:59:20Z GiovanniPen 22308 782049 wikitext text/x-wiki {{Cumuni|nomucumuni=Giarri|nomuufficiali=Giarre |articulustemma=[[Stemma cità di Giarri|Stemma di Giarri]] |muttu=''"Abundantia in turribus tuis"''<br />(L'abbundanza n'te to turri) |riggiuni=Sicilia |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=27 |abbitanti=26.402 |dinsita=978 |cumunilimitrofi=[[Aciriali]], [[Màscali]], [[Milu]], [[Ripostu]], [[Sant'Arfiu]], [[Santa Vinirina]], [[Zafarana Etnea]] |cap=95014 |prifissutelefonicu=095 }} '''Giarri''' (o '''I Giarri''' ntâ parrata lucali) è un cumuni di 26.402 abbitanti dâ [[pruvincia di Catania]]. Lu sò nomu dimustra la prisenza di n'anticu malazzeni di giarri distinati ô [[cummerciu]] dû vinu, di l'ogghiu, etc. == Storia == ===Kallipolis=== Secunnu l'ùrtimi studi, c'acchiànanu ô [[1970]] circa, È pussíbbili ca l'antica citati di [[Kallipolis]] (zoè "citati bedda" 'n [[Lingua greca|grecu]]), s'attruvassi sutta la zona c'attuarmenti ricopri lu cumuni sicilianu di [[Giarri]], cchiù esattamenti la frazzioni dâ Macchia. ===Storia muterna=== [[{{ns:6}}:Piazza Duomo, Giarre.jpg|thumb|left|220px|Lu Domu di Giarri]] La storia di Giarri (o dî "Giarri") è relativamenti ricenti. Lu primu centru urbanu risali ô [[sèculu XVI]] quannu li vìscuvi di Catania, patruni di l'antica Cuntea di Màscali, dèsiru li tirreni in "enfiteusi" a ricchi jacitani e missinisi. Ntô [[1815]], lu Parramentu Sicilianu cuncidíu ê Giarri l'autonumìa amministrativa e la nova citati cù li so frazzioni si spartíu di [[Màscali]]. 'Ntô [[1841]] u [[Ripostu]] ad·divintàu cumuni, ma duranti lu perìudu fascista, li dui citati fôru junciuti ppi sei anni sutta lu nomu di '''Jonia''' (1939-1945). ==Frazzioni== A lu cumuni di oggi appartèninu li quarteri di: [[San Giuanni (Giarri)|San Giuanni]], [[Macchia (Giarri)|Macchia]], Trippunti, Strata, San Liunardeddu, [[Atareddu]], Sciara, Miscareddu e parti di li paisi dâ Carrubba e di Tagghiaùrza. == Tradizzioni == * 20 jinnaru, Festa di San Bastianu Martiri. [[Catigurìa:Cumuni dâ pruvincia di Catania]] 01s3hjt7a0fn8efymqsqgdadr9b8y6p Piadimunti 0 7910 782034 775896 2026-05-13T10:39:20Z GiovanniPen 22308 782034 wikitext text/x-wiki {{Cumuni|nomucumuni=Piadimunti|nomuufficiali=Piedimonte Etneo |pruvincia=[[Pruvincia di Catania|Catania]] |superfici=26 |abbitanti=3.671 |dinsita=141 |cumunilimitrofi=[[Calatabianu]], [[Castigghiuni di Sicilia]], [[Ciumifriddu]], [[Linguarossa]], [[Màscali]], [[Sant'Arfiu]] |cap=95017 |prifissutelefonicu=095 }} '''Piadimunti''' ('''Piemunti''' o '''Piamunti''' ntâ parrata lucali) è un [[cumuni|cumuni sicilianu]] di 3.671 abbitanti dâ [[pruvincia di Catania]]. È canusciutu nnî munti etnei (chiddi ca stannu sutta dû [[Etna|vurcanu]]) pâ festa dâ vinnigna unni li paisani e li furisteri si ponnu aggiuntari pi vìviri li mumenti particulari dâ vinnigna siciliana. == Tradizzioni == * 20 jinnaru, Festa di San Bastianu Martiri, festeggiamenti. [[Catigurìa:Cumuni dâ pruvincia di Catania]] b2t5n57hjwfejxsz7bwt5hb79k37n7k Template:Coord 10 23819 781995 756322 2026-05-13T10:12:20Z GiovanniPen 22308 modulo 781995 wikitext text/x-wiki <includeonly>{{#invoke:Coordinates|coord}}</includeonly><noinclude> {{Esutèricu}} {{man}} {{TemplateData}} [[Catigurìa:Template Coord|Coord]] [[Catigurìa:Mudeḍḍi chi ùsanu dati di Wikidata]] </noinclude> d4dmdai979nxpv2y9cde0b968fy4i5e 782027 781995 2026-05-13T10:23:28Z GiovanniPen 22308 fix funzione 782027 wikitext text/x-wiki <includeonly>{{#invoke:Coord|main}}</includeonly><noinclude> {{Esutèricu}} {{man}} {{TemplateData}} [[Catigurìa:Template Coord|Coord]] [[Catigurìa:Mudeḍḍi chi ùsanu dati di Wikidata]] </noinclude> ta5xt2cm8nz5q0e0bcsyhtxr620wytd Stemma dâ pruvincia riggiunali di Catania e dî sò cità 0 30655 782036 775666 2026-05-13T10:41:50Z GiovanniPen 22308 /* Stemma dê citati dâ "Terra di Aci" */ fix svg 782036 wikitext text/x-wiki {{O}} ==Stemma Pruvincia Riggiunali di Catania== [[{{ns:6}}:Provincia di Catania-Stemma.svg|right|220px]] La Pruvincia di Catania havi lu stemma e lu cunfaloni chî culuri assignati cu lu dicretu dû 7 giugnettu [[1883]] dû Re [[Umbertu I]]. Lu stemma è custituitu di nu scudu aràrdicu nquartatu; <li> a lu primu d'azzurru a lu [[liafanti]] d'oru, pri [[Catania]];<li> a lu secunnu d'argentu a la cruci di russu, pri [[Caltaggiruni]];<li> a lu terzu di russu a la cruci d'argentu, pri [[Nicusia]] (*); <li> a lu quartu d'azzurru a lu casteddu turricellatu di dui pezzi d'oru; la turri a manu manca cimata di un pinnuni di russu, chidda a manu dritta di un liuncinu nascenti macari iddu d'oru, pri [[Aci Riali]]. Iddu stemma è cimatu di la currispunnenti curona furmata di un circulu ca teni dùdici turri cu li merli, lijati ntornu, a mitati di l'autizza, di un curduni di muru tuttu d'oru. (*) Cu la rifurma amministrativa dû [[1817]], la [[Sicilia]] veni spartuta 'n 7 ntinnenzi e chisti 'n cchiù circundari o suttantinnenzi. Nicusia addiventa capulocu di unu dê quattru circundari dâ ntinnenza di Catania. Oggi Nicusia fa parti dâ [[pruvincia di Enna]] ==Stemma citati di Catania== [[{{ns:6}}:Catania-Stemma.svg|left|180px]] '''Lu stemma dû Comuni di [[Catania]]''' è custituitu di nu scudu cô funnu azzurru, cimatu di la curona riali aragunisi e sutta a la liggenta c'è scrivutu "S.P.Q.C." (*); a lu centru c'è nu [[liafanti]] (**) di culuri russu purpurinu misu di prufilu, cu la prubbòsciti isata e li zanni di culuri avòriu girati a manu manca e supra d'iddu c'è misa na granni littra maiùscula "A" (***), macari chista di culuri russu. (*) Catania rumana si friggiava di la sigla latina mpiriali "S.P.Q.C." Senatus Populus Que Catanensium: Lu Sinatu e lu Pòpulu di Catania. (**) Lu sìmmulu ufficiali dâ cità di Catania è la [[stàtula]] di petra làvica dô liafanti, chiamatu dê catanisi '''[[Liotru]]''' (o '''Diotru''') e ca s'attrova ntâ chiazza ô Domu dô [[1736]]. (***) La littra “A” ca è misa ntô stemma cìvicu, è la littra nizziali dû nomu di Agathae ([[Sant'Àgata]], patrona dâ cità) e voli [[Ricordu|arricurdari]] nu miràculu fattu dâ Santa ntô [[1357]]. A maju di dd'annu , ci fu nto Golfu di Ògnina nà tinta battagghia ca, vistu comu finìu, passò ntâ stòria comu ''"Scaccu di Catania".'' La frotta siciliana cumannata di l'ammiràgghiu Artali Alagona, ô gridu "Sant'Àjta e Alagona" vincìu l' avvirsari, canciannu a sò favuri li sorti di la “[[Guerra dê Novant'anni]]", ca dû [[1282]] ô [[1372]] si cummattìu tra [[Napuli]] e la [[Sicilia]]. ==Stemma citati di Aci Riali== [[{{ns:6}}:Acireale-Stemma.svg|right|200px]] Ntâ prima mità dû Cincucentu, veni addifinutu lu siggillu citatinu ca appoi, pi dicretu dû 29 sittèmmiru [[1936]], addiventa lu stemma dù Cumuni di [[Aciriali]]: chissu "e' raffiguratu di nu scudu d'azzurru, di lu Casteddu (*) a manu ritta ca nesci dô mari, chî merli â ghibbillina e ntra li merli lu liuni rampanti e curunatu di oru, e ca teni cu li branchi nu stindardu bifidu di russu, càricu di li littri capitali A.G. (**) d'oru, lu casteddu è misu vicinu ntô centru di tri faragghiuni (***), ca nèsciunu dû mari a manu manca.<br>Na curona rìggia è misa supra lu scudu ca e' circundatu ntâ basi di dui rami di quercia e di làuru". (*) Lu casteddu è chiddu di [[Aci Casteddu]], siparatu di Aci Riali e addivintatu autònumu ntô [[1647]].<br> (**) Li littri "A.G.", aricòrdanu lu mitu di [[Aci e Galatea]].<br> (***) Li faragghiuni sunnu chiddi di [[Acitrizza]], frazzioni di Aci Casteddu dô 1647, quannu chistu addivintò autònumu, ==Stemma dê citati dâ "[[Terra di Aci]]" == <gallery> Image:Aci Bonaccorsi-Stemma.svg|<center> [[Aci Bonaccossi]] Image:Aci Catena-Stemma.svg|<center> [[Aci Catina]] Image:Aci Castello-Stemma.svg|<center>[[Aci Casteddu]] Image:Acireale-Stemma.svg|<center> [[Aci Riali]] </gallery> <br> Ntô [[1092]] li tirritori di li citati ca oggi sunnu li cumuni autònumi di [[Aci Casteddu]], [[Aci Riali]], [[Aci Bonaccossi]], [[Aci Catina]], [[Valverde]] (all'èbbica Aci Valverde), facèvanu parti di l'accussì chiamata "Universitati di Aci", ditta accuddì pi nnicàrini l'unitati dô tirritoriu, pulìtica, murali, ecunòmica e stòrica dâ "Terra di Aci"; chista fu assignata dû Gran Conti Ruggeru a Angeriu, nzemi â nòmina di vìscuvu di [[Catania]]. Ntô [[1392]] li "terri di Aci" tòrnanu ô Riggiu Dimàniu, ma ntô [[1420]] lu re [[Alfonzu IV d'Aragona]] e appoi [[Firdinandu Velasquez]] la fannu n'àutra vota turnari a èssiri nu fèudu. Dopu èssiri passata di na famigghia nubbiliari a n'àutra, ntô [[1528]], lu cunsigghiu cìvicu s'ancontra a Casalottu (oggi [[Aci Sant'Antoniu]]) e nùmina sei "sìnnachi", ca vènunu ncaricati di pigghiari li tassi e cu chissi pajari lu riscattu. L' ''Universitati di Aci'' si vuleva livari dû puteri dê baruni e ntô [[1531]] ci arrinisciu pajannu la summa di 72.000 fiurini.<br> Nta ss'uccasioni, pi l' "Universitati di Aci", turnata a èssiri dimaniali, vinni criatu lu ''"siggillu"'' dâ cità, ca era ubblicatòriu apporri nta l'atti pùbbrici cìvichi e ca arresta appoi prisenti nta tutti li citati di "Aci" : ''“Pro certitudine veritatis has nostras patentes lítteras fieri fecimus sub parvo Universitatis nostrae sigillo in pede muni- tas, ex territorio Jacis, die IV ind. 1551”'' .<br> Nta stu siggillu circulari, ca havi nu bordu cu la liggenda ''“REDEMPTA FUIT 3 AUSTI 4 IND. 1531”'' , sunnu rapprisintati chiusi intra nu scudu nu casteddu a tri turri a manu dritta e tri faragghiuni ca nesciunu dû mari a manu manca.<br> La "Terra di Aci", comu sìmmulu di la sò nova libbirtati scegghi l'anticu ''Castrum di Acicasteddu'', ca rapprisintava la dimanialitati di "Aci", prima d'èssiri addivintata fèudu, e li tri Faragghiuni di [[Aci Trizza]] unni si rapprisenta la [[Aci e Galatea|liggenna]] mitulòggica du pastureddu Aci e dâ ninfa marina Galatea. Lu casteddu e li faragghiuni arrèstanu prisenti nzinu ad oggi ntê stemmi di '''Aciriali''', '''Acicasteddu''', '''Aci Catina''', '''Aci Bonaccossi''', e ntô stemma di Aci Sant'Antoniu nzinu ô [[1985]]. ==Stemma citati di Aci Sant'Antoniu== [[{{ns:6}}:Aci Sant'Antonio-Stemma.svg|right|200px]] Siccomu l'anticu Stemma cìvicu dû cumuni di Aci Sant'Antoniu non avìa lu furmali dicretu cuvernativu di ricanuscimentu, ntô [[1983]] lu cumuni s'arrivurgìu a lu "Studiu Aràrdicu di cunzulenza ligali Nubbiliari" di [[Gènuva]] cu la ntinzioni di fàrisi fari nu stemma cìvicu furmarmenti arricanusciutu. Ma li ndàggini stòrichi svurgiuti di ssu Studiu Aràrdicu di Genuva, foru fatti nta na manera supirficiali e lu stemma ca ni niscìu arrisurtau straneru pâ siculari stòria dâ ''Terra di Aci'', di unni lu tirritoriu di Aci Sant'Antoniu apparteni. <br> Lu stemma, ca cu dilibirazzioni dû 6 Austu [[1984]] lu comuni appruvau, porta li sìmmuli di famigghi nubbiliari astrànii ô tirritoriu dâ citati, si non fussi sulu picchì a partiri di la secunna mità dû Seicentu foru feudutari di na parti di li tirritori di Aci. Ricentimenti lu comuni di Aci Sant'Antoniu, fici la dumanna pi uttèniri lu ricanuscimentu ministeriali di l'anticu sò stemma, ca è chiddu ca nzinu ô 1983 nun avìa lu ricanuscimentu cuvernativu, ma ca era misu nta tutti li ducumenta ufficiali di l'antica "Universitati di Aci" e ca nta l'òpira di [[Fidericu Gravina]], "Supplimentu a lu Blasoni ntâ [[Sicilia]] spittanti a li municipi e a li famigghi di l'Italia", si dici ca ''"lu stemma di Aci Sant'Antoniu è chiddu stissu di [[Aciriali]], accussi comu a chistu sunnu puru li stemmi di [[Acicasteddu]], [[Aci Bonaccossi]], e [[Acicatina]]"'' . ==Stemma citati di Belpassu== [[{{ns:6}}:Belpasso-Stemma.png|left|180px]] Lu Stemma "è rapprisintatu di la mìtica Àrabba Finici (*) ricanti: ntô pettu nu scudu cu l'[[Etna]] ca ci nèsciunu alcuni lingui di focu stilizzati, nta l'artigghi la scritta "Melior de cinere surgo" (*). Ntê lati nu ramusceddu di quercia e unu di [[làuru]], annudati ô centru di nu fioccu. L'Àrabba Finici è surmuntata di la curona aràrdica di li Cumuni". (*) L'àrabba finici rapprisenta la capacità di rinàsciri dê propi cìnniri, e macara lu muttu latinu "melior de cinere surgo" si rifirisci a la stissa cosa. ==Stemma citati di Biancavilla== :Lu stemma è nu scudu troncu e è cumpostu di li siquenti sìmmuli <li> curona cìvica: misa sùpira a lu scudu e rapprisenta la municipalitati di Biancavilla;<li> suli radiusu: misu nta la parti àuta di lu scudu e ammenzu a l'azzurru ca simmulèggia lu celu; [[{{ns:6}}:Biancavilla-Stemma.svg|right|200px]] <li> zolla di terra; misa ntô vasciu, simmulèggia lu tirritòriu. Chistu sìmmulu, anzemi a lu suli radiusu e a lu celu azzurru, risarta lu significatu di Callicari" (anticu nomu di Biancavilla) ca 'n grecu signìfica 'bedda contrata'; <li> cavaddu: rapprisenta lu cavaddu di l'eroi nazzionali arbanesi [[Giorgiu Castriota]] chiamtu "Scanderbeg" , noltri, nzemi a lu cipressu, rapprisenta lu stemma gintilizziu di la famigghia di lu primu capitanu (sìnnacu) di Biancavilla [[Cesari Masi]];<li>cipressu: simmulèggia l'[[àrvulu]] unni, secunnu n'antica ricustruzzioni arbanisi, Giuvanni Castriota, figghiu di lu ''Scanderbeg'', doppu aviri lijatu lu cavaddu di sà patri e sarpau pi jiri nta l'[[Italia]] portannnu 'n sarvu la matri e la sò genti minazzata di lu nvasuri turcu mussurmanu Maumettu II;<li>turri: cumposta di tri pezzi e cu la finestra, è lu sìmmulu di li signuri di lu locu, li conti Moncada;<li>cruci greca: ricunferma l'appartinenza di li profuchi arbanesi a la riliggioni cristiana di ritu grecu-ortudossu;<li>nastru d'oru: misu sùpira la cruci greca e cu la scritta ''"Scanderbeg"'' ca, 'n àrrabbu, voli diri "Alessandru lu signuri o lu grandi";<li>curona di conti: misa sùpira lu nastru e la croci greca." <br> Testu pigghiatu dô statutu cumunali. ==Stemma citati di Bronti== [[{{ns:6}}:Bronte-Stemma.svg|right|200px]] La cità di Bronti havi nu propiu stemma cumpostu di:<li> n'àquila, cu dui curoni una sùpira la testa e l'àutra nta lu [[coddu]]; nta li quarti di lu stemma appàrinu: a manu dritta, nta l'àutu cincu palli nta lu funnali giallu, dui aquilotti curunati e dui strisci russi; nta lu funnali nìuru nu liuncinu e n'àquila nta lu funnali giallu, l'intermezzu di li dui stemmi è cuspaggiutu di gigghi: a manu manca, nta l'àutu setti gigghi sùpira funnali jancu, na turri e nu liuncinu; tri gigghi nta lu funnalli giallu; nta lu menzu a manu manca àutri dui quarti; unu cu li gigghi a destra, l'àutru cu li palli a sinistra e lu muttu ''Fidelissima Brontis Universitas'' (Bronti cità fidelissima).<br> Lu stemma è attravirsatu di nu munili di perli. La discrizzioni è pigghiata di lu "Statutu di lu cumuni di Bronti". ==Stemma citati di Cattabbianu== [[{{ns:6}}:Stemma calatabiano1.jpg|left|200px]] Lu Comuni havi comu segnu distintivu di la propia pirsonalitati giuridica lu stemma civicu. Lu stemma di Cattabbianu è custituitu di: scudu truncatu:nta lu primu campu di celu, a lu casteddu sdirubbatu (*), funnatu sùpira nu monti, lu tuttu a lu naturali; nta lu secunnu, d'azzurru, a cincu crucetti d'oru misi 'n cruci (**). <br> (La discrizzioni è pigghiata di lu "Statutu di lu cumuni di Cattabianu"). (*) Lu casteddu misu sùpira nu munti e ca talìa lu paisi di Cattabbianu, è na furtezza ca si penza havi n'urìggini àrabba, accussì comu addimustra lu sò nomu "Kaalat-bian" (casteddu di Bianu, ca avìa a èssiri cu prubbabbilità l'amministraturi e signuri).<ref>[https://web.archive.org/web/20080104172725/http://www.comune.calatabiano.ct.it/castello.htm Lu casteddu di Cattabbianu]</ref> (**) Li cincu crucetti ripigghiunu li nzigni di la famigghia "Crujllas" <ref>[https://web.archive.org/web/20070910223524/http://www.corteostoricocalatabiano.it/cruyllas.htm La famigghia Crujllas]</ref> ca s'attròvanu nta n'arcu 'n petra làvica d'intra lu casteddu di Cattabbianu. <references/> ==Stemma citati di Caltaggiruni== [[{{ns:6}}:Caltagirone-Stemma.svg|right|200px]] Lu stemma dû cumuni di [[Caltaggiruni]] è:<br> "D'argentu a la cruci di russu nta lu intra di nu scudu. Urnamenti esteriori di cità (comu di lu dicretu Prisidenti di la Ripùbbrica dû 6 aprili 1987). Fannu parti di lu stemma noltri, pri tradizzioni millinària, li urnamenti rafficuranti l'aquila curunata cu l'ali aperti e ca cu l'artigghiu destru teni n'ossu di gicanti, cu li grifoni alati a li lati.('''*''') (Discrizzioni pigghiata dô statutu cumunali appruvatu cu dilibbirazzioni n. 67 dû 23 aprili 2004) ('''*''')<li> L'aquila curunata cu l'ali aperti è l'anticu sìmmulu dâ cità.<li> La cità fu libbirata ntô [[1030]] dâ duminazzioni saracina di la cità di [[Genuva]]. Pri ricunuscenza Caltaggiruni ci misi ntô pettu di l'aquila dû stemma citatinu, lu granni scudu cruciatu russu nta lu campu jancu, tinuta di dui grifoni alati a li lati (sìmmulu dâ ripùbbrica marinara di Genuva). [[Catigurìa:Stemma]] noaskbkkclnzlwzv0x8bm1nzj6fyg29 782038 782036 2026-05-13T10:44:16Z GiovanniPen 22308 /* Stemma citati di Belpassu */ fix img 782038 wikitext text/x-wiki {{O}} ==Stemma Pruvincia Riggiunali di Catania== [[{{ns:6}}:Provincia di Catania-Stemma.svg|right|220px]] La Pruvincia di Catania havi lu stemma e lu cunfaloni chî culuri assignati cu lu dicretu dû 7 giugnettu [[1883]] dû Re [[Umbertu I]]. Lu stemma è custituitu di nu scudu aràrdicu nquartatu; <li> a lu primu d'azzurru a lu [[liafanti]] d'oru, pri [[Catania]];<li> a lu secunnu d'argentu a la cruci di russu, pri [[Caltaggiruni]];<li> a lu terzu di russu a la cruci d'argentu, pri [[Nicusia]] (*); <li> a lu quartu d'azzurru a lu casteddu turricellatu di dui pezzi d'oru; la turri a manu manca cimata di un pinnuni di russu, chidda a manu dritta di un liuncinu nascenti macari iddu d'oru, pri [[Aci Riali]]. Iddu stemma è cimatu di la currispunnenti curona furmata di un circulu ca teni dùdici turri cu li merli, lijati ntornu, a mitati di l'autizza, di un curduni di muru tuttu d'oru. (*) Cu la rifurma amministrativa dû [[1817]], la [[Sicilia]] veni spartuta 'n 7 ntinnenzi e chisti 'n cchiù circundari o suttantinnenzi. Nicusia addiventa capulocu di unu dê quattru circundari dâ ntinnenza di Catania. Oggi Nicusia fa parti dâ [[pruvincia di Enna]] ==Stemma citati di Catania== [[{{ns:6}}:Catania-Stemma.svg|left|180px]] '''Lu stemma dû Comuni di [[Catania]]''' è custituitu di nu scudu cô funnu azzurru, cimatu di la curona riali aragunisi e sutta a la liggenta c'è scrivutu "S.P.Q.C." (*); a lu centru c'è nu [[liafanti]] (**) di culuri russu purpurinu misu di prufilu, cu la prubbòsciti isata e li zanni di culuri avòriu girati a manu manca e supra d'iddu c'è misa na granni littra maiùscula "A" (***), macari chista di culuri russu. (*) Catania rumana si friggiava di la sigla latina mpiriali "S.P.Q.C." Senatus Populus Que Catanensium: Lu Sinatu e lu Pòpulu di Catania. (**) Lu sìmmulu ufficiali dâ cità di Catania è la [[stàtula]] di petra làvica dô liafanti, chiamatu dê catanisi '''[[Liotru]]''' (o '''Diotru''') e ca s'attrova ntâ chiazza ô Domu dô [[1736]]. (***) La littra “A” ca è misa ntô stemma cìvicu, è la littra nizziali dû nomu di Agathae ([[Sant'Àgata]], patrona dâ cità) e voli [[Ricordu|arricurdari]] nu miràculu fattu dâ Santa ntô [[1357]]. A maju di dd'annu , ci fu nto Golfu di Ògnina nà tinta battagghia ca, vistu comu finìu, passò ntâ stòria comu ''"Scaccu di Catania".'' La frotta siciliana cumannata di l'ammiràgghiu Artali Alagona, ô gridu "Sant'Àjta e Alagona" vincìu l' avvirsari, canciannu a sò favuri li sorti di la “[[Guerra dê Novant'anni]]", ca dû [[1282]] ô [[1372]] si cummattìu tra [[Napuli]] e la [[Sicilia]]. ==Stemma citati di Aci Riali== [[{{ns:6}}:Acireale-Stemma.svg|right|200px]] Ntâ prima mità dû Cincucentu, veni addifinutu lu siggillu citatinu ca appoi, pi dicretu dû 29 sittèmmiru [[1936]], addiventa lu stemma dù Cumuni di [[Aciriali]]: chissu "e' raffiguratu di nu scudu d'azzurru, di lu Casteddu (*) a manu ritta ca nesci dô mari, chî merli â ghibbillina e ntra li merli lu liuni rampanti e curunatu di oru, e ca teni cu li branchi nu stindardu bifidu di russu, càricu di li littri capitali A.G. (**) d'oru, lu casteddu è misu vicinu ntô centru di tri faragghiuni (***), ca nèsciunu dû mari a manu manca.<br>Na curona rìggia è misa supra lu scudu ca e' circundatu ntâ basi di dui rami di quercia e di làuru". (*) Lu casteddu è chiddu di [[Aci Casteddu]], siparatu di Aci Riali e addivintatu autònumu ntô [[1647]].<br> (**) Li littri "A.G.", aricòrdanu lu mitu di [[Aci e Galatea]].<br> (***) Li faragghiuni sunnu chiddi di [[Acitrizza]], frazzioni di Aci Casteddu dô 1647, quannu chistu addivintò autònumu, ==Stemma dê citati dâ "[[Terra di Aci]]" == <gallery> Image:Aci Bonaccorsi-Stemma.svg|<center> [[Aci Bonaccossi]] Image:Aci Catena-Stemma.svg|<center> [[Aci Catina]] Image:Aci Castello-Stemma.svg|<center>[[Aci Casteddu]] Image:Acireale-Stemma.svg|<center> [[Aci Riali]] </gallery> <br> Ntô [[1092]] li tirritori di li citati ca oggi sunnu li cumuni autònumi di [[Aci Casteddu]], [[Aci Riali]], [[Aci Bonaccossi]], [[Aci Catina]], [[Valverde]] (all'èbbica Aci Valverde), facèvanu parti di l'accussì chiamata "Universitati di Aci", ditta accuddì pi nnicàrini l'unitati dô tirritoriu, pulìtica, murali, ecunòmica e stòrica dâ "Terra di Aci"; chista fu assignata dû Gran Conti Ruggeru a Angeriu, nzemi â nòmina di vìscuvu di [[Catania]]. Ntô [[1392]] li "terri di Aci" tòrnanu ô Riggiu Dimàniu, ma ntô [[1420]] lu re [[Alfonzu IV d'Aragona]] e appoi [[Firdinandu Velasquez]] la fannu n'àutra vota turnari a èssiri nu fèudu. Dopu èssiri passata di na famigghia nubbiliari a n'àutra, ntô [[1528]], lu cunsigghiu cìvicu s'ancontra a Casalottu (oggi [[Aci Sant'Antoniu]]) e nùmina sei "sìnnachi", ca vènunu ncaricati di pigghiari li tassi e cu chissi pajari lu riscattu. L' ''Universitati di Aci'' si vuleva livari dû puteri dê baruni e ntô [[1531]] ci arrinisciu pajannu la summa di 72.000 fiurini.<br> Nta ss'uccasioni, pi l' "Universitati di Aci", turnata a èssiri dimaniali, vinni criatu lu ''"siggillu"'' dâ cità, ca era ubblicatòriu apporri nta l'atti pùbbrici cìvichi e ca arresta appoi prisenti nta tutti li citati di "Aci" : ''“Pro certitudine veritatis has nostras patentes lítteras fieri fecimus sub parvo Universitatis nostrae sigillo in pede muni- tas, ex territorio Jacis, die IV ind. 1551”'' .<br> Nta stu siggillu circulari, ca havi nu bordu cu la liggenda ''“REDEMPTA FUIT 3 AUSTI 4 IND. 1531”'' , sunnu rapprisintati chiusi intra nu scudu nu casteddu a tri turri a manu dritta e tri faragghiuni ca nesciunu dû mari a manu manca.<br> La "Terra di Aci", comu sìmmulu di la sò nova libbirtati scegghi l'anticu ''Castrum di Acicasteddu'', ca rapprisintava la dimanialitati di "Aci", prima d'èssiri addivintata fèudu, e li tri Faragghiuni di [[Aci Trizza]] unni si rapprisenta la [[Aci e Galatea|liggenna]] mitulòggica du pastureddu Aci e dâ ninfa marina Galatea. Lu casteddu e li faragghiuni arrèstanu prisenti nzinu ad oggi ntê stemmi di '''Aciriali''', '''Acicasteddu''', '''Aci Catina''', '''Aci Bonaccossi''', e ntô stemma di Aci Sant'Antoniu nzinu ô [[1985]]. ==Stemma citati di Aci Sant'Antoniu== [[{{ns:6}}:Aci Sant'Antonio-Stemma.svg|right|200px]] Siccomu l'anticu Stemma cìvicu dû cumuni di Aci Sant'Antoniu non avìa lu furmali dicretu cuvernativu di ricanuscimentu, ntô [[1983]] lu cumuni s'arrivurgìu a lu "Studiu Aràrdicu di cunzulenza ligali Nubbiliari" di [[Gènuva]] cu la ntinzioni di fàrisi fari nu stemma cìvicu furmarmenti arricanusciutu. Ma li ndàggini stòrichi svurgiuti di ssu Studiu Aràrdicu di Genuva, foru fatti nta na manera supirficiali e lu stemma ca ni niscìu arrisurtau straneru pâ siculari stòria dâ ''Terra di Aci'', di unni lu tirritoriu di Aci Sant'Antoniu apparteni. <br> Lu stemma, ca cu dilibirazzioni dû 6 Austu [[1984]] lu comuni appruvau, porta li sìmmuli di famigghi nubbiliari astrànii ô tirritoriu dâ citati, si non fussi sulu picchì a partiri di la secunna mità dû Seicentu foru feudutari di na parti di li tirritori di Aci. Ricentimenti lu comuni di Aci Sant'Antoniu, fici la dumanna pi uttèniri lu ricanuscimentu ministeriali di l'anticu sò stemma, ca è chiddu ca nzinu ô 1983 nun avìa lu ricanuscimentu cuvernativu, ma ca era misu nta tutti li ducumenta ufficiali di l'antica "Universitati di Aci" e ca nta l'òpira di [[Fidericu Gravina]], "Supplimentu a lu Blasoni ntâ [[Sicilia]] spittanti a li municipi e a li famigghi di l'Italia", si dici ca ''"lu stemma di Aci Sant'Antoniu è chiddu stissu di [[Aciriali]], accussi comu a chistu sunnu puru li stemmi di [[Acicasteddu]], [[Aci Bonaccossi]], e [[Acicatina]]"'' . ==Stemma citati di Belpassu== [[{{ns:6}}:Belpasso-Stemma.svg|left|180px]] Lu Stemma "è rapprisintatu di la mìtica Àrabba Finici (*) ricanti: ntô pettu nu scudu cu l'[[Etna]] ca ci nèsciunu alcuni lingui di focu stilizzati, nta l'artigghi la scritta "Melior de cinere surgo" (*). Ntê lati nu ramusceddu di quercia e unu di [[làuru]], annudati ô centru di nu fioccu. L'Àrabba Finici è surmuntata di la curona aràrdica di li Cumuni". (*) L'àrabba finici rapprisenta la capacità di rinàsciri dê propi cìnniri, e macara lu muttu latinu "melior de cinere surgo" si rifirisci a la stissa cosa. ==Stemma citati di Biancavilla== :Lu stemma è nu scudu troncu e è cumpostu di li siquenti sìmmuli <li> curona cìvica: misa sùpira a lu scudu e rapprisenta la municipalitati di Biancavilla;<li> suli radiusu: misu nta la parti àuta di lu scudu e ammenzu a l'azzurru ca simmulèggia lu celu; [[{{ns:6}}:Biancavilla-Stemma.svg|right|200px]] <li> zolla di terra; misa ntô vasciu, simmulèggia lu tirritòriu. Chistu sìmmulu, anzemi a lu suli radiusu e a lu celu azzurru, risarta lu significatu di Callicari" (anticu nomu di Biancavilla) ca 'n grecu signìfica 'bedda contrata'; <li> cavaddu: rapprisenta lu cavaddu di l'eroi nazzionali arbanesi [[Giorgiu Castriota]] chiamtu "Scanderbeg" , noltri, nzemi a lu cipressu, rapprisenta lu stemma gintilizziu di la famigghia di lu primu capitanu (sìnnacu) di Biancavilla [[Cesari Masi]];<li>cipressu: simmulèggia l'[[àrvulu]] unni, secunnu n'antica ricustruzzioni arbanisi, Giuvanni Castriota, figghiu di lu ''Scanderbeg'', doppu aviri lijatu lu cavaddu di sà patri e sarpau pi jiri nta l'[[Italia]] portannnu 'n sarvu la matri e la sò genti minazzata di lu nvasuri turcu mussurmanu Maumettu II;<li>turri: cumposta di tri pezzi e cu la finestra, è lu sìmmulu di li signuri di lu locu, li conti Moncada;<li>cruci greca: ricunferma l'appartinenza di li profuchi arbanesi a la riliggioni cristiana di ritu grecu-ortudossu;<li>nastru d'oru: misu sùpira la cruci greca e cu la scritta ''"Scanderbeg"'' ca, 'n àrrabbu, voli diri "Alessandru lu signuri o lu grandi";<li>curona di conti: misa sùpira lu nastru e la croci greca." <br> Testu pigghiatu dô statutu cumunali. ==Stemma citati di Bronti== [[{{ns:6}}:Bronte-Stemma.svg|right|200px]] La cità di Bronti havi nu propiu stemma cumpostu di:<li> n'àquila, cu dui curoni una sùpira la testa e l'àutra nta lu [[coddu]]; nta li quarti di lu stemma appàrinu: a manu dritta, nta l'àutu cincu palli nta lu funnali giallu, dui aquilotti curunati e dui strisci russi; nta lu funnali nìuru nu liuncinu e n'àquila nta lu funnali giallu, l'intermezzu di li dui stemmi è cuspaggiutu di gigghi: a manu manca, nta l'àutu setti gigghi sùpira funnali jancu, na turri e nu liuncinu; tri gigghi nta lu funnalli giallu; nta lu menzu a manu manca àutri dui quarti; unu cu li gigghi a destra, l'àutru cu li palli a sinistra e lu muttu ''Fidelissima Brontis Universitas'' (Bronti cità fidelissima).<br> Lu stemma è attravirsatu di nu munili di perli. La discrizzioni è pigghiata di lu "Statutu di lu cumuni di Bronti". ==Stemma citati di Cattabbianu== [[{{ns:6}}:Stemma calatabiano1.jpg|left|200px]] Lu Comuni havi comu segnu distintivu di la propia pirsonalitati giuridica lu stemma civicu. Lu stemma di Cattabbianu è custituitu di: scudu truncatu:nta lu primu campu di celu, a lu casteddu sdirubbatu (*), funnatu sùpira nu monti, lu tuttu a lu naturali; nta lu secunnu, d'azzurru, a cincu crucetti d'oru misi 'n cruci (**). <br> (La discrizzioni è pigghiata di lu "Statutu di lu cumuni di Cattabianu"). (*) Lu casteddu misu sùpira nu munti e ca talìa lu paisi di Cattabbianu, è na furtezza ca si penza havi n'urìggini àrabba, accussì comu addimustra lu sò nomu "Kaalat-bian" (casteddu di Bianu, ca avìa a èssiri cu prubbabbilità l'amministraturi e signuri).<ref>[https://web.archive.org/web/20080104172725/http://www.comune.calatabiano.ct.it/castello.htm Lu casteddu di Cattabbianu]</ref> (**) Li cincu crucetti ripigghiunu li nzigni di la famigghia "Crujllas" <ref>[https://web.archive.org/web/20070910223524/http://www.corteostoricocalatabiano.it/cruyllas.htm La famigghia Crujllas]</ref> ca s'attròvanu nta n'arcu 'n petra làvica d'intra lu casteddu di Cattabbianu. <references/> ==Stemma citati di Caltaggiruni== [[{{ns:6}}:Caltagirone-Stemma.svg|right|200px]] Lu stemma dû cumuni di [[Caltaggiruni]] è:<br> "D'argentu a la cruci di russu nta lu intra di nu scudu. Urnamenti esteriori di cità (comu di lu dicretu Prisidenti di la Ripùbbrica dû 6 aprili 1987). Fannu parti di lu stemma noltri, pri tradizzioni millinària, li urnamenti rafficuranti l'aquila curunata cu l'ali aperti e ca cu l'artigghiu destru teni n'ossu di gicanti, cu li grifoni alati a li lati.('''*''') (Discrizzioni pigghiata dô statutu cumunali appruvatu cu dilibbirazzioni n. 67 dû 23 aprili 2004) ('''*''')<li> L'aquila curunata cu l'ali aperti è l'anticu sìmmulu dâ cità.<li> La cità fu libbirata ntô [[1030]] dâ duminazzioni saracina di la cità di [[Genuva]]. Pri ricunuscenza Caltaggiruni ci misi ntô pettu di l'aquila dû stemma citatinu, lu granni scudu cruciatu russu nta lu campu jancu, tinuta di dui grifoni alati a li lati (sìmmulu dâ ripùbbrica marinara di Genuva). [[Catigurìa:Stemma]] c4kw06nptw76s4i7sfexzjyawbtawf2 782044 782038 2026-05-13T10:49:53Z GiovanniPen 22308 added [[Category:Pruvincia di Catania]] using [[Help:Gadget-HotCat|HotCat]] 782044 wikitext text/x-wiki {{O}} ==Stemma Pruvincia Riggiunali di Catania== [[{{ns:6}}:Provincia di Catania-Stemma.svg|right|220px]] La Pruvincia di Catania havi lu stemma e lu cunfaloni chî culuri assignati cu lu dicretu dû 7 giugnettu [[1883]] dû Re [[Umbertu I]]. Lu stemma è custituitu di nu scudu aràrdicu nquartatu; <li> a lu primu d'azzurru a lu [[liafanti]] d'oru, pri [[Catania]];<li> a lu secunnu d'argentu a la cruci di russu, pri [[Caltaggiruni]];<li> a lu terzu di russu a la cruci d'argentu, pri [[Nicusia]] (*); <li> a lu quartu d'azzurru a lu casteddu turricellatu di dui pezzi d'oru; la turri a manu manca cimata di un pinnuni di russu, chidda a manu dritta di un liuncinu nascenti macari iddu d'oru, pri [[Aci Riali]]. Iddu stemma è cimatu di la currispunnenti curona furmata di un circulu ca teni dùdici turri cu li merli, lijati ntornu, a mitati di l'autizza, di un curduni di muru tuttu d'oru. (*) Cu la rifurma amministrativa dû [[1817]], la [[Sicilia]] veni spartuta 'n 7 ntinnenzi e chisti 'n cchiù circundari o suttantinnenzi. Nicusia addiventa capulocu di unu dê quattru circundari dâ ntinnenza di Catania. Oggi Nicusia fa parti dâ [[pruvincia di Enna]] ==Stemma citati di Catania== [[{{ns:6}}:Catania-Stemma.svg|left|180px]] '''Lu stemma dû Comuni di [[Catania]]''' è custituitu di nu scudu cô funnu azzurru, cimatu di la curona riali aragunisi e sutta a la liggenta c'è scrivutu "S.P.Q.C." (*); a lu centru c'è nu [[liafanti]] (**) di culuri russu purpurinu misu di prufilu, cu la prubbòsciti isata e li zanni di culuri avòriu girati a manu manca e supra d'iddu c'è misa na granni littra maiùscula "A" (***), macari chista di culuri russu. (*) Catania rumana si friggiava di la sigla latina mpiriali "S.P.Q.C." Senatus Populus Que Catanensium: Lu Sinatu e lu Pòpulu di Catania. (**) Lu sìmmulu ufficiali dâ cità di Catania è la [[stàtula]] di petra làvica dô liafanti, chiamatu dê catanisi '''[[Liotru]]''' (o '''Diotru''') e ca s'attrova ntâ chiazza ô Domu dô [[1736]]. (***) La littra “A” ca è misa ntô stemma cìvicu, è la littra nizziali dû nomu di Agathae ([[Sant'Àgata]], patrona dâ cità) e voli [[Ricordu|arricurdari]] nu miràculu fattu dâ Santa ntô [[1357]]. A maju di dd'annu , ci fu nto Golfu di Ògnina nà tinta battagghia ca, vistu comu finìu, passò ntâ stòria comu ''"Scaccu di Catania".'' La frotta siciliana cumannata di l'ammiràgghiu Artali Alagona, ô gridu "Sant'Àjta e Alagona" vincìu l' avvirsari, canciannu a sò favuri li sorti di la “[[Guerra dê Novant'anni]]", ca dû [[1282]] ô [[1372]] si cummattìu tra [[Napuli]] e la [[Sicilia]]. ==Stemma citati di Aci Riali== [[{{ns:6}}:Acireale-Stemma.svg|right|200px]] Ntâ prima mità dû Cincucentu, veni addifinutu lu siggillu citatinu ca appoi, pi dicretu dû 29 sittèmmiru [[1936]], addiventa lu stemma dù Cumuni di [[Aciriali]]: chissu "e' raffiguratu di nu scudu d'azzurru, di lu Casteddu (*) a manu ritta ca nesci dô mari, chî merli â ghibbillina e ntra li merli lu liuni rampanti e curunatu di oru, e ca teni cu li branchi nu stindardu bifidu di russu, càricu di li littri capitali A.G. (**) d'oru, lu casteddu è misu vicinu ntô centru di tri faragghiuni (***), ca nèsciunu dû mari a manu manca.<br>Na curona rìggia è misa supra lu scudu ca e' circundatu ntâ basi di dui rami di quercia e di làuru". (*) Lu casteddu è chiddu di [[Aci Casteddu]], siparatu di Aci Riali e addivintatu autònumu ntô [[1647]].<br> (**) Li littri "A.G.", aricòrdanu lu mitu di [[Aci e Galatea]].<br> (***) Li faragghiuni sunnu chiddi di [[Acitrizza]], frazzioni di Aci Casteddu dô 1647, quannu chistu addivintò autònumu, ==Stemma dê citati dâ "[[Terra di Aci]]" == <gallery> Image:Aci Bonaccorsi-Stemma.svg|<center> [[Aci Bonaccossi]] Image:Aci Catena-Stemma.svg|<center> [[Aci Catina]] Image:Aci Castello-Stemma.svg|<center>[[Aci Casteddu]] Image:Acireale-Stemma.svg|<center> [[Aci Riali]] </gallery> <br> Ntô [[1092]] li tirritori di li citati ca oggi sunnu li cumuni autònumi di [[Aci Casteddu]], [[Aci Riali]], [[Aci Bonaccossi]], [[Aci Catina]], [[Valverde]] (all'èbbica Aci Valverde), facèvanu parti di l'accussì chiamata "Universitati di Aci", ditta accuddì pi nnicàrini l'unitati dô tirritoriu, pulìtica, murali, ecunòmica e stòrica dâ "Terra di Aci"; chista fu assignata dû Gran Conti Ruggeru a Angeriu, nzemi â nòmina di vìscuvu di [[Catania]]. Ntô [[1392]] li "terri di Aci" tòrnanu ô Riggiu Dimàniu, ma ntô [[1420]] lu re [[Alfonzu IV d'Aragona]] e appoi [[Firdinandu Velasquez]] la fannu n'àutra vota turnari a èssiri nu fèudu. Dopu èssiri passata di na famigghia nubbiliari a n'àutra, ntô [[1528]], lu cunsigghiu cìvicu s'ancontra a Casalottu (oggi [[Aci Sant'Antoniu]]) e nùmina sei "sìnnachi", ca vènunu ncaricati di pigghiari li tassi e cu chissi pajari lu riscattu. L' ''Universitati di Aci'' si vuleva livari dû puteri dê baruni e ntô [[1531]] ci arrinisciu pajannu la summa di 72.000 fiurini.<br> Nta ss'uccasioni, pi l' "Universitati di Aci", turnata a èssiri dimaniali, vinni criatu lu ''"siggillu"'' dâ cità, ca era ubblicatòriu apporri nta l'atti pùbbrici cìvichi e ca arresta appoi prisenti nta tutti li citati di "Aci" : ''“Pro certitudine veritatis has nostras patentes lítteras fieri fecimus sub parvo Universitatis nostrae sigillo in pede muni- tas, ex territorio Jacis, die IV ind. 1551”'' .<br> Nta stu siggillu circulari, ca havi nu bordu cu la liggenda ''“REDEMPTA FUIT 3 AUSTI 4 IND. 1531”'' , sunnu rapprisintati chiusi intra nu scudu nu casteddu a tri turri a manu dritta e tri faragghiuni ca nesciunu dû mari a manu manca.<br> La "Terra di Aci", comu sìmmulu di la sò nova libbirtati scegghi l'anticu ''Castrum di Acicasteddu'', ca rapprisintava la dimanialitati di "Aci", prima d'èssiri addivintata fèudu, e li tri Faragghiuni di [[Aci Trizza]] unni si rapprisenta la [[Aci e Galatea|liggenna]] mitulòggica du pastureddu Aci e dâ ninfa marina Galatea. Lu casteddu e li faragghiuni arrèstanu prisenti nzinu ad oggi ntê stemmi di '''Aciriali''', '''Acicasteddu''', '''Aci Catina''', '''Aci Bonaccossi''', e ntô stemma di Aci Sant'Antoniu nzinu ô [[1985]]. ==Stemma citati di Aci Sant'Antoniu== [[{{ns:6}}:Aci Sant'Antonio-Stemma.svg|right|200px]] Siccomu l'anticu Stemma cìvicu dû cumuni di Aci Sant'Antoniu non avìa lu furmali dicretu cuvernativu di ricanuscimentu, ntô [[1983]] lu cumuni s'arrivurgìu a lu "Studiu Aràrdicu di cunzulenza ligali Nubbiliari" di [[Gènuva]] cu la ntinzioni di fàrisi fari nu stemma cìvicu furmarmenti arricanusciutu. Ma li ndàggini stòrichi svurgiuti di ssu Studiu Aràrdicu di Genuva, foru fatti nta na manera supirficiali e lu stemma ca ni niscìu arrisurtau straneru pâ siculari stòria dâ ''Terra di Aci'', di unni lu tirritoriu di Aci Sant'Antoniu apparteni. <br> Lu stemma, ca cu dilibirazzioni dû 6 Austu [[1984]] lu comuni appruvau, porta li sìmmuli di famigghi nubbiliari astrànii ô tirritoriu dâ citati, si non fussi sulu picchì a partiri di la secunna mità dû Seicentu foru feudutari di na parti di li tirritori di Aci. Ricentimenti lu comuni di Aci Sant'Antoniu, fici la dumanna pi uttèniri lu ricanuscimentu ministeriali di l'anticu sò stemma, ca è chiddu ca nzinu ô 1983 nun avìa lu ricanuscimentu cuvernativu, ma ca era misu nta tutti li ducumenta ufficiali di l'antica "Universitati di Aci" e ca nta l'òpira di [[Fidericu Gravina]], "Supplimentu a lu Blasoni ntâ [[Sicilia]] spittanti a li municipi e a li famigghi di l'Italia", si dici ca ''"lu stemma di Aci Sant'Antoniu è chiddu stissu di [[Aciriali]], accussi comu a chistu sunnu puru li stemmi di [[Acicasteddu]], [[Aci Bonaccossi]], e [[Acicatina]]"'' . ==Stemma citati di Belpassu== [[{{ns:6}}:Belpasso-Stemma.svg|left|180px]] Lu Stemma "è rapprisintatu di la mìtica Àrabba Finici (*) ricanti: ntô pettu nu scudu cu l'[[Etna]] ca ci nèsciunu alcuni lingui di focu stilizzati, nta l'artigghi la scritta "Melior de cinere surgo" (*). Ntê lati nu ramusceddu di quercia e unu di [[làuru]], annudati ô centru di nu fioccu. L'Àrabba Finici è surmuntata di la curona aràrdica di li Cumuni". (*) L'àrabba finici rapprisenta la capacità di rinàsciri dê propi cìnniri, e macara lu muttu latinu "melior de cinere surgo" si rifirisci a la stissa cosa. ==Stemma citati di Biancavilla== :Lu stemma è nu scudu troncu e è cumpostu di li siquenti sìmmuli <li> curona cìvica: misa sùpira a lu scudu e rapprisenta la municipalitati di Biancavilla;<li> suli radiusu: misu nta la parti àuta di lu scudu e ammenzu a l'azzurru ca simmulèggia lu celu; [[{{ns:6}}:Biancavilla-Stemma.svg|right|200px]] <li> zolla di terra; misa ntô vasciu, simmulèggia lu tirritòriu. Chistu sìmmulu, anzemi a lu suli radiusu e a lu celu azzurru, risarta lu significatu di Callicari" (anticu nomu di Biancavilla) ca 'n grecu signìfica 'bedda contrata'; <li> cavaddu: rapprisenta lu cavaddu di l'eroi nazzionali arbanesi [[Giorgiu Castriota]] chiamtu "Scanderbeg" , noltri, nzemi a lu cipressu, rapprisenta lu stemma gintilizziu di la famigghia di lu primu capitanu (sìnnacu) di Biancavilla [[Cesari Masi]];<li>cipressu: simmulèggia l'[[àrvulu]] unni, secunnu n'antica ricustruzzioni arbanisi, Giuvanni Castriota, figghiu di lu ''Scanderbeg'', doppu aviri lijatu lu cavaddu di sà patri e sarpau pi jiri nta l'[[Italia]] portannnu 'n sarvu la matri e la sò genti minazzata di lu nvasuri turcu mussurmanu Maumettu II;<li>turri: cumposta di tri pezzi e cu la finestra, è lu sìmmulu di li signuri di lu locu, li conti Moncada;<li>cruci greca: ricunferma l'appartinenza di li profuchi arbanesi a la riliggioni cristiana di ritu grecu-ortudossu;<li>nastru d'oru: misu sùpira la cruci greca e cu la scritta ''"Scanderbeg"'' ca, 'n àrrabbu, voli diri "Alessandru lu signuri o lu grandi";<li>curona di conti: misa sùpira lu nastru e la croci greca." <br> Testu pigghiatu dô statutu cumunali. ==Stemma citati di Bronti== [[{{ns:6}}:Bronte-Stemma.svg|right|200px]] La cità di Bronti havi nu propiu stemma cumpostu di:<li> n'àquila, cu dui curoni una sùpira la testa e l'àutra nta lu [[coddu]]; nta li quarti di lu stemma appàrinu: a manu dritta, nta l'àutu cincu palli nta lu funnali giallu, dui aquilotti curunati e dui strisci russi; nta lu funnali nìuru nu liuncinu e n'àquila nta lu funnali giallu, l'intermezzu di li dui stemmi è cuspaggiutu di gigghi: a manu manca, nta l'àutu setti gigghi sùpira funnali jancu, na turri e nu liuncinu; tri gigghi nta lu funnalli giallu; nta lu menzu a manu manca àutri dui quarti; unu cu li gigghi a destra, l'àutru cu li palli a sinistra e lu muttu ''Fidelissima Brontis Universitas'' (Bronti cità fidelissima).<br> Lu stemma è attravirsatu di nu munili di perli. La discrizzioni è pigghiata di lu "Statutu di lu cumuni di Bronti". ==Stemma citati di Cattabbianu== [[{{ns:6}}:Stemma calatabiano1.jpg|left|200px]] Lu Comuni havi comu segnu distintivu di la propia pirsonalitati giuridica lu stemma civicu. Lu stemma di Cattabbianu è custituitu di: scudu truncatu:nta lu primu campu di celu, a lu casteddu sdirubbatu (*), funnatu sùpira nu monti, lu tuttu a lu naturali; nta lu secunnu, d'azzurru, a cincu crucetti d'oru misi 'n cruci (**). <br> (La discrizzioni è pigghiata di lu "Statutu di lu cumuni di Cattabianu"). (*) Lu casteddu misu sùpira nu munti e ca talìa lu paisi di Cattabbianu, è na furtezza ca si penza havi n'urìggini àrabba, accussì comu addimustra lu sò nomu "Kaalat-bian" (casteddu di Bianu, ca avìa a èssiri cu prubbabbilità l'amministraturi e signuri).<ref>[https://web.archive.org/web/20080104172725/http://www.comune.calatabiano.ct.it/castello.htm Lu casteddu di Cattabbianu]</ref> (**) Li cincu crucetti ripigghiunu li nzigni di la famigghia "Crujllas" <ref>[https://web.archive.org/web/20070910223524/http://www.corteostoricocalatabiano.it/cruyllas.htm La famigghia Crujllas]</ref> ca s'attròvanu nta n'arcu 'n petra làvica d'intra lu casteddu di Cattabbianu. <references/> ==Stemma citati di Caltaggiruni== [[{{ns:6}}:Caltagirone-Stemma.svg|right|200px]] Lu stemma dû cumuni di [[Caltaggiruni]] è:<br> "D'argentu a la cruci di russu nta lu intra di nu scudu. Urnamenti esteriori di cità (comu di lu dicretu Prisidenti di la Ripùbbrica dû 6 aprili 1987). Fannu parti di lu stemma noltri, pri tradizzioni millinària, li urnamenti rafficuranti l'aquila curunata cu l'ali aperti e ca cu l'artigghiu destru teni n'ossu di gicanti, cu li grifoni alati a li lati.('''*''') (Discrizzioni pigghiata dô statutu cumunali appruvatu cu dilibbirazzioni n. 67 dû 23 aprili 2004) ('''*''')<li> L'aquila curunata cu l'ali aperti è l'anticu sìmmulu dâ cità.<li> La cità fu libbirata ntô [[1030]] dâ duminazzioni saracina di la cità di [[Genuva]]. Pri ricunuscenza Caltaggiruni ci misi ntô pettu di l'aquila dû stemma citatinu, lu granni scudu cruciatu russu nta lu campu jancu, tinuta di dui grifoni alati a li lati (sìmmulu dâ ripùbbrica marinara di Genuva). [[Catigurìa:Stemma]] [[Catigurìa:Pruvincia di Catania]] hm9bmsfw5zk99e7qb8q5n2giqjfufc0 Wikipedia:Circulu 4 33273 782029 781040 2026-05-13T10:29:20Z GiovanniPen 22308 /* Infobox disfunziunanti */ Risposta 782029 wikitext text/x-wiki __NEWSECTIONLINK__ [[Catigurìa:Aiutu|Circulu]] [[Catigurìa:Sirvizza|Circulu]] =Lu Cìrculu= <div style="border:3px solid #ccc; background: #fff; text-align: center; padding:3px; float:right; font-size: smaller; line-height: 1.3; margin-right: 5px;"> <div style="width:100%">{{CURRENTDAYNAME}}</div> <div style="font-size: x-large; width: 100%;">{{CURRENTDAY}}</div> <div style="width: 100%;"> {{CURRENTMONTHNAME}}</div> <div style="background: #aaa; color: #000;">'''{{CURRENTTIME}}''' UTC</div> </div> '''[http://scn.wikipedia.org/w/wiki.phtml?title=Wikipedia:Circulu&action=edit&section=new Cliccàti ccà pi scrìviri la vostra dumanna o la vostra assirvazzioni]''' ---- [[File:Circolo-Coversazione.jpg|thumb|450px|[[Circulu di Cunvirsazzioni a Rausa]]]] <gallery mode="packed-hover"> Achilles_Hector_triskele_cropped.jpg|Achilli e lu trisceli P7310046.jpg|Arancini Cassata.jpg|Na cassata dâ zona di Palermu Icon of the Sicily portal.svg </gallery> =Ntroducimentu= Siddu vuliti lassari un missaggiu: jiti â fini dî missaggi, criati un ==Tìtulu==, e lassati chiddu chi vuliti diri. Siddu vuliti jùnciri na discussioni, criati li ===Suttatìtuli=== etc oppuru '''[http://scn.wikipedia.org/w/wiki.phtml?title=Wikipedia:Circulu&action=edit&section=new Cliccàti ccà pi scrìviri la vostra dumanna o la vostra assirvazzioni]''' <br> putiti macari cuntattàrini supra la '''[irc://irc.freenode.net/wikipedia-scn Chat IRC n sicilianu]''' =Archiviu dô Cìrculu= *[[Wikipedia:Circulu/Archiviu]] == Santu == Salutamu a tutti, scrivu chistu pi' cumunicàrivi ca l'utenti Santu passò a 'na vita megghiu. Tanti beddi cosi a tutti. --[[Utenti:Smb16|Smb16]] ([[User talk:Smb16|msg]]) 16:05, 21 maj 2017 (CEST) :RIP. --[[Utenti:Markos90|Markos90]] ([[User talk:Markos90|msg]]) 16:48, 22 maj 2017 (CEST) :RIP. [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 10:14, 19 utt 2017 (CEST) :Si RIP. Vi risparmio il mio schifoso siciliano. Ho lasciato un avviso in stile internazionale. Magari scrivete qualcosa di più adeguato voi che lo conoscevate. Su it Wikipedia si usa la spilletta che usa chi è in lutto, ma non è corretto infatti la usa un vedovo molto conosciuto e ogmi tanto a qualcuno viene uno schianto credendo che ci abbia lasciato anche lui--[[Utenti:Pierpao|Pierpao]] ([[User talk:Pierpao|msg]]) 15:03, 11 nuv 2017 (CET) ::Ah in siciliano ovviamente io non ho osato :(--[[Utenti:Pierpao|Pierpao]] ([[User talk:Pierpao|msg]]) 15:04, 11 nuv 2017 (CET) ::Grazzi pi zoccu facisti. [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 21:15, 11 nuv 2017 (CET) == Cullabburazzioni == Salutamu a tutti, sugnu lu cu-funnaturi di la ''Cadèmia Siciliana'', urganizzazzioni senza prufittu funnata nnô 2016. Mi piacissi parrari cull'amministratura pirchì fùssimu 'ntirissati a dumannàrivi si si po' cullabburari cu vuatri. Avemu nnâ testa un pruggettu di prupunìrivi. Facìtimi sapiri quarchi cosa. --[[Utenti:Smb16|Smb16]] ([[User talk:Smb16|msg]]) 03:17, 31 ggt 2017 (CEST) *Salutamu, Turi! Chi bella idea di travagghiari anzèmmula! Aspittamu chi nni dìcinu l'autri. Ni sintemu! --[[Utenti:Vicè|Vicè]] ([[User talk:Vicè|msg]]) 23:57, 1 aus 2017 (CEST) :qui [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:39, 19 giugn 2024 (CEST) == Saluti! == Salutamu amici di wiki. Quarchi simana fa, pâ prima vota nzinu d’ottu anni fa, avìa vogghia di lèggiri tanticchia di sicilianu. Circannu, circannu, arristai dilusu picchì viramenti zoccu nn’attruvai nun era assai. Pi furtuna scuprìi stu situ [http://forum.cademiasiciliana.org Cademia Siciliana], chi hannu puru na pàggina di facebook attiva. Poi, cchiossai furtuna, quasi la prima jurnata mi scuntru cu dui utenti chi canuscìi tanti anni fa (ccà e cchiù avanti ntô linguasiciliana forum). E ora m’addunu ca chissi dâ Cademia hannu già fattu cuntattu cu scn.wiki, e macari vitti la mala nova di unu di nostri utenti vecchi. Accuminzai a lèggiri diversi pàggini, attruvai quarchi missaggiu di l’annu 2015, e vitti ca Peppi Melfi e Sarvaturi ancura travagghiàvunu ntâ Wikipedia. Chi surprisa! Ni stamu parranu d’armenu unnici anni di dèdica. Tanti auguri a vuiatri! Poi liggìi di n’utenti chi si chiamava ‘’Pippinu’’, chi ruvinau tanti pàggini, e pinzai ca statavi parrannu di mia! Pi diri la viritati, ju nun pozzu ricurdari assai di chi succidìu tant’anni fa, allura putissi cridiri pi veru ca facìa quarcchicosa sbagghiata a ddu tempu! (pi furtuna, nun si trattava di mia) Allura, vi dicu ca m’attrovu n’àutra vota ‘n circulazzioni ma nun sacciu siddu haiu àlica di fari stu tipu di travagghiu. Provu a dàricci n’ucchiata quarchi tempu, e facirmenti adaciu adaciu mi ritorna la capacità. Mi haiu scurdatu quasi tuttu di comu funziona Wikipedia, e oramai mi sentu vicchiareddu - è cchiutostu nu prucettu pi chiddi giuvani. Stati beni…. Pippu D'Angelo 12:37, 5 utt 2017 (CEST : test - [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 04:18, 17 utt 2017 (CEST) :qui [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:39, 19 giugn 2024 (CEST) == Rifari amministraturi Pippu D'Angelo == Comu supra, fatimi sapiri --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 10:44, 17 utt 2017 (CEST) * {{+1}} --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 10:44, 17 utt 2017 (CEST) * {{+1}} [[User:Gmelfi|Peppi]] 22:35, 17 utt 2017 (CEST) * {{+1}} Binidica a tutti vandri cumpà! Grazzi p'aviri cuntinuatu a purtari nn'avanti stu bellu pruggettu. Macari siḍḍu nun sugnu chiù attivu ancapu a scn.wiki, sugnu assai faurevuli a lu ritornu di Pippu comu amministraturi. Salutamu! --[[Utenti:Vicè|Vicè]] ([[User talk:Vicè|msg]]) 02:46, 22 utt 2017 (CEST) ::Grazzi a tutti! Armenu ora pozzu canciari la me pàggina d'utenti! [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 22:21, 23 utt 2017 (CEST) ::Pozzu accuminzari n'autra vota misculiannu l'àrticuli ntâ vitrina? Mporta si ripetu chiddi chi cci nni foru già o haiu a circari chiddi novi pi mintìricci? [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 05:01, 24 utt 2017 (CEST) :::Sì, tranquilllu. Puoi canciari tuttu chiddu ca vuoi, prorpiu comu na vota. [[User:Gmelfi|Peppi]] 09:12, 24 utt 2017 (CEST) :::Ok! :) [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 09:17, 24 utt 2017 (CEST) == comu usari lu passatu nsicilianu == Salutamu! Sugnu siculumirianu e staiu nzignannu sicilianu. Mi putiti spiegari comu usari li termini "au" e "ava"? P'asempiu, me nannu passava lu mari tri voti o ma nannu passau lu mari tri voti. Comu si sapi quannu usari l'unu o l'autru? Binidica a tutti :Ciau anònimu, fussi megghiu si ti riggistrassi (mi pari ca lu to sicilianu e' abbastanti bonu, e criju ca capisci già comu sti cunjugazzioni funziònanu). 'N ogni casu, «passava» fa parti dû mpirfettu. Si usa pi parrari di quarcchicosa c'avissi succidutu duranti nu pirìudu nnô passatu, p'asempiu, putissi diri ca to nannu passava lu mari quannu era carusu o cchiù giovanni, spiciarmenti si cci capitau n'àutru abbinimentu cchiù spicìficu (mentri ca passava lu mari chissu cci capitau...), o si parrassi di zoccu to nannu vulìa fari a ddu tempu: iddu avissi avutu spiranza di truvari travagghiu, e passava lu mari armenu tri voti circannu travagghiu. Ma si usa l'àutra furma (lu pritiritu) siddu vulissi discrìviri n'abbinimentu nnô passatu: to nannu passau lu mari tri voti, e sulu tri voti, e facirmenti nun cci passa cchiù. Ma siddu cci resta la pussibbilitati di travirsari lu mari n'àutra vota, putissi diri ca to nannu: avi già passatu lu mari tri voti (e facirmenti lu fa n'àutra vota...) Bonu, eni nu gran aiutu pi mia. Grazzi fratuzzu! == Registrazioni di utenze in automatico == Salve, mi chiedo se anche a voi è successo un qualcosa di particolare ieri. Una cosa che non riesco a capire è che si registrano utenze globali in automatico, a me è successo che mi ci si sono collegate ad altri progetti wikipedia che non le ho collegate io stesso, ma non so chi o cosa fa tutto questo??? qualcuno ne sa qualcosa? ho scritto [https://meta.wikimedia.org/wiki/Wikimedia_Forum#Automatical_global_user_registrations su meta]. --[[Utenti:S4b1nuz E.656|S4b1nuz E.656]] ([[User talk:S4b1nuz E.656|msg]]) 10:03, 11 fri 2018 (CET) == IMPORTANTE: rassegna dell'attività di amministrazione == Ciao. Una politica che riguarda la rimozione dei "diritti avanzati" (amministratore, burocrate, ecc) è stata adottata come parte [[m:Requests for comment/Activity levels of advanced administrative rights holders/Summary/it|sommaria della comunità]] nell'anno 2013: in accordo a questa politica, gli [[m:Stewards/it|Stewards]] stanno rivedendo le attività degli amministratori su tutte le wiki della Fondazione di Wikimedia con nessun criterio politico che potrebbe riguardare l'inattività delle utenze. Di tale principio, ne risulta che al meglio delle nostre conoscenze, le utenze sulle wiki non avrebbero un processo formale per la rimozione di questi "diritti avanzati" che per l'appunto riguarderebbe tutti gli account inattivi. E in una propria conclusione ciò andrà a significare che gli steward in accordo alla [[m:Admin activity review/it|rassegna dell'attività amministrativa]] si prenderanno cura di questo processo. Abbiamo stabilito che i seguenti utenti soddisfano i criteri di inattività (senza modifiche e senza azioni di registro per più di 2 anni): # Sarvaturi~scnwiki (burocrate, amministratore) Questi utenti ben presto riceveranno una notifica: ad essi si chiederà di avviare alla comunità una discussione se vogliono mantenere alcuni o tutti i loro diritti. Quindi, se gli utenti non rispondono alla discussione richiesta, i loro diritti che precedentemente hanno mantenuto sino a quel momento saranno rimossi dagli amministratori. Tuttavia, se dalla comunità si vorrebbe creare il proprio processo di rassegna di attività che sostituisce quello globale, si potrebbe prendere un'altra decisione di quei diritti dei detentori che sono inattivi dove codesti utenti hanno già una politica, ma la stessa fu superata e non è più valida. Pe cui, si è pregati di avvisare gli Stewards ([[:m:Stewards' noticeboard|stewards on Meta-Wiki]]), laddove gli steward senza determinato avviso non potranno sapere se procedere o astenersi al riesame dei diritti wiki di questi utenti. Grazie. '''[[User:Rschen7754|Rs]][[User talk:Rschen7754|chen]][[Special:Contributions/Rschen7754|7754]]''' 08:01, 10 aus 2018 (CEST) == IMPORTANT: Admin activity review == Hello. A policy regarding the removal of "advanced rights" (administrator, bureaucrat, interface administrator, etc.) was adopted by [[:m:Requests for comment/Activity levels of advanced administrative rights holders|global community consensus]] in 2013. According to this policy, the [[:m:stewards|stewards]] are reviewing administrators' activity on all Wikimedia Foundation wikis with no inactivity policy. To the best of our knowledge, your wiki does not have a formal process for removing "advanced rights" from inactive accounts. This means that the stewards will take care of this according to the [[:m:Admin activity review|admin activity review]]. We have determined that the following users meet the inactivity criteria (no edits and no logged actions for more than 2 years): # Klone123 (administrator) These users will receive a notification soon, asking them to start a community discussion if they want to retain some or all of their rights. If the users do not respond, then their advanced rights will be removed by the stewards. However, if you as a community would like to create your own activity review process superseding the global one, want to make another decision about these inactive rights holders, or already have a policy that we missed, then please notify the [[:m:Stewards' noticeboard|stewards on Meta-Wiki]] so that we know not to proceed with the rights review on your wiki. Thanks, [[Utenti:Stanglavine|Stanglavine]] ([[User talk:Stanglavine|msg]]) 02:24, 19 jin 2022 (CET) == Collaborazione == Buongiorno amici siciliani. Vorrei proporvi, dopo dicembre 2022 (in quel mese faremo una nostra editathon), una collaborazione: ne abbiamo già fatta una con la Wikipedia in galiziano e una con quella in ladino dolomitivo. Si tratterebbe di scegliere un tot di voci relative alla storia, alla cultura, alla lingua e al territorio di Sicilia e Lombardia e scriverle sulle rispettive enciclopedie. Che ne dite? -- [[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 19:48, 24 nuv 2022 (CET) :{{Ping|Sciking}} (commento utente non siciliano) Ciao Sciking, purtroppo devo dire che di utenti attivi siciliani su questa Wiki non ce ne sono al momento... in genere controllo il ''Canciati antura'' vedendo che la maggior parte di modifiche son fatte dagli IP (qualche volta vandaliche), altre invece da utenti/IP stranieri (ad es. aggiungono delle liste riguardo a delle serie televisive, cambiare immagini oppure aggiornare qualche info). :A parere mio, l'idea la trovo carina :-), ma ti consiglierei di proporla su un'altra Wiki con utenti più attivi. :Puoi provare a proporre sulla Wiki ligure (di cui sono un admin), emiliano-romagnola, napoletana, veneta, piemontese, sarda e/o tarantina dove ti posso garantire che son presenti degli utenti attivi madrelingua/quasi madrelingua. Saluti. --[[Utenti:S4b1nuz E.656|<span style="color:#009246;">'''S4b1nuz'''</span> <span style="color:#CE2B37; font-family:futura">'''ᴇ.656'''</span>]]<sup>[[Discussioni utenti:S4b1nuz E.656|<span style="color:#006AA7">''(SMS)''</span>]]</sup> 14:14, 25 nuv 2022 (CET) ::{{ping|S4b1nuz E.656}} uno di questi giorni passo su quella in ligure, allora. --[[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 19:06, 30 nuv 2022 (CET) :::{{ping|Sciking}} Ciao di nuovo, a ripensarci che siamo verso il periodo Natalizio e tra 1 mese di Epifania, credo che alcuni utenti potrebbero fare qualche Wikipausa. Sarebbe meglio che punti sul vostro Editatlon di Wikipedia lombarda... La tua collaborazione temporanea potresti proporla in un altro periodo dell'anno 2023 (sempre su qualche Wiki a tua scelta). Saluti e buon weekend! --[[Utenti:S4b1nuz E.656|<span style="color:#009246;">'''S4b1nuz'''</span> <span style="color:#CE2B37; font-family:futura">'''ᴇ.656'''</span>]]<sup>[[Discussioni utenti:S4b1nuz E.656|<span style="color:#006AA7">''(SMS)''</span>]]</sup> 23:02, 3 dic 2022 (CET) ::::qui [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:32, 19 giugn 2024 (CEST) == Traducemu la Wikipedia in sicilianu == Pi sviluppari la Wikipedia siciliana, putemu traduciri articuli dâ Wikipedia nglisi e di l'italiana. E un tradutturi miccanicu pò fari lu travagghiu chiù facili. La machina pò traduciri na cintinara di articuli, e l'essiri umanu havi sulu a curreggiri li sbagghi. Ora ca [https://translate.napizia.com/ lu tradutturi di Napizia] funziona megghiu, putemu usarlu pi traduciri na cintinara di articuli pi Wikipedia siciliana. Allura haiu l'intinzioni di traduciri miccanicamenti articuli pi Wikipedia siciliana. Ma prima di farlu, scrivu stu missaggiu pi annunziari la mè ntinzioni. Vulissi sentiri lu vostru cunzigghiu. [[Utenti:Eryk Wdowiak|Eryk Wdowiak]] ([[User talk:Eryk Wdowiak|msg]]) 07:26, 22 apr 2023 (CEST) :Mantegnu un [[Utenti:Eryk Wdowiak|elencu dî mè traduzzioni miccanichi]] â mè paggina. [[Utenti:Eryk Wdowiak|Eryk Wdowiak]] ([[User talk:Eryk Wdowiak|msg]]) 00:06, 25 apr 2023 (CEST) :Pi dumannari na traduzzioni, vi preju di lassari un missaggiu ntâ [[Discussioni_utenti:Eryk_Wdowiak|discussioni]]. [[Utenti:Eryk Wdowiak|Eryk Wdowiak]] ([[User talk:Eryk Wdowiak|msg]]) 16:14, 25 apr 2023 (CEST) :: anche [https://traduttoresiciliano.blogspot.com/2016/07/traduttore-italiano-siciliano.html qui] e [http://www.salviamoilsiciliano.com/come-si-dice/dizionario/ glossario] [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:31, 19 giugn 2024 (CEST) == creare alias redirect namespace == Ciao, penso sia utile a tutti avere i namespace abbreviati (alias), analogamente a come avviene su itwiki e altri progetti (per comodità typing e linguistiche).<br> Ad esempio: T=Template C=CAT=Categoria=Category=Catigurìa (poi ci sarebbero anche DP e DW per le talk) Se è fattibile potremmo fare richiesta su phabricator :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 14:38, 28 sit 2024 (CEST) : Yes. Credo sia molto fattibile e sensato. Se ho capito correttamente si tratterebbe di modificare questo file per fare una cosa del genere: : https://phabricator.wikimedia.org/source/mediawiki-config/browse/master/wmf-config/core-Namespaces.php;b0c00bf7406275732056e3672d802f3c7f58ee8b$868-873 : quindi aggiungere qualcosa del genere: <pre> '+scnwiki' => [ 'CAT' => NS_CATEGORY, 'DP' => 103, 'DW' => NS_PROJECT_TALK, 'T' => NS_TEMPLATE, 'U' => NS_USER, ],</pre> Quindi si potrebbe aprire un task del genere: [[phabricator:T101274]] (alle gentili persone che frequentano [[phabricator:tag/wikimedia-site-requests/]]) asd --[[Utenti:Valerio Bozzolan|Valerio Bozzolan]] ([[User talk:Valerio Bozzolan|msg]]) 14:58, 28 sit 2024 (CEST) ::Sono d'accordo. [[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 13:52, 29 sit 2024 (CEST) :::haiu criatu a pàggina su phabricator: a truvati [[phabricator:T375979|cca]] [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 18:42, 29 sit 2024 (CEST) ::::Ho aggiunto DU => NS_USER_TALK. Per la storia di C o CAT CAT va bene lo stesso anzi per certi aspetti è meglio. Ho riprogrammato la richiesta di Developer perché nella sezione odierna erano impegnati --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 23:00, 30 sit 2024 (CEST) :::::grazie ∞ [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 00:54, 1 utt 2024 (CEST) == Politica dialettale == Una cosa che ho imparato su lmowiki è l'importanza di una politica dialettale fatta bene e di come prevenga problemi più avanti, vi suggerirei di adottarne una ben strutturata. Prima di tutto bisogna discutere di grafia: mi pare di capire che qui ci siano delle convenzioni ortografiche che, se hanno una base nella storia del siciliano, possono rimanere, ma bisogna anche capire se vi sono altre ortografie in uso che vanno accettate o usate. Soprattutto, per salentino e calabrese c'è da capire quali sono delle modalità di scrittura accettate e qual è la classificazione dialettale più comunemente accettata per essi. In Lombardia abbiamo un gruppo contiguo, quindi classifichiamo per grafia principalmente, ma nel vostro caso potrebbe aver senso dividere prima in siciliano, salentino e calabrese ed eventualmente poi fare sottoclassificazioni grafiche e dialettali. Una cosa da deprecare sono le voci scritte più volte in più dialetti. [[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 23:28, 1 utt 2024 (CEST) :sono d'accordo sul deprecare le voci scritte in più lingue. approfittando del flag temporaneo di admin che mi è stato concesso possiamo identificarle, risistemarle quando necessario ed eventualmente eliminarle (quando presenti in molteplici versioni). [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 17:34, 5 utt 2024 (CEST) ::Nell'edizione scn.wikipedia un consenso sull'ortografia è stato raggiunto una ventina di anni fa. Il risultato fu il frutto di un confronto costruttivo tra amministratori originari di varie parti della Sicilia, e ha preso in conto anche la problematica di poter essere compatibile con le varianti continentali di Clalbria e Salento. Molte voci sono d'altronde dedicate a spiegare bene l'uso dell'ortografia siciliana da preferire. L'uso episodico di altre ortografie è comunque tollerato nella misura in cui lo spirito del progetto wikipedia non è snaturato. Sono d'accordo che una voce deve essere scritta in una sola versione. [[User:Gmelfi|Peppi]] 10:47, 23 utt 2024 (CEST) :::penso che sfrutteremo anche il più recente documento sull'ortografia della [[Cademia Siciliana]]. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 13:08, 23 utt 2024 (CEST) :::: Ricordo che le basi ortografiche e grammaticali per questa edizione di wikipedia sono state poste diversi anni fa e figurani nelle pagine raggiungibili dal menu a sinistra [[Cumpenniu stilisticu|Wikipedia:Cumpenniu Stilisticu]] e [[Grammatica|Wikipedia:Grammatica]]. Si veda anche [[WP:Mutivi dî nostri scigghiuti ortugràfichi]] per maggior chiarezza. [[User:Gmelfi|Peppi]] 18:35, 27 utt 2024 (CET) == Ntirventi nti scn.wikipedia== Pi favuri, nun fari canci di massa senza aviri fattu na discussioni e aviri avutu nu cunsensu supra la quistioni cu l'autri utenti di wikipedia. Appi a rimettiri annarrèri tutti li pàggini di austu. L'azzioni di fari canci di massa senza consensu è assai dannusa pi lu proggettu. E sparti di chistu nun arricanusci lu trfvagghiu di qualitati fattu nti l'urtimi vint'anni. Pi esseri chiaru, si l'amici dâ Ccademia vonu contribbuiri sunu binvinuti, ma l'ortografìa nun si cancia di maniera massiva supra li pâggini criati nzinu a ora, e senza nu cunsensu adequatu. Esistunu già nu cumpenniu stilisticu e reguli ortografichi assai precisi, e s'hannu a rispittari. Naturalmenti articuli scritti cu na varianti di l'ortografia accittata sunu accittati (s'havi a mettiri nu disclaimer nti stu sensu), ntâ misura n cui nun snaturanu lu progettu ntê sò integritati. [[Utenti:Gmelfi]] ([[User talk:Gmelfi|msg]]) :Caru Giovanni. Ti vulìa scriviri a prupositu dâ qualitati ca avemu a tèniri nti sta wikipedia. Nzinu a ora, ni semu basati supra li documenta sritti n scilianu, e n particulari li vocabbulari n sicilianu ca sunu disponibbili su Google Libri. Avemu a tèniri nu liveddu di qualitati assai àutu pi stu pruggettu. E' funnamintali puru scriviri n sicilianu, puru ntê discussioni ntra nuautri. Ci sunu diversi cosi ca si ptutissiru discurriri supra li ntirventi ca hannu statu fatti ricintimenti. Per esempiu, la parola "mudeddu" in sicilianu nun l'haiu mai vista né scritta né orali. Tu usi sta parola di sta manera ? Hai nu documentu ? Ntâ lingua parrata si dici "modellu", e nun è nu neologgismu italianu! Se vai a taliari lu vocabbulariu di Pasqualino (ca havi cchiossai di 100 anni) (chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://books.googleusercontent.com/books/content?req=AKW5QaffEUJyww3-xhSrpvu5Ae8Q8i_iJwqcs5KqRNhvsT3nMxgGF7pLiudlP_-hgvFgyEgtByftSjMywsqL4EtmMA9tUbI_9PKnQ6NoxjdME6CyQmd9Hdp4egkfT96bqUU0S18QG2MriYEZ-nC6YHjCsEvZEPVQkRu7I0SAOI6fkATgMnB5Ow887ZtLIoaHbjovEkmdGQr2jOteSs7g-fK4bLdGaMTXhaDyu0OMcumkQ9GnADSE_f4_3XEtFpHI9G1Qn6scLEiGceihml1quzQ5B_yNZS_qHkzL_XH-dj_OVGfNQlslkso) c'è scrittu "modellu". perciò la regola ca s'havi sempri a scrivri la doppia ll cu la doppia dd nun è na regula ginirali, contrariamenti a chiddu ca si cridi. E nun s'hannu a nvintari paroli cu n'ortografia inesistenti, senno la qualitati ginirali s'abbassa. N'autra quistioni assai dubbia (secunnnu mia) è l'usu di la doppia dd cu lu puntu di sutta. Capisciu la ntinzioni di rènniri lu suonu particulari di la doppia dd n siclianu, ma secunnu mia è utopicu pinsari ca stu tipu di ortografia veni aduttata di tutti, pirchì è simpricimentu troppu cumpricatu. Na soluzioni raggiunevuli pir mia fussi chista: La doppia dd puntata si pò usari, ma nun si pò obbligari l'usu nti l'usu giniralizzatu ntâ scrittura siciliana. Sta soluzioni è usata n italianu, unni li paroli ntô vocabbulariu cuntenunu accenti gravi o acuti (quannu dannu nnicazzioni supra la prununcia), ma ntâ lingua scritta, currenti l'accenti sunu piazzati sulu pê paroli accintati all'urtima sillaba. [[User:Gmelfi|Peppi]] 11:23, 28 utt 2024 (CET) ::{{ping|gmelfi}} ::sono d'accordo con te e anch'io ritengo sia importante scrivere anche tra di noi nelle discussioni in siciliano (ma non mi sento particolarmente in grado e quindi anche per brevità scrivo in italiano) ::uso anche ad esempio l'interfaccia tradotta di firefox e telegram. ::le uniche cose che mi vengono da dire sono: le lingue evolvono (e tra queste anche il siciliano) difatti ci sono dei termini che non esistevano e che non sentirai mai dire "in giro"; le indicazioni sulla scrittura me le ha fornite {{ping|dapal}} seguendo il lavoro dei linguisti e della ''Cademia Siciliana'', quindi un documento seppur recente c'è. ::ps la tua firma sta volta ha funzionato correttamente. ::pps come detto altre voltre, imho le pagine personali non sono il posto migliore dove fare queste discussioni. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:51, 28 utt 2024 (CET) <div><span style="font-family: verdana, sans-serif; color: white; background: blue; font-weight: bold; border: 1px solid black; font-stretch: ultra-condensed">cb</span> ''La discussione proviene dalla pagina '''[[Discussioni_utenti:GiovanniPen#Ntirventi_nti_scn.wikipedia]]'''''.<small><br /> – Il [[Wikipedia:Cambusa|cambusiere]] --[[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) [fuori crono] 15:31, 28 utt 2024 (CET) </small></div> :Salutamu. :M'hâ pirdunari, ma anestu sintìrimi diri ca "mudeḍḍu" nun esisti, e chi mmeci àvi a siri ''mudellu'', è na fissarìa. [https://imgur.com/a/xTXWPWq Chista è na schirmata dû Vucabbulariu Sicilianu], unni è attistatu ''mudeḍḍu''. Cchiù assai, mudeḍḍu appatta cû ''vucalìsimu sicilianu'', mmeci ''modellu'' (chi speru fussi nu sbagghiu, vistu chi Pasqualinu dici mudellu) no, vidi pi scempru la O àtuna (puru chi cci sunnu eccizzioni a tipu l'accenti sicunnari o si a palora trasìu nnô sistema sicilianu 'n tempi ricenti). :Nuiautri dâ [[Cademia Siciliana]] àvi anni chi circamu palori pi adattalli â vita di oji, cunzidirannu macari chi a lingua è na cosa viva, e circamu d'adattari macari a lingua scritta. Si parri talianu, tu 'un parri comu Danti, adunca 'un capisciu st'attaccamentu â lingua dî pueti. Pueti chi poi, nun avennu nuḍḍa norma ortugràfica, scrivìanu ognidunu comu vulìa. :Sicunnu poi, a ḍḍ è na granni vittoria pâ lingua siciliana. Scrivilla è fàcili [https://cademiasiciliana.org/tools-it/sicilian-language-keyboard-layouts-microsoft-windows/ câ nostra tastera], e fìcimu mèttiri macari a littra nne Android, e si po' scrìviri macari di iOS. Si circamu a qualità, s'àvi a usari ḍḍ unni serbi. Vulennu, unu putissi scrìviri ddh/ddr, e poi fariccillu abbirsari ôn bot. :Pâ custioni lu/u: nuiautri pinzamu ca ''lu'' s'avissi a usari nnê testi furmali (statuti, liggi), o pi riprisintari ḍḍi dialetti unni si dici. Pi Wikipedia, puru tinennu 'n cuntu ca è na nciclupidìa, pinzamu ca è megghiu falla cchiù vicina a comu parra a genti, pi falla cchiù accissìbbili. E tû dici unu chi veni di unu di ḍḍi posti unni si ''dici'' lu ([[Mazzara]], ma macari nnô [[Girgenti|giurgintanu]]. Già a [[Marsala]], pi diri, dìcinu ''u'', e si vidìssiru scrittu ''lu'' parissi fausu e furzatu. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 15:02, 28 utt 2024 (CET) ::@[[Utenti:Gmelfi|Gmelfi]] @[[Utenti:GiovanniPen|GiovanniPen]] spustai cca a discurruta! [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 15:20, 28 utt 2024 (CET) :::<small>grazzi. abbissai comu u template ''Cambusa'' di itwiki.</small> [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:35, 28 utt 2024 (CET) :::Grazzî pâ discussioni. Ristamu costruttivi. Tuttu lu rispettu pô travagghiu dâ Ccademia. Arrispettu lu travagghiu pi la promuzzioni dû sicilianu, pi aviri travagghiatu pi interfacci di traduzzioni nti diversi applicazioni nfurmatichi. Ma resta lu fattu ca Wikipedia.scn (ca esisti di cchiossai di 20 anni) nun è n'organu dâ Ccademia, e la Ccademia nun mi pari ca havi na arricanusciuta a liveddu accademicu, macari ca porta lu nomu. Cu sunu li linguisti e li filùluggi ca travagghiunu ntâ Ccademia ? Ntâ pàggina "Cu siemu" nun c'è scrittu! M'agghiu ligghiutu lu documentu pi l'ortografia siciliana dâ Ccademia. E' nu travagghiu apprizzabbili, ma è assai cchiu riddottu di tuttu lu travagghiu ca fu fattu nti scn.wikipedia ntra l'utilizzatura ca accuminzarru lu progettu 20 anni fa. Se talìi li pàggini cu li reguli grammaticali e li formi prifiruti, ci sunu spiegazzioni ca s'abbasunu supra documenti scritti, vocabbulari e quant'autru, e nun sunu simpricimenti na scigghiuta di unu ca si suisu dû liettu. :::E ancora cu tuttu lu rispettu, la schirmata di "mudeddu" ca m'ammusciasti dici "vedi modellu", e veni a diri ca la forma cchiù usata è senza dubbiu modellu. Tô rici quarcunu ca ha usatu sta parola n sicilianu, pi esempiu quannu unu vâ ô comuni pi jinchiri nu modellu pi na autucertificazzioni. Ca la lingua siciliana evolvi nun lu mettu n dubbiu. Ma nun vor diri ca avemu a nvintari paroli ca nun esistunu né ntâ lingua parrata né ntâ lingua scritta o ca avemu a prumòviri paroli (comu mudeddu) ca puru se esistunu hannu n'usu minoritariu rispettu a formi assai cchiù usati (comu modellu). [[User:Gmelfi|Peppi]] 15:56, 28 utt 2024 (CET) ::::Amâ fari tanti cosi. chistu è u fattu. (tipo sistemare l'ortografia dei mesi) ::::appoi, secunnu mia, mmeci di prioccuparisi troppu, usamu direttamente "template" e bonu cchiu (anche picchì u namespace non lo possiamo cambiare, e sarebbe un lavorone). ::::d'autra banna nun putemu, secunnu mia, accittari palori grammaticamenti sbagghiati sulu picchì sunnu cchiù cumuni / cchiù diffusi. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:03, 28 utt 2024 (CET) ::::U Ducumentu pi l'Ortugrafìa dû Sicilianu fu uggettu di discurruta di tesi accadèmica, e ancora oji ci travàgghianu ricircaturi ca sunnu nnô munnu accadèmicu. Ntra tutti, @[[Utenti:Smb16|Smb16]]. Certu ca Wikipedia nun è na succursali di Cademia (cu na C sula pi favuri, è nomu propiu), ma a nostra ortugrafìa è bastanti stàbbili, e veni usata macari di genti chi câ Cademia nun cci tràsinu nenti. E nun sulu: fu pinzata macari pi èssiri leggia e fàcili di usari. ::::Ora, certu nuḍḍu àvi ntinzioni di supranijàriti, ma mancu putemu stari fermi a "u fìcimu vint'anni nn'arrè, àv'a stari accussì pi sempri", e pi chistu ti dissi chi viatu faraju na pruposta pi canciari u Cumpenniu Stilìsticu pi usari a nostra ortugrafìa. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 17:53, 28 utt 2024 (CET) :::::Lu cumpenniu stilisticu, cu la Grammatica e l'ortografia raccumannata pirmisiru di criari nu pruggetu stabbili e nun vidu pirchì s'havissi a canciari. Comunqui si quarchi contribbuturi voli scriviri cu n'autra ortografìa spirimintali, abbasta ca metti lu tag adequatu, e pir mia nun c'è probblema. Cô tempu si vidi se s'havi a canciari quarchi cosa ntê raccumannazioni ca damu ê utilizzatura. [[User:Gmelfi|Peppi]] 15:33, 29 utt 2024 (CET) ==Infobox disfunziunanti== Cari culleghi di scn, nutai ca diversi pàggini cuntênunu infobox ca nun funzionanu bonu. Per esempio la pàggina [[Etna]] nun pigghia li cuurdinati giografichi e l'infobox è strammu. Na cosa simili succedi pî prisidenti dê Stati Uniti e tanti autri catigurii di pàggini. Quarchid'unu di vuatri si fira a sistimari li bug ? Iu nun mi la firu (sugnu troppu viecchiu, forsi, :-) ). Diciemu ca tra na pàggina cu nu infubox disfunziunanti (ca nun è WIP) e na paggina senza infobox, è megghiu na pàggina senza infobox. Pirciò annunciu ca ntê prossimi jorna se nenti veni fattu, li infobox ca nun funzionanu currittamenti sunu distinati a essiri cancillati. [[User:Gmelfi|Peppi]] 22:49, 30 utt 2024 (CET) :salutamu, :staiu pruvannu cu @[[Utenti:Dapal|Dapal]] ad abbirsari diversi template e i Mòduli che non funzionano o che non sono tradotti. :accamora iddu sta rifacendo T:Bio (mi pare) :sono d’accordo che se gli info box non funzionano tanto vale levarli. Io mi sono accorto che ci sono assai template da scancillari direttamenti, tuttu arristau fermo a 10anni arrè. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 10:30, 31 utt 2024 (CET) ::@[[Utenti:Gmelfi|Gmelfi]] cunfermu, staju travagghiannu a chiḍḍu pî biugrafìi, e chiḍḍu usa {{tl|Infobox}}, chi dintra usa {{tl|Navbox}}. Abbisogna n'anticchia di tempu, ma a picca a picca abbirsamu tutti cosi. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 11:20, 31 utt 2024 (CET) :ps l'etna non ha le coordinate inserite e il template ancora non è stato aggiornato per prenderle da wikidata. lo faremo asap [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 04:40, 16 nuv 2024 (CET) ::diversi infobox funzionano, alcuni vanno semplicemente inseriti o sostituiti/aggiornati. altri purtroppo non sono ancora stati corretti e possono apparire "rotti" ::@[[Utenti:Dapal|Dapal]] stava sviluppando t:bio ma non è ancora stato pubblicato (è nelle sue sandbox mi pare) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 19:29, 5 fri 2025 (CET) :@[[Utenti:Gmelfi|Gmelfi]] abbissai i cuurdinati :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:29, 13 maj 2026 (CEST) == Proposal to enable the "Contribute" entry point in Sicilian Wikipedia == {{Int:Hello}} Sicilian Wikipedians, Apologies as this message is not in your language. {{Int:please-translate}}. The [[mediawikiwiki:Wikimedia_Language_and_Product_Localization|WMF Language and Product Localization]] team proposes enabling an entry point called "Contribute" to your Wikipedia. The [[:bn:বিশেষ:Contribute|Contribute]] entry point is based on collaborative work with other product teams in the Wikimedia Foundation on [[mediawikiwiki:Edit_Discovery|Edit discovery]], which validated the entry point as a persistent and constant path that contributors took to discover ways to contribute content in Wikipedia. Therefore, enabling this entry point in your Wikipedia will help contributors quickly discover available tools and immediately click to start using them. This entry point is designed to be a central point for discovering contribution tools in Sicilian Wikipedia. '''Who can access it''' Once it is enabled in your Wikipedia, newcomers can access the entry point automatically by just logging into their account, click on the User drop-down menu and choose the "Contribute" icon, which takes you to another menu where you will find a self-guided description of what you can do to contribute content, as shown in the image below. An option to "view contributions" is also available to access the list of your contributions. [[File:Mobile_Contribute_Page.png|Mobile Contribute Page]] [[File:Mobile_contribute_menu_(detailed).png|Mobile contribute menu (detailed)]] For experienced contributors, the Contribute icon is not automatically shown in their User drop-down menu. They will still see the "Contributions" option unless they change it to the "Contribute" manually. This feature is available in four Wikipedia (Albanian, Malayalam, Mongolian, and Tagalog). We have gotten valuable feedback that helped us improve its discoverability. Now, it is ready to be enabled in other Wikis. One major improvement was to [[phab:T369041|make the entry point optional for experienced contributors]] who still want to have the "Contributions" entry point as default.           We plan to enable it '''on mobile''' for Wikis, where the Section translation tool is enabled. In this way, we will provide a main entry point to the mobile translation dashboard, and the exposure can still be limited by targeting only the mobile platform for now. If there are no objections to having the entry point for mobile users from your community, we will enable it by 10th December 2024. We welcome your feedback and questions in this thread on our proposal to enable it here. Suppose there are no objections, we will deploy the "Contribute" entry point in your Wikipedia. We look forward to your response soon. Thank you! On behalf of the WMF Language and Product Localization team. [[Utenti:UOzurumba (WMF)|UOzurumba (WMF)]] ([[User talk:UOzurumba (WMF)|msg]]) 05:38, 28 nuv 2024 (CET) :imho it doesnt make sense that if i ckick on my account icon i'll not find my contributions immediatly but a generic "contribute" page. :Moreover [[Special:WantedPages]] is not reliable at all (expecially in our scn wikipedia). :i think it can be a good things for unexperienced user and to reach easier the translation, but no. thanks [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:40, 28 nuv 2024 (CET) ::Thank you @[[Utenti:GiovanniPen|GiovanniPen]], for your feedback. To clarify your comment: ::<blockquote>imho it doesnt make sense that if i ckick on my account icon i'll not find my contributions immediatly but a generic "contribute" page.</blockquote> ::For you with edits in Sicilian, Italian, and other Wikipedias, if you click on your account icon in those Wikis, you will still find your contributions icon immediately and not the "contribute" page (even after the "Contribute" is enabled there) because you have edits in those Wikipedias. The only scenario where you will find the "Contribute" entry point is if you go to the Albanian Wikipedia or any other Wikipedia you don't have any edits. It will then assume you are a new contributor and take you through that entry point to help you discover different ways to contribute. ::I hope the above clarifies that the "Contribute" entry point will only be seen by new contributors in any wikipedia where the entry point is enabled or if a contributor with edits decides to change their setting to the "Contribute" entry point. Please let me know if you have any questions. Thanks! [[Utenti:UOzurumba (WMF)|UOzurumba (WMF)]] ([[User talk:UOzurumba (WMF)|msg]]) 05:01, 3 dic 2024 (CET) == Cademia e quistioni di ortugrafìa == L'espirienzia di quarchi simana ammustra ca certi articuli ca portunu lu template "Cademia Sicialiana" sunnu scritti di na manera ca è cumpatibbili chê reguli grammaticali n usu nti l'autri pàggini. Nun havi tantu sensu distinguiri l'articuli ca hannu lu template e chiddi ca nun ci l'annu. Li quistioni cchiù mpurtanti mi parunu l'articulu determinativu (ca s'avissi a usari nti la forma littiraria, comu è usatu d'altrondi puru ntâ rivista ca la Cademia a traduciutu pi cuntu di l'Unescu, e venardiri "Lu, Li, La" nveci di "u i a"), e la duppia dd, ca si po tranquillamenti lassari libbira di putìrisi scriviri cû duppiu punti di sutta (pê wikipidiani esperti) o senza duppiu puntu di sutta (chiù facili pi cuegghié). Naturalmenti ci sunnu assai quistioni ca si putìssiru discurriri, e spissu l'utilizzatura si pigghiunu la libbirtati di scriviri comu sunnu abbituati a parrari ( e ci sinnu parrati assai diversi di na pruvincia all'autra). Ma la basi cumuni ca havemu (la grammatica, lu cumpenniu stilisticu, e ci junciu puru lu documentu dâ Ccademia, senza cuntari tutti li dizziunari antichi e no, li risursi n sicilianu dispunibbili unnegghié) dunanu na bona dirizzioni ca avemu a cuntinuari a sviluppari, nti nu spiritu cullabburaticu e custruttivu tutti nsemmula. [[User:Gmelfi|Peppi]] 14:38, 28 nuv 2024 (CET) :Salutamu Gmelfi! Ni prija assai ca ti piaci u nostru travagghiu e puru nuiautri, comu già sai, tannu partemmu propia dû Cumpenniu Stilìsticu dâ Wiki comu rifirimentu ntra l'autri. L'ortugrafìa dâ Cademia pirò nun è sulu lu/la/li (accittati dâ nostra pruposta comu "furmi auti") o i ḍḍ, ma è na pruposta ca stamu ammuttannu pi criari un criteriu d'arfabbitizzazzioni a liveḍḍu pupulari, vali a diri, nun putemu cchiù jiri avanti pinzannu a na lingua ca veni parrata tuttu u jornu, tutti i jorna ma unni nuḍḍu a sapi scrìviri. U Cumpenniu Stilìsticu dâ Wiki àvi assai punti ca foru attinziunati dintra â nostra assuciazzioni e certi cosi, ora mai, lassaru u so tempu (vidi l'h pû verbu aviri, usati 'n italianu pi spártiri u verbu di autri minutagghi, ma nùtili tutali ntô cuntestu sicilianu). Pigghiamu macari a cura chi s'àv'a aviri ntâ scigghiuta dî paroli. :A Wikipedia nun po e nun àvi a èssiri un rifirimentu linguìsticu picchì nun è a missioni di nuḍḍa Wiki nta nuḍḍa lingua. I liggi e i règuli di na lingua sunnu, di sòlitu, manijati di enti terzi, cumposti di spicialisti. L'ubbittivu dâ Wiki nun è diri comu s'àv'a scrìviri e comu no (ca tantu videmu ca sulu picca sicùtanu un criteriu), ma criari cuntinutu fruìbbili ntâ lingua. [[Utenti:Zoologo|Zoologo]] ([[User talk:Zoologo|msg]]) 20:43, 28 nuv 2024 (CET) ::@[[Utenti:Gmelfi|Gmelfi]] @[[Utenti:Zoologo|Zoologo]] se nun usati u ping... [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:45, 6 dic 2024 (CET) :::nun v'acchiappati (macari senza parrari... puru cu l'editwar) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 11:13, 7 sit 2025 (CEST) ::::Comu discussu ca supra lu template "Cademia" nun è nicissariu. Chiddi ca vòlunu scriviri chê reguli grammaticali e ortografici di la Cademia lu ponnu fari tranquillamenti e la cosa è sustanzialmenti cumpatibbili chê reguli fissati ntâ grammatica e ntô cumpenniu stilisticu. Arricordu ca lu templati fu intrudottu pi distinguiri l'articuli cunformi â scn.wiki di chiddi cunformi ê reguli dâ Cademia. Appressu la quistioni di l'articulu ditirminaticu fu discurruta a parti e ni '''misimu d'accordu supra l'usu di lu la li''' (e sparti, l'articuli lu la li foru usati dâ Cademia puru pi lu giurnali di l'Unescu di cui curau la traduzzioni n sicilianu): pi la quistioni di la doppia dd, si pò lassari la libbirtati di usu (nun è facili pi l'utilizzaturi cuegghé di usari la doppia dd chê punta di sutta). Anzi nvitu quarcunu di la cademia di cumpritari lu cumpenniu stilisticu pi l'usu di la duppia dd. Pi tutti l'autri quistioni, c'è na sustanziali cumpatibbilità tra li reguli di scn e di la Cademia. L'usu dû template è pirciò càducu. [[User:Gmelfi|Peppi]] 12:39, 7 sit 2025 (CEST) :::::il template imho è utile, sia per catalogare le voci "corrette" riviste o aggiornate ma anche per identificare una grafia da un'altra... lo stesso di come fa lmo wiki per le varianti etc (@[[Utenti:Sciking|Sciking]], no?). [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 14:41, 7 sit 2025 (CEST) :::::comunque andare a fare un rb quando la modifica è valida va contro alla policy [[:it:WP:MORDERE]] imho... [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 14:42, 7 sit 2025 (CEST) ::::::Cosa volete sapere sui TL di lmowiki? :) [[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 16:11, 7 sit 2025 (CEST) == [[User:GiovanniPen]]'s flag == Salutamu!<br> scrivo questo messaggio indirizzandolo principalmente a @[[Utenti:Melos|Melos]] e @[[Utenti:Gmelfi|Gmelfi]] che ho avuto il piacere di affiancare in questo periodo nel quale mi è stato concesso il flag temporaneo di amministratore.<br> Ringrazio anche @[[Utenti:Valerio Bozzolan|Valerio Bozzolan]] e @[[Utenti:Sciking|Sciking]] che mi hanno aiutato sin dall'inizio e @[[Utenti:ValterVB|ValterVB]] che mi ha dato una grossa mano col [[@[[Utenti:ValterVBot|suo bot]] e sopportato pazientemente ogni volta.<br> La mia è una richiesta per tutta la comunità siculofona, della quale fanno parte attivamente soprattutto @[[Utenti:Dapal|Dapal]] @[[Utenti:Zoologo|Zoologo]] @[[Utenti:GianAntonucci|GianAntonucci]] @[[Utenti:Qaqqu|Qaqqu]] (che ringrazio dell'aiuto e per il coinvolgimento della [[Cademia Siciliana]] insieme a @[[Utenti:Narkku|Narkku]] @[[Utenti:Paolorausch|Paolorausch]] @[[Utenti:Smb16|Smb16]]) ma anche saltuariamente (according to [[Special:RecentChanges]] and [[Special:ActiveUsers]]) i non siciliani @[[Utenti:Dostojewskij|Dostojewskij]] @[[Utenti:Mistico Dois|Mistico Dois]] e molto recentemente @[[Utenti:Terminisugnu|Terminisugnu]] e @[[Utenti:Cristiano Barone|Cristiano Barone]].<br> I rinnovi che mi potevano venire concessi automaticamente temporaneamente e senza una richiesta (o accettazione/proposta da parte della comunità) li ho "usati" tutti da settembre ad oggi (in realtà fino a fine mese), motivo per il quale apro oggi questa discussione (''discurruta'' ppi usari u sicilianu) sperando in un vostro riscontro positivo (a seguito della mia attività di questi mesi).<br> Se così fosse, idealmente il periodo di sysop temporaneo potrebbe venire esteso (intanto) a tutto il 2025; anno nel quale sarò anche coordinatore regionale di Wikimedia Italia per la Sicilia e che vedrà proprio Catania sede dell'evento internazionale [[:meta:ItWikiCon|itWikiCon]].<br> Sono ovviamente bene accetti ogni genere di pareri, suggerimenti, critiche, consigli e chi più ne ha più ne metta. -[[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 21:28, 5 jin 2025 (CET) *{{+1}} Giuvanni fu n'ajutu prizziusu assai! --[[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 21:34, 5 jin 2025 (CET) *{{+1}} Granni, Giuvanni. N'autru annu di crìscita! --[[Utenti:Narkku|Narkku]] ([[User talk:Narkku|msg]]) 21:41, 5 jin 2025 (CET) *{{+1}} A mprissioni ca c'haiu avutu è di nu picciottu ca ascuta i cunsigghi, chiddu chi c'hava diri a Giuvanni ci lu dissi già a sulu. I cosi vanu discussi e canciati senza prescia. Pi mia nun ci viru nienti di mali a fallu cuntinuari comu amministraturi tempuraniu pi n'autru annu. --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 23:48, 5 jin 2025 (CET) * {{+1}} Travagghiu assai apprizzatu e equilibbratu. --[[User:Gmelfi|Peppi]] 11:09, 6 jin 2025 (CET) * {{+1}} --[[Utenti:GianAntonucci|GianAntonucci]] ([[User talk:GianAntonucci|msg]]) 11:16, 6 jin 2025 (CET) * {{+1}} Troppu forti Giuvanni, oggiallannu travagghiau bonu bonu e sugnu sicuru ca macari avannu è a stissa cosa! --[[Utenti:Pow3redTheBest|Pow3redTheBest]] ([[User talk:Pow3redTheBest|msg]]) 12:02, 6 jin 2025 (CET) * {{+1}} Bravu e pacinziusu --[[Utenti:Zoologo|Zoologo]] ([[User talk:Zoologo|msg]]) 16:20, 6 jin 2025 (CET) * {{+1}} Nuautri avemu di bisognu di pirsuni forti e sperti, sinza livàri nenti ê nostri amministraturi, 'u to' travagghìu pi nuautri fu 'a megghiu cosa sti misi (armenu sicunnu mìa). Continuannu accussìni finarmenti Wikipedia SCN sarrà cchiù prutetta e furnita. [[Utenti:Cristiano Barone|Cristiano Barone]] ([[User talk:Cristiano Barone|msg]]) 14:15, 7 jin 2025 (CET) ::Grazie a tutti per i preziosi e graditi commenti :) ::buon wiki lavoro a tutti e spero tanto di incontrarvi presto durante i prossimi eventi/raduni. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 09:49, 22 jin 2025 (CET) :::{{fattu}} Auguru a Giuvanni nu bonu travagghiu --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 04:48, 24 jin 2025 (CET) ::::Si avvicina la scadenza :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 21:51, 3 dic 2025 (CET) :::ciaooo, sembrava ieri ma è già volato un altro anno. se vi fa piacere io chiederei il diritto normalmente e non più temporaneo :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 13:59, 16 jin 2026 (CET) ::::{{+1}} [[Utenti:GianAntonucci|GianAntonucci]] ([[User talk:GianAntonucci|msg]]) 14:49, 16 jin 2026 (CET) ::::{{+1}} [[Utenti:Qaqqu|Qaqqu]] ([[User talk:Qaqqu|msg]]) 14:55, 16 jin 2026 (CET) ::::{{+1}} [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 15:00, 16 jin 2026 (CET) ::::{{+1}} [[Spiciali:Contributi/&#126;2026-34413-8|&#126;2026-34413-8]] ([[Discussioni utenti:&#126;2026-34413-8|discussione]]) 15:14, 16 jin 2026 (CET) :::::grazie ma non penso che dagli ip valga :/ [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:56, 16 jin 2026 (CET) ::::{{+1}} sempri avanzi, bon travagghiu Giuvà [[Utenti:Narkku|Narkku]] ([[User talk:Narkku|msg]]) 15:31, 16 jin 2026 (CET) ::::{{+1}} [[Utenti:Paolorausch|Paolorausch]] ([[User talk:Paolorausch|msg]]) 15:11, 16 jin 2026 (CET) ::::{{+1}} Avemu bisognu di pirsuni comu a tia [[User:Gmelfi|Peppi]] 23:00, 16 jin 2026 (CET) == Enabling Dark mode for logged-out users in this Wikipedia == <div lang="en" dir="ltr"> {{int:Hello}} Wikipedians, Apologies, as this message is not written in your native language. {{Int:please-translate}}. The [[mediawikiwiki:Reading/Web|Wikimedia Foundation Web team]] will be enabling [[mediawikiwiki:Special:MyLanguage/Reading/Web/Accessibility_for_reading|dark mode]] here on your Wikipedia by February 2025 now that pages on your wiki have passed our checks for accessibility and other quality checks. Congratulations! The plan to enable is made possible by the diligent work of editors and other technical contributors in your community who ensured that templates, gadgets, and other parts of pages can be accessible in dark mode. Thank you all for making dark mode available for everybody! For context, the Web team has concluded work on dark mode. If, on some wikis, the option is not yet available for logged-out users, this is likely because many pages do not yet display well in dark mode. As communities make progress on this work, we enable this feature on additional wikis once per month. If you notice any issues after enabling dark mode, please create a page: <code>Reading/Web/Accessibility for reading/Reporting/xx.wikipedia.org</code> in MediaWiki ([[mediawikiwiki:Reading/Web/Accessibility_for_reading/Reporting|like these pages]]), and report the issue in the created page. Thank you! On behalf of the [[mediawikiwiki:Reading/Web|Wikimedia Foundation Web team]]. </div> <bdi lang="en" dir="ltr">[[User:UOzurumba (WMF)|UOzurumba (WMF)]]</bdi> 23:15, 21 jin 2025 (CET) <!-- Messaggio inviato da User:UOzurumba (WMF)@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=User:UOzurumba_(WMF)/sandbox_Dark_mode_deployment_list_(February_2025)&oldid=28153450 --> :Thank you @[[Utenti:UOzurumba (WMF)|UOzurumba (WMF)]] :I request that Dark Mode be made available for non-logged users as well. :I've been using Dark Mode on this wiki by default for quite some time now and I haven't noticed any anomalies (anymore) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 09:47, 22 jin 2025 (CET) ::Thank you @[[Utenti:GiovanniPen|GiovanniPen]], for your feedback. [[Utenti:UOzurumba (WMF)|UOzurumba (WMF)]] ([[User talk:UOzurumba (WMF)|msg]]) 15:29, 22 jin 2025 (CET) == Traduzzioni dî noma dî cristiani: quali regula aduttari ? == Cari culleghi wikipidiani. Vitti ca ricintimenti quarchi biografia ha statu spustata pi prisirvari lu nomu (spissu in italianu) dû pirsunaggiu (pi esempiu [[Giorgio Chiellini]]). Nun sugnu contra lu principiu di lassari li noma in italianu, armenu pî pirsunaggi ca nun hannu liami particulari câ Sicilia. Capisciu li mutivazzioni ca foru misi pi giustificari lu spostamentu. Però, nun è dittu ca s'havi a applicari pi tutti li biografii. Pi esempiu se taliati la catiguria [[:Catigurìa:Biografìi|biografii]] tanti biografìi (forsi na cintinara) hannu lu nomu n sicilianu, speci pi pirsunaggi liati a Sicilia, ma nun sulu. Na scigghiuta raggiunevuli fussi ca pi li pirsuni ca chiaramenti la forma siciliana dû nomu è usata di manera usuali ntâ lingua parrata, la vuci s'havi a scriviri n Sicilianu (pi esempiu [[Francu Battiatu]], [[Cartesiu]], [[Sòcrati|Socrati]], [[Carlu III dû Regnu Unitu|Carlu III]], ecc.). Sta regula è in usu nti autri wikipedi, e nun ci trovu nenti di mali. Sparti di chistu secunnu mia fussi na bona cosa lassari nu rimannu quannu la vuci è n italianu e unu arricerca la pirsuna cû nomu n sicilianu. Pi esempiu ntâ wikipedia italiana, se unu cerca Giuseppe Stalin, o Abramo Lincoln, lu rimannu effettivamenti grapi la paggina cô nomu origginali forasteru. [[User:Gmelfi|Peppi]] 18:18, 16 fri 2025 (CET) :Si sunnu pirsunaggi storici o siciliani ci sta averli tradutti. Annunca i lassamu urigginali. IMHO [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 00:35, 17 fri 2025 (CET) ::U nomu 'n sicilianu sulu si è sturicamenti attistatu. Masinnò a Trump l'avìssimu a chiamari "Dunardu Trump", e ô so amicu "Iluni Musk". ::Si vulemu sicilianizzari i noma (ma pi mia no), ànn'a èssiri redirect â vuci cû nomu urigginali, comu affaccia a l'anàgrafi. Iu lassassi sempri i noma urigginali pirò, e lassassi jiri soccu fici u talianu picchì, nni l'èbbica fascista, tutti cosi foru italianizzati. ::Oji â scola nun si studìa Abramo Lincoln, ma Abraham Lincoln, e macari u re è Charles III, no Carlo III. Sparti, 'n italianu si dici Mariah Carey, e no Maria. Scempri cci nn'è quantu nni vuliti. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 00:58, 17 fri 2025 (CET) == Sub-referencing: User testing == <div lang="en" dir="ltr"> [[File:Sub-referencing reuse visual.png|400px|right]] <small>''Apologies for writing in English, please help us by providing a translation below''</small> Hi I’m Johannes from [[:m:Wikimedia Deutschland|Wikimedia Deutschland]]'s [[:m:WMDE Technical Wishes|Technical Wishes team]]. We are making great strides with the new [[:m:WMDE Technical Wishes/Sub-referencing|sub-referencing feature]] and we’d love to invite you to take part in two activities to help us move this work further: #'''Try it out and share your feedback''' #:[[:m:WMDE Technical Wishes/Sub-referencing# Test the prototype|Please try]] the updated ''wikitext'' feature [https://en.wikipedia.beta.wmflabs.org/wiki/Sub-referencing on the beta wiki] and let us know what you think, either [[:m:Talk:WMDE Technical Wishes/Sub-referencing|on our talk page]] or by [https://greatquestion.co/wikimediadeutschland/talktotechwish booking a call] with our UX researcher. #'''Get a sneak peak and help shape the ''Visual Editor'' user designs''' #:Help us test the new design prototypes by participating in user sessions – [https://greatquestion.co/wikimediadeutschland/gxk0taud/apply sign up here to receive an invite]. We're especially hoping to speak with people from underrepresented and diverse groups. If that's you, please consider signing up! No prior or extensive editing experience is required. User sessions will start ''May 14th''. We plan to bring this feature to Wikimedia wikis later this year. We’ll reach out to wikis for piloting in time for deployments. Creators and maintainers of reference-related tools and templates will be contacted beforehand as well. Thank you very much for your support and encouragement so far in helping bring this feature to life! </div> <bdi lang="en" dir="ltr">[[User:Johannes Richter (WMDE)|Johannes Richter (WMDE)]] ([[User talk:Johannes Richter (WMDE)|talk]])</bdi> 17:03, 28 apr 2025 (CEST) <!-- Messaggio inviato da User:Johannes Richter (WMDE)@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=User:Johannes_Richter_(WMDE)/Sub-referencing/massmessage_list&oldid=28628657 --> == migliorie == se non ci sono contrari, richiederei agli amministratori di interfaccia (quindi @[[Utenti:Melos|Melos]]) di:<br> modificare le impostazioni del software in modo che compaia l'iconcina dei progetti (nella barra laterale, strumenti, "in altri progetti") di fianco al nome, analogamente a quanto succede in wikipedia in francese;<br> inserire per tutti (così da averli attivabili) i gadget markAdmins (per il quale serve fare qualcosina col bot @[[Utenti:Valerio Bozzolan|Valerio Bozzolan]]), catalot (oltre il già attivabile hotcat), wikidatainfo, liveclock (purge) e qualunque altro si ritenga necessario.<br> grazie! [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 01:05, 19 maj 2025 (CEST) :{{+1}} [[Utenti:Cristiano Barone|Cristiano Barone]] ([[User talk:Cristiano Barone|msg]]) 11:09, 26 maj 2025 (CEST) :re-ping {{ping|melos}}. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 13:26, 7 gnt 2025 (CEST) ::sperando che prima o poi passi la patch [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 11:12, 7 sit 2025 (CEST) :::ricordiamoci che siamo una wiki "media" e non "small" (https://gerrit.wikimedia.org/g/operations/mediawiki-config/+/a2d2aaab9ace84280dd2f4c70a33bb69cd73850f/dblists/medium.dblist) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 20:31, 24 dic 2025 (CET) :quello che andava sistemato da gerrit è stato fatto. le icone di fianco ai progetti nella sidebar sono state aggiunte (come su wikipedia in fr e nl etc). tra gli accessori (al momento) ci sono solo i seguenti: :* Cat-a-lot (Nu strumentu pi aiutari a spustari chhiù file tra li categurii o junciri catigurii a li risultati di la ricerca) :* HotCat (untranslated: Permette di gestire le categorie di una pagina direttamente dalla modalità di visualizzazione.) :penso possa essere molto utile avere anche wikidatainfo e liveclock. poi vedremo che altro :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 19:34, 4 maj 2026 (CEST) == Wikidata Item and Property labels soon displayed in Wiki Watchlist/Recent Changes == ''(Apologies for posting in English, you can help by translating into your language)'' Hello everyone, the [[m:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Resolve_Labels|Wikidata For Wikimedia Projects]] team is excited to announce an upcoming change in how Wikidata edit changelogs are displayed in your [[Special:Watchlist|Watchlists]] and [[Special:RecentChanges|Recent Changes]] lists. If an edit is made on Wikidata that affects a page in another Wikimedia Project, the changelog will contain some information about the nature of the edit. This can include a QID (or Q-number), a PID (or P-number) and a value (which can be text, numbers, dates, or also QID or PID’s). Confused by these terms? See the [[d:Special:MyLanguage/Wikidata:Glossary|Wikidata:Glossary]] for further explanations. The upcoming change is scheduled for '''17.07.2025''', between '''1300 - 1500 UTC'''. The change will display the label (item name) alongside any QID or PIDs, as seen in the image below: [[File:Apr10 edit summary on Wikidata.png|An edit sum entry on Wikidata, labels display alongside their P- and Q-no.'s]] These changes will only be visible if you have Wikidata edits enabled in your User Preferences for Watchlists and Recent Changes, or have the active filter ‘Wikidata edits’ checkbox toggled on, directly on the Watchlist and Recent Changes pages. Your bot and gadget may be affected! There are thousands of bots, gadgets and user-scripts and whilst we have researched potential effects to many of them, we cannot guarantee there won’t be some that are broken or affected by this change. Further information and context about this change, including how your bot may be affected can be found on this [[m:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Resolve_Labels|project task page]]. We welcome your questions and feedback, please write to us on this dedicated [[m:Talk:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Resolve_Labels|Talk page]]. Thank you, - [[m:User:Danny_Benjafield_(WMDE)|Danny Benjafield (WMDE)]] on behalf of the Wikidata For Wikimedia Projects Team. [[Utenti:MediaWiki message delivery|MediaWiki message delivery]] ([[User talk:MediaWiki message delivery|msg]]) 14:45, 14 gnt 2025 (CEST) <!-- Messaggio inviato da User:Danny Benjafield (WMDE)@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=User:Danny_Benjafield_(WMDE)/MassMessage_Test_List&oldid=28981877 --> == neutralizzazione progetti == tanto non c'è comunità... restano tutte come pagine di servizio obsolete... pareri? [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 19:32, 23 agu 2025 (CEST) == AVVISU: Misa fora sirvizziu dû Template "Ortugrafìa dâ Cademia" == Lu template Ortugrafìa dâ Cademia è misu fora sirvizziu ntê prossimi jorna. Li pirsuni ntirissati ponnu fari nu backup di vuci e articuli a cui stu template è assuciatu. Lu template ha svurgiutu n compitu di classificazzioni utili, a un momentu unni na seri di quistioni eranu n discussioni. Ora nun è cchiù nicissariu, e supratuttu viola na seri di reguli di wikipedia: * '''<nowiki>[[WP:PROMO]]</nowiki> –''' ** Wikipedia nun è nu spazio pi pubblicizzari enti privati. Nu logu ricurrenti comu ntô template attuali è cunsideratu promozzioni. * '''<nowiki>[[WP:TEMPLATE]]</nowiki> – Usu dû template''' ** Li template hannu a sèrbiri sulu pi scopi nciclopedici, pi navigazzioni o manutinzioni. Nun si pò ammettiri di usàrili pi mettiri loghi o sponsorizzazioni. * '''<nowiki>[[WP:COI]]</nowiki> – Conflitto di interessi''' ** Siddu l’associazioni ca lu prumòvi cuntribuisci pi mutivi di mmagini o autopromozioni, chistu pò minari l’attendibilitati e la neutralitati dî cuntinuta. [[User:Gmelfi|Peppi]] 22:02, 7 sit 2025 (CEST) :@[[Utenti:Gmelfi|Gmelfi]] anche se tu eliminassi il template (per quanto imho deve sempre esserci parere concorde della comunità) il contenuto delle voci non dovrebbe venire inficiato, per cui non vedo perché “le persone interessate dovrebbero fare backup di voci srticoli a cui il template è associato” :aggiungo che non è cambiato niente (se non in minima parte) da quando il template è stato creato e iniziato a usare, ancora ci sono pagine in condizioni pietose… :infine, continuando così, rischiamo di perdere una buona fetta (se non la totalità) di quella estremamente risicata comunità che c’è ed è innegabile che l’aiuto che ci stanno dando i ragazzi della cademia è enorme! [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 08:40, 8 sit 2025 (CEST) :PS: anche all’opposto è sempre COI: sia che a favore di qualcosa sia se estremamente o palesemente contrari. Deve valere sempre [[:it:WP:NPOV]] (e il tuo sockpuppet su enwiki ha già mostrato tanta ostilità “preventiva” nei confronti della cademia forse) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 08:43, 8 sit 2025 (CEST) ::Supra lu pareri dâ cumunitati sugnu pirfittamenti d'accordu. Ma nun c'è dubbiu ca lu template è usatu di manera nun cunformi. Comu dittu supra viola diversi politici di usu. E sparti di chistu, lu template fa cridiri (a tortu), ca li vuci cu stu template ponnu essiri mudificati sulu usannu la grammatica e l'ortografia dû documentu (ca pirò nun è cumprensiva e nun è di facili appropriazzioni). L'usu dû logu è puru inappropriatu, pirchì nudda associazzioni, macari senza scopu di lucru, pò mettiri nu "stampu" nti na vuci di wikipedia, e spiru ca vuatri siti d'âccordu. E cumunqui, firmu ristannu ca lu template viola li reguli di wikipedia (e pi chissu s'havi a livari), li vuci restunu comu sunu. Comu dissi già, li reguli dû documentu sunu essenziarmenti cumpatibbili cu la grammatica e lu cumpenniu stilisticu. Apprezzu assi li cuntribbuti di l'utenti ca scrivunu cu reguli ortofrafici ca nun sunu cumpritamenti in adequazzioni cu lu cumpenniu stilisticu e la grammatica. Anzi, lu cumpenniu stilisticu e la grammatica sunu vuci di wikipedia ca si ponnu canciari siddu c'è nu cunsensu nti stu sensu. Pirsunarmenti iu sugnu di l'idea ca avissimu a discurriri di manera trasparenti e pùbbrica (ntô circulu o ntê pàggini di discussioni dê reguli di grammatica) supra eventuali canci o ntegrazzioni ca putissimu aduttari. Iu sugnu pi lu dialugu. [[User:Gmelfi|Peppi]] 15:27, 11 sit 2025 (CEST) :::Nuiautri pigghiammu pi spirazzioni i mudeḍḍi [[:lmo:Modell:SL|Modell:SL]], [[:lmo:Modell:NOL|Modell:NOL]], [[:lij:Template:Grafia_unitäia|Template:Grafia_unitäia]], [[:lij:Template:Grafîa_ofiçiâ|Template:Grafîa_ofiçiâ]] (e autri sìmili ca cci sunnu pi autri lingui). Superchiu avemu u nostru mercu, ma allura abbasta chi u livamu e semu a postu. Na pàggina avissi a èssiri scritta di manera cuirenti; adunca u mudeḍḍu signalija sulu chi si sta usannu n'ortugrafìa spicìfica. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 17:59, 11 sit 2025 (CEST) ::::Grazzi pi li vostri risposti. Pi vèniri ncontru ê dumanni di mantinimentu dû template, e nti nu spiritu custruttivu, comu amministraturi e burocrati, e n certu sensu vardianu neutrali dî reguli di wikipedia, putiemu accittari la pruposta di rittificari lu template pi mittillu n cunfurmità, e n particulari livannu lu logu, accussì lu template si pò cunsidirari cunformi ê reguli (n quantu template di sirvizziu e manutinzioni). Mi pari comunqui un piccatu ca lu [[Wikipedia:Cumpenniu Stilìsticu|Cumpenniu stilisticu]], l'[[Ortografìa siciliana|Ortografia]], e la [[Wikipedia:Grammàtica|grammatica]] ca fu stabbiluta (e chi si pò puru canciari, evòrviri, discutiri) nun attrovanu l'unanimitati di l'utenzi. [[User:Gmelfi|Peppi]] 14:10, 18 sit 2025 (CEST) :::::che comunque non penso che si sia mai detto che non ci sia unanimità tra noi utenti attivi e conoscitori della lingua nei modi di scrittura ortografia grammatica etc. il problema è che nel tempo molte cose sono state fatte "male" o da chi non conosceva o non ha seguito le regole (stilistiche e non) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 19:30, 4 maj 2026 (CEST) == Missaggiu d'erruri nti circa ducentu pàggini == Signalu lu missaggiu d'erruri ca cumpari n particulari n capu ê pàggini dê stati: lu messaggiu è [[Cuurdinati giugràfichi|"Cuurdinati]]<nowiki>: missing longitude (dec format) in {{</nowiki>[[Template:Coord|Coord]]<nowiki>}} ". Stu missaggi cumpari praticamenti nti tutti li pàggini. Mi pari ca veni di l'infobox stati, ma nun mi firai a risorviri lu probblema. Quarcunu sapi comu risorviri lu probblema ? </nowiki>[[User:Gmelfi|Peppi]] 12:00, 22 sit 2025 (CEST) :È un problema di implementazione delle coordinate. Sapevo che esistesse ma speravo fosse risolto. A volte è perché mancano le coordinate nel template infobox stato (che andrebbe comunque rifatto o risistemato) mentre altre volte è perché le coordinate proprio non ci sono (nei parametri del template) e siccome l’implementazione non è corretta spunta l’errore. :L’ideale sarebbe averle automaticamente da wikidata, i’ll work on it appena posso. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:07, 22 sit 2025 (CEST) ::Lu probblema fu risurvutu. Filicitazzioni pi lu travagghiu di qualitati eccillenti. [[User:Gmelfi|Peppi]] 14:22, 1 utt 2025 (CEST) == Wikipedia 25: cercasi volontari per registrare un benvenuto sonoro == <div lang="en" dir="ltr"> <div lang="it" dir="ltr"> [[File:Work-in-progress sketch of the Confetti mascot easter egg.jpg|frameless|250px|right]] {{int:please-translate}} {{int:Hello}}, scusate se scrivo in italiano! Per il [[:m:Wikipedia 25|25° compleanno di Wikipedia]] e per creare delle [[:m:Wikipedia 25/Easter egg experiments|sorpresine per i lettori]] come proposto dalla Wikimedia Foundation, sto invitando i volontari delle varie Wikipedie dell'area italiana a registrare la frase "Ti diamo il benvenuto su Wikipedia" nella loro lingua regionale. Il messaggio audio comparirà "a sorpresa" sulla Wikipedia in italiano e sulle altre wikipedie aderenti al progetto degli [[:m:Wikipedia 25/Easter egg experiments|Ester eggs experiments]]. Farà parte di una raccolta di suoni che include tutte le registrazioni di "Ti diamo il benvenuto su Wikipedia" nelle varie lingue registrate, più alcuni altri suoni provenienti da Commons. Quando un utente cliccerà sulla mascotte del Globetto (Baby Globe) che suona con un sintetizzatore, verrà riprodotto un suono casuale da questa raccolta. Quindi, la frase nella tua lingua non verrà riprodotta ogni volta, ma solo alcune volte e in modo casuale. '''Briefing su come registrare il benvenuto sonoro su Wikipedia''' ([[:m:Talk:Wikipedia_25/Easter_egg_experiments#c-CDekock-WMF-20251209155700-Song_Ng%C6%B0-20251201160400|da qui]]): #la registrazione audio deve essere più corta di 10 secondi, e consistere solo nella frase "Benvenuti su Wikipedia" o "Ti diamo il benvenuto su Wikipedia" nella tua lingua regionale; #il file va caricato su [[:commons:Special:UploadWizard|Wikimedia Commons]] e bisogna chiederne la protezione da parte di un admin di modo da impedire che sia vandalizzato o spostato; #condividi il link del file su Commons [[:m:Talk:Wikipedia_25/Easter_egg_experiments#Are_there_ideas_or_elements_that_you_would_love_to_see_implemented_on_your_language_Wikipedia?|qui]] notificando l'utente CDekock-WMF; #'''deadline''' per fornire i link agli audio su Commons dei "Benvenuti su Wikipedia": '''mercoledi 21 gennaio 2026'''. Registriamo più audio possibile. {{Int:Feedback-thanks-title}} --[[User:Una tantum|Una tantum]] ([[User talk:Una tantum|talk]]) </div> </div> 16:44, 14 jin 2026 (CET) <!-- Messaggio inviato da User:Una tantum@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=User:Una_tantum/sandbox/MM/It_fallback_v2&oldid=29928398 --> == Central Notice Banner on Sicilian wiki on mobile == Hello! Sorry for not writing in your language. <br/> [[m:Wikipedia_25/Easter_egg_experiments#Participating_wikis|Your wiki has decided to activate the Birthday mode]] in celebration of Wikipedia’s 25th birthday. As part of the project, I wanted to let you know that the Wikimedia Foundation is planning to run Central Notice Banners from '''16 Feb - 16 Mar''' on your Wikipedia for ''both logged-in and logged-out users'' on ''mobile only''. <br/>The banner will let people know that [https://wikimediafoundation.org/it/wikipedia-mascot/ Birthday mode] is available on mobile (Minerva) and informs them how to turn them on.<br/> You can view more details of the banner campaign [https://phabricator.wikimedia.org/T410079 on Phabricator]. <br/> Please feel free to reply here with any questions. Thank you!<br/> [[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 14:52, 28 jin 2026 (CET) :thanks @[[Utenti:IKristiani-WMF|IKristiani-WMF]] :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:51, 28 jin 2026 (CET) :better link is https://wikimediafoundation.org/wikipedia25/wikipedia-mascot/ [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:51, 28 jin 2026 (CET) :Thanks @[[Utenti:GiovanniPen|GiovanniPen]]. You're right! Even better link is: https://wikimediafoundation.org/it/wikipedia-mascot/ [[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 04:36, 29 jin 2026 (CET) :dear @[[Utenti:IKristiani-WMF|IKristiani-WMF]], sorry for answering this late. the translations have already been done (as maybe you have seen). :I take this opportunity to point out a problem at the end of the link you sent (WP25 in Italiano), it appears just "Bildnachweis" (wrong language) with no photo credits below. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 22:48, 4 fri 2026 (CET) ::Hello @[[Utenti:GiovanniPen|GiovanniPen]] Thank you so much for volunteering your time to help with the translation. I have noted the error you pointed out and will inform the team to fix this. ::[[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 08:08, 5 fri 2026 (CET) :::Thanks, and of course to @[[Utenti:GianAntonucci|GianAntonucci]] as well that managed the translation :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 11:54, 5 fri 2026 (CET) == Help us translate Birthday Mode for your wiki == Hello! We need your help in translating the Community Configuration for Birthday Mode from English to Sicilian. This is the setting that your community will use to customize the Baby Globe on your wiki.</br> You can help translate directly [https://translatewiki.net/w/i.php?title=Special%3ATranslate&group=ext-wp25eastereggs&language=scn&filter=&optional=1&action=translate here]. You need to create an account on Translate Wiki if you haven’t already.</br> Please feel free to reply here with any questions. Thank you! [[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 11:05, 10 fri 2026 (CET) :@[[Utenti:GianAntonucci|GianAntonucci]] @[[Utenti:Dapal|Dapal]] @[[Utenti:Qaqqu|Qaqqu]] [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 11:15, 11 fri 2026 (CET) ::Appò, u fici. [[Utenti:GianAntonucci|GianAntonucci]] ([[User talk:GianAntonucci|msg]]) 00:02, 12 fri 2026 (CET) :::Thanks @[[Utenti:GianAntonucci|GianAntonucci]]. :::@[[Utenti:IKristiani-WMF|IKristiani-WMF]] all done :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:04, 13 fri 2026 (CET) == Alcuni aggiornamenti importanti sulla Modalità compleanno == Ciao! '''Ora puoi attivare la modalità Compleanno!''' Con la presente desideriamo informarti di alcune importanti modifiche alla modalità Compleanno che la tua wiki ha deciso di adottare. Queste modifiche sono state apportate dopo aver testato la modalità Compleanno attraverso il cluster beta e Test Wikipedia e dopo essersi assicurati che fosse accessibile alle persone con problemi di sensibilità al movimento. Per informazioni dettagliate, consulta [[metawiki:Wikipedia_25/Easter_egg_experiments/Collaboration_process#Go-live_date_and_configuration_update_–_12_Feb|questa pagina]]. Alcune delle modifiche importanti includono: # L'elenco predefinito di voci (QID) in cui apparirà Baby Globe sarà limitato a 2500 per lingua su Wikipedia e non ci sarà alcun Baby Globe “neutro” che apparirà su tutte le pagine non configurate. Ciò significa che, quando troverete Baby Globe, vi sembrerà più un easter egg. È possibile visualizzare [[metawiki:Wikipedia_25/Easter_egg_experiments/article_configuration#Configuration_defaults|l'elenco delle voci predefinite]] che ogni lingua di Wikipedia può ulteriormente personalizzare tramite [[Spiciali:CommunityConfiguration/WP25EasterEggs|la configurazione della comunità]]. # Al fine di mostrare Baby Globe sul web mobile, abiliteremo gli [[phab:T416644|avvisi del sito a livello globale sui dispositivi mobili]]. # La Modalità compleanno sarà ora disponibile fino al 6 aprile. Non esitate a rispondere qui per qualsiasi domanda. Grazie! [[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 17:39, 19 fri 2026 (CET) :Grazie! [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 22:39, 19 fri 2026 (CET) == Prossimi incontri: OSM a Messina, Wikipedia a Catania == [[File:Wikipedia 25 event in Palermo, Sicily 03.jpg|thumb|Partecipanti durante l'incontro di Wikipedia 25 a Palermo a gennaio]] Buongiorno a tutti, Appena completato il [[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Eventi_per_il_compleanno_di_Wikipedia|nostro tour di Sicilia con eventi per celebrare il compleanno di Wikipedia]], andiamo avanti con i nostri prossimi incontri per conoscerci di persona e migliorare insieme i nostri progetti collaborativi preferiti. Puoi raggiungerci prossimamente a queste occasioni: * '''[[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Mapping_Day_e_formazione_a_Messina,_28_Febbraio|Mapping Day a Messina, questo sabato 28 febbraio]]''': giornata di scoperta e di contribuzione alla mappa libera OpenStreetMaps attraverso vari strumenti che si usano dal telefono. * '''[[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Modifichiamo_Wikipedia_insieme!_Catania,_13_marzo|Incontro di contribuzione a Wikipedia a Catania il 13 marzo]]''': un raduno per modificare Wikipedia insieme. Se vuoi partecipare, non dimenticare di iscriverti nell'elenco di partecipanti per ogni evento, e di raggiungere il nostro gruppo Telegram per ricevere aggiornamenti. E come sempre, se hai un'idea o vuoi organizzare un incontro nella tua zona, non esitare a contattare me o [[it:utente:GiovanniPen|GiovanniPen]], ti supportiamo con gran piacere. A presto, [[it:utente:Auregann|Auregann]], 08:21, 25 fri 2026 (CET) <small>Ricevi questo messaggio perché sei iscritto/a nella [[m:lGlobal message delivery/Targets/Wikimediani in Sicilia|lista di diffusione dei Wikimediani in Sicilia]].</small> <!-- Messaggio inviato da User:Auregann@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Wikimediani_in_Sicilia&oldid=30124662 --> == Prossimi incontri di presenza in Sicilia (marzo-aprile 2026) == Ciao! Ecco i prossimi eventi che organizziamo per i volontari di Wikipedia in Sicilia. Se hai voglia di conoscere altri utenti di persona o di diventare più coinvolto/a nei nostri progetti, non esitare a partecipare! * [[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Wikimeet_palermitano_-_Palermo,_27_marzo|Wikimeet a '''Palermo, 27 marzo''']] * [[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Astrofotografia_e_licenze_libere,_Gruppo_Astrofili_Catanesi,_16_aprile|Incontro sull'astrofotografia e licenze libere a '''Catania, 16 aprile''']] * [[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Modifichiamo_Wiki_e_OSM_insieme!_-_Catania,_23_aprile|Modifichiamo Wiki e OSM insieme! a '''Catania, 23 aprile''']] Per qualsiasi domanda su questi eventi, o se hai un idea per un prossimo evento, non esitare a contattare il nostro coordinatore regionale [[it:utente:GiovanniPen|GiovanniPen]]. A presto, [[it:utente:Auregann|Auregann]], 12:17, 24 mar 2026 (CET) <small>Ricevi questo messaggio perché sei iscritto/a nella [[m:lGlobal message delivery/Targets/Wikimediani in Sicilia|lista di diffusione dei Wikimediani in Sicilia]].</small> <!-- Messaggio inviato da User:Auregann@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Wikimediani_in_Sicilia&oldid=30244242 --> == Prossimi incontri wiki e OSM in provincia di Catania (aprile e maggio 2026) == Ciao! Il gruppo dei Wikimediani in Sicilia ha organizzato nuovi incontri per conoscere altri utenti di Wikipedia e OSM di persona e lavorare insieme sui nostri progetti preferiti. Ecco i prossimi raduni in zona di Catania ad aprile e maggio, tutte le informazioni e iscrizioni si trovano [[it:Wikipedia:Raduni/Raduni in Sicilia 2026|sulla pagina dei raduni in Sicilia]]. * '''Modifichiamo Wiki e OSM insieme!''' il 23 aprile sera da Localhost (Catania), per conoscere nuove persone e lavorare insieme * '''Editathon "Voci di carta, voci digitali"''' il 7 maggio pomeriggio al DISUM dell'Università di Catania, per migliorare insieme voci sugli autori italiani * '''Mappiamo le Aci''', 16 e 17 maggio ad Acireale, per arricchire i dati cartografici su OpenStreetMap, a piedi o in bici Per qualsiasi domanda su questi eventi, o se hai un idea per un prossimo evento, non esitare a contattare il nostro coordinatore regionale [[it:utente:GiovanniPen|GiovanniPen]]. A presto, [[it:utente:Auregann|Auregann]] 10:35, 22 apr 2026 (CEST) <small>Ricevi questo messaggio perché sei iscritto/a nella [[m:lGlobal message delivery/Targets/Wikimediani in Sicilia|lista di diffusione dei Wikimediani in Sicilia]].</small> <!-- Messaggio inviato da User:Auregann@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Wikimediani_in_Sicilia&oldid=30244242 --> == Hiruwiki == Hello everyone, I’d like to ask if there is any interest within the Sicilian Wikipedia in using Hiruwiki. Hiruwiki is a collection of interactive, multilingual geometric and mathematical widgets designed for Wikimedia projects. It was originally developed by the Basque Wikimedia Chapter and later updated for broader international use. The goal is to allow editors to embed dynamic proofs, visualisations, and interactive elements directly into wiki pages, making learning content more engaging and easier to understand. Do you think this could be useful for courses or educational materials on this wiki? You can see an example on the Dutch wikipedia [[:nl:Wikipedia:Hiruwiki]] [[Utenti:ItsNyoty|ItsNyoty]] ([[User talk:ItsNyoty|msg]]) 22:13, 2 maj 2026 (CEST) :thanks. {{+1}} by me ofc (as said irl at the [[:mw:Wikimedia Hackathon 2026|hackathon]] 😊). [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 23:42, 2 maj 2026 (CEST) f16wi5rfziizmoium2iwqn73ltdve7b 782030 782029 2026-05-13T10:30:25Z GiovanniPen 22308 /* Infobox disfunziunanti */ Risposta 782030 wikitext text/x-wiki __NEWSECTIONLINK__ [[Catigurìa:Aiutu|Circulu]] [[Catigurìa:Sirvizza|Circulu]] =Lu Cìrculu= <div style="border:3px solid #ccc; background: #fff; text-align: center; padding:3px; float:right; font-size: smaller; line-height: 1.3; margin-right: 5px;"> <div style="width:100%">{{CURRENTDAYNAME}}</div> <div style="font-size: x-large; width: 100%;">{{CURRENTDAY}}</div> <div style="width: 100%;"> {{CURRENTMONTHNAME}}</div> <div style="background: #aaa; color: #000;">'''{{CURRENTTIME}}''' UTC</div> </div> '''[http://scn.wikipedia.org/w/wiki.phtml?title=Wikipedia:Circulu&action=edit&section=new Cliccàti ccà pi scrìviri la vostra dumanna o la vostra assirvazzioni]''' ---- [[File:Circolo-Coversazione.jpg|thumb|450px|[[Circulu di Cunvirsazzioni a Rausa]]]] <gallery mode="packed-hover"> Achilles_Hector_triskele_cropped.jpg|Achilli e lu trisceli P7310046.jpg|Arancini Cassata.jpg|Na cassata dâ zona di Palermu Icon of the Sicily portal.svg </gallery> =Ntroducimentu= Siddu vuliti lassari un missaggiu: jiti â fini dî missaggi, criati un ==Tìtulu==, e lassati chiddu chi vuliti diri. Siddu vuliti jùnciri na discussioni, criati li ===Suttatìtuli=== etc oppuru '''[http://scn.wikipedia.org/w/wiki.phtml?title=Wikipedia:Circulu&action=edit&section=new Cliccàti ccà pi scrìviri la vostra dumanna o la vostra assirvazzioni]''' <br> putiti macari cuntattàrini supra la '''[irc://irc.freenode.net/wikipedia-scn Chat IRC n sicilianu]''' =Archiviu dô Cìrculu= *[[Wikipedia:Circulu/Archiviu]] == Santu == Salutamu a tutti, scrivu chistu pi' cumunicàrivi ca l'utenti Santu passò a 'na vita megghiu. Tanti beddi cosi a tutti. --[[Utenti:Smb16|Smb16]] ([[User talk:Smb16|msg]]) 16:05, 21 maj 2017 (CEST) :RIP. --[[Utenti:Markos90|Markos90]] ([[User talk:Markos90|msg]]) 16:48, 22 maj 2017 (CEST) :RIP. [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 10:14, 19 utt 2017 (CEST) :Si RIP. Vi risparmio il mio schifoso siciliano. Ho lasciato un avviso in stile internazionale. Magari scrivete qualcosa di più adeguato voi che lo conoscevate. Su it Wikipedia si usa la spilletta che usa chi è in lutto, ma non è corretto infatti la usa un vedovo molto conosciuto e ogmi tanto a qualcuno viene uno schianto credendo che ci abbia lasciato anche lui--[[Utenti:Pierpao|Pierpao]] ([[User talk:Pierpao|msg]]) 15:03, 11 nuv 2017 (CET) ::Ah in siciliano ovviamente io non ho osato :(--[[Utenti:Pierpao|Pierpao]] ([[User talk:Pierpao|msg]]) 15:04, 11 nuv 2017 (CET) ::Grazzi pi zoccu facisti. [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 21:15, 11 nuv 2017 (CET) == Cullabburazzioni == Salutamu a tutti, sugnu lu cu-funnaturi di la ''Cadèmia Siciliana'', urganizzazzioni senza prufittu funnata nnô 2016. Mi piacissi parrari cull'amministratura pirchì fùssimu 'ntirissati a dumannàrivi si si po' cullabburari cu vuatri. Avemu nnâ testa un pruggettu di prupunìrivi. Facìtimi sapiri quarchi cosa. --[[Utenti:Smb16|Smb16]] ([[User talk:Smb16|msg]]) 03:17, 31 ggt 2017 (CEST) *Salutamu, Turi! Chi bella idea di travagghiari anzèmmula! Aspittamu chi nni dìcinu l'autri. Ni sintemu! --[[Utenti:Vicè|Vicè]] ([[User talk:Vicè|msg]]) 23:57, 1 aus 2017 (CEST) :qui [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:39, 19 giugn 2024 (CEST) == Saluti! == Salutamu amici di wiki. Quarchi simana fa, pâ prima vota nzinu d’ottu anni fa, avìa vogghia di lèggiri tanticchia di sicilianu. Circannu, circannu, arristai dilusu picchì viramenti zoccu nn’attruvai nun era assai. Pi furtuna scuprìi stu situ [http://forum.cademiasiciliana.org Cademia Siciliana], chi hannu puru na pàggina di facebook attiva. Poi, cchiossai furtuna, quasi la prima jurnata mi scuntru cu dui utenti chi canuscìi tanti anni fa (ccà e cchiù avanti ntô linguasiciliana forum). E ora m’addunu ca chissi dâ Cademia hannu già fattu cuntattu cu scn.wiki, e macari vitti la mala nova di unu di nostri utenti vecchi. Accuminzai a lèggiri diversi pàggini, attruvai quarchi missaggiu di l’annu 2015, e vitti ca Peppi Melfi e Sarvaturi ancura travagghiàvunu ntâ Wikipedia. Chi surprisa! Ni stamu parranu d’armenu unnici anni di dèdica. Tanti auguri a vuiatri! Poi liggìi di n’utenti chi si chiamava ‘’Pippinu’’, chi ruvinau tanti pàggini, e pinzai ca statavi parrannu di mia! Pi diri la viritati, ju nun pozzu ricurdari assai di chi succidìu tant’anni fa, allura putissi cridiri pi veru ca facìa quarcchicosa sbagghiata a ddu tempu! (pi furtuna, nun si trattava di mia) Allura, vi dicu ca m’attrovu n’àutra vota ‘n circulazzioni ma nun sacciu siddu haiu àlica di fari stu tipu di travagghiu. Provu a dàricci n’ucchiata quarchi tempu, e facirmenti adaciu adaciu mi ritorna la capacità. Mi haiu scurdatu quasi tuttu di comu funziona Wikipedia, e oramai mi sentu vicchiareddu - è cchiutostu nu prucettu pi chiddi giuvani. Stati beni…. Pippu D'Angelo 12:37, 5 utt 2017 (CEST : test - [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 04:18, 17 utt 2017 (CEST) :qui [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:39, 19 giugn 2024 (CEST) == Rifari amministraturi Pippu D'Angelo == Comu supra, fatimi sapiri --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 10:44, 17 utt 2017 (CEST) * {{+1}} --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 10:44, 17 utt 2017 (CEST) * {{+1}} [[User:Gmelfi|Peppi]] 22:35, 17 utt 2017 (CEST) * {{+1}} Binidica a tutti vandri cumpà! Grazzi p'aviri cuntinuatu a purtari nn'avanti stu bellu pruggettu. Macari siḍḍu nun sugnu chiù attivu ancapu a scn.wiki, sugnu assai faurevuli a lu ritornu di Pippu comu amministraturi. Salutamu! --[[Utenti:Vicè|Vicè]] ([[User talk:Vicè|msg]]) 02:46, 22 utt 2017 (CEST) ::Grazzi a tutti! Armenu ora pozzu canciari la me pàggina d'utenti! [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 22:21, 23 utt 2017 (CEST) ::Pozzu accuminzari n'autra vota misculiannu l'àrticuli ntâ vitrina? Mporta si ripetu chiddi chi cci nni foru già o haiu a circari chiddi novi pi mintìricci? [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 05:01, 24 utt 2017 (CEST) :::Sì, tranquilllu. Puoi canciari tuttu chiddu ca vuoi, prorpiu comu na vota. [[User:Gmelfi|Peppi]] 09:12, 24 utt 2017 (CEST) :::Ok! :) [[Utenti:Pippu d'Angelo|Pippu d]] - [[User talk:Pippu d'Angelo|(dica)]] 09:17, 24 utt 2017 (CEST) == comu usari lu passatu nsicilianu == Salutamu! Sugnu siculumirianu e staiu nzignannu sicilianu. Mi putiti spiegari comu usari li termini "au" e "ava"? P'asempiu, me nannu passava lu mari tri voti o ma nannu passau lu mari tri voti. Comu si sapi quannu usari l'unu o l'autru? Binidica a tutti :Ciau anònimu, fussi megghiu si ti riggistrassi (mi pari ca lu to sicilianu e' abbastanti bonu, e criju ca capisci già comu sti cunjugazzioni funziònanu). 'N ogni casu, «passava» fa parti dû mpirfettu. Si usa pi parrari di quarcchicosa c'avissi succidutu duranti nu pirìudu nnô passatu, p'asempiu, putissi diri ca to nannu passava lu mari quannu era carusu o cchiù giovanni, spiciarmenti si cci capitau n'àutru abbinimentu cchiù spicìficu (mentri ca passava lu mari chissu cci capitau...), o si parrassi di zoccu to nannu vulìa fari a ddu tempu: iddu avissi avutu spiranza di truvari travagghiu, e passava lu mari armenu tri voti circannu travagghiu. Ma si usa l'àutra furma (lu pritiritu) siddu vulissi discrìviri n'abbinimentu nnô passatu: to nannu passau lu mari tri voti, e sulu tri voti, e facirmenti nun cci passa cchiù. Ma siddu cci resta la pussibbilitati di travirsari lu mari n'àutra vota, putissi diri ca to nannu: avi già passatu lu mari tri voti (e facirmenti lu fa n'àutra vota...) Bonu, eni nu gran aiutu pi mia. Grazzi fratuzzu! == Registrazioni di utenze in automatico == Salve, mi chiedo se anche a voi è successo un qualcosa di particolare ieri. Una cosa che non riesco a capire è che si registrano utenze globali in automatico, a me è successo che mi ci si sono collegate ad altri progetti wikipedia che non le ho collegate io stesso, ma non so chi o cosa fa tutto questo??? qualcuno ne sa qualcosa? ho scritto [https://meta.wikimedia.org/wiki/Wikimedia_Forum#Automatical_global_user_registrations su meta]. --[[Utenti:S4b1nuz E.656|S4b1nuz E.656]] ([[User talk:S4b1nuz E.656|msg]]) 10:03, 11 fri 2018 (CET) == IMPORTANTE: rassegna dell'attività di amministrazione == Ciao. Una politica che riguarda la rimozione dei "diritti avanzati" (amministratore, burocrate, ecc) è stata adottata come parte [[m:Requests for comment/Activity levels of advanced administrative rights holders/Summary/it|sommaria della comunità]] nell'anno 2013: in accordo a questa politica, gli [[m:Stewards/it|Stewards]] stanno rivedendo le attività degli amministratori su tutte le wiki della Fondazione di Wikimedia con nessun criterio politico che potrebbe riguardare l'inattività delle utenze. Di tale principio, ne risulta che al meglio delle nostre conoscenze, le utenze sulle wiki non avrebbero un processo formale per la rimozione di questi "diritti avanzati" che per l'appunto riguarderebbe tutti gli account inattivi. E in una propria conclusione ciò andrà a significare che gli steward in accordo alla [[m:Admin activity review/it|rassegna dell'attività amministrativa]] si prenderanno cura di questo processo. Abbiamo stabilito che i seguenti utenti soddisfano i criteri di inattività (senza modifiche e senza azioni di registro per più di 2 anni): # Sarvaturi~scnwiki (burocrate, amministratore) Questi utenti ben presto riceveranno una notifica: ad essi si chiederà di avviare alla comunità una discussione se vogliono mantenere alcuni o tutti i loro diritti. Quindi, se gli utenti non rispondono alla discussione richiesta, i loro diritti che precedentemente hanno mantenuto sino a quel momento saranno rimossi dagli amministratori. Tuttavia, se dalla comunità si vorrebbe creare il proprio processo di rassegna di attività che sostituisce quello globale, si potrebbe prendere un'altra decisione di quei diritti dei detentori che sono inattivi dove codesti utenti hanno già una politica, ma la stessa fu superata e non è più valida. Pe cui, si è pregati di avvisare gli Stewards ([[:m:Stewards' noticeboard|stewards on Meta-Wiki]]), laddove gli steward senza determinato avviso non potranno sapere se procedere o astenersi al riesame dei diritti wiki di questi utenti. Grazie. '''[[User:Rschen7754|Rs]][[User talk:Rschen7754|chen]][[Special:Contributions/Rschen7754|7754]]''' 08:01, 10 aus 2018 (CEST) == IMPORTANT: Admin activity review == Hello. A policy regarding the removal of "advanced rights" (administrator, bureaucrat, interface administrator, etc.) was adopted by [[:m:Requests for comment/Activity levels of advanced administrative rights holders|global community consensus]] in 2013. According to this policy, the [[:m:stewards|stewards]] are reviewing administrators' activity on all Wikimedia Foundation wikis with no inactivity policy. To the best of our knowledge, your wiki does not have a formal process for removing "advanced rights" from inactive accounts. This means that the stewards will take care of this according to the [[:m:Admin activity review|admin activity review]]. We have determined that the following users meet the inactivity criteria (no edits and no logged actions for more than 2 years): # Klone123 (administrator) These users will receive a notification soon, asking them to start a community discussion if they want to retain some or all of their rights. If the users do not respond, then their advanced rights will be removed by the stewards. However, if you as a community would like to create your own activity review process superseding the global one, want to make another decision about these inactive rights holders, or already have a policy that we missed, then please notify the [[:m:Stewards' noticeboard|stewards on Meta-Wiki]] so that we know not to proceed with the rights review on your wiki. Thanks, [[Utenti:Stanglavine|Stanglavine]] ([[User talk:Stanglavine|msg]]) 02:24, 19 jin 2022 (CET) == Collaborazione == Buongiorno amici siciliani. Vorrei proporvi, dopo dicembre 2022 (in quel mese faremo una nostra editathon), una collaborazione: ne abbiamo già fatta una con la Wikipedia in galiziano e una con quella in ladino dolomitivo. Si tratterebbe di scegliere un tot di voci relative alla storia, alla cultura, alla lingua e al territorio di Sicilia e Lombardia e scriverle sulle rispettive enciclopedie. Che ne dite? -- [[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 19:48, 24 nuv 2022 (CET) :{{Ping|Sciking}} (commento utente non siciliano) Ciao Sciking, purtroppo devo dire che di utenti attivi siciliani su questa Wiki non ce ne sono al momento... in genere controllo il ''Canciati antura'' vedendo che la maggior parte di modifiche son fatte dagli IP (qualche volta vandaliche), altre invece da utenti/IP stranieri (ad es. aggiungono delle liste riguardo a delle serie televisive, cambiare immagini oppure aggiornare qualche info). :A parere mio, l'idea la trovo carina :-), ma ti consiglierei di proporla su un'altra Wiki con utenti più attivi. :Puoi provare a proporre sulla Wiki ligure (di cui sono un admin), emiliano-romagnola, napoletana, veneta, piemontese, sarda e/o tarantina dove ti posso garantire che son presenti degli utenti attivi madrelingua/quasi madrelingua. Saluti. --[[Utenti:S4b1nuz E.656|<span style="color:#009246;">'''S4b1nuz'''</span> <span style="color:#CE2B37; font-family:futura">'''ᴇ.656'''</span>]]<sup>[[Discussioni utenti:S4b1nuz E.656|<span style="color:#006AA7">''(SMS)''</span>]]</sup> 14:14, 25 nuv 2022 (CET) ::{{ping|S4b1nuz E.656}} uno di questi giorni passo su quella in ligure, allora. --[[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 19:06, 30 nuv 2022 (CET) :::{{ping|Sciking}} Ciao di nuovo, a ripensarci che siamo verso il periodo Natalizio e tra 1 mese di Epifania, credo che alcuni utenti potrebbero fare qualche Wikipausa. Sarebbe meglio che punti sul vostro Editatlon di Wikipedia lombarda... La tua collaborazione temporanea potresti proporla in un altro periodo dell'anno 2023 (sempre su qualche Wiki a tua scelta). Saluti e buon weekend! --[[Utenti:S4b1nuz E.656|<span style="color:#009246;">'''S4b1nuz'''</span> <span style="color:#CE2B37; font-family:futura">'''ᴇ.656'''</span>]]<sup>[[Discussioni utenti:S4b1nuz E.656|<span style="color:#006AA7">''(SMS)''</span>]]</sup> 23:02, 3 dic 2022 (CET) ::::qui [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:32, 19 giugn 2024 (CEST) == Traducemu la Wikipedia in sicilianu == Pi sviluppari la Wikipedia siciliana, putemu traduciri articuli dâ Wikipedia nglisi e di l'italiana. E un tradutturi miccanicu pò fari lu travagghiu chiù facili. La machina pò traduciri na cintinara di articuli, e l'essiri umanu havi sulu a curreggiri li sbagghi. Ora ca [https://translate.napizia.com/ lu tradutturi di Napizia] funziona megghiu, putemu usarlu pi traduciri na cintinara di articuli pi Wikipedia siciliana. Allura haiu l'intinzioni di traduciri miccanicamenti articuli pi Wikipedia siciliana. Ma prima di farlu, scrivu stu missaggiu pi annunziari la mè ntinzioni. Vulissi sentiri lu vostru cunzigghiu. [[Utenti:Eryk Wdowiak|Eryk Wdowiak]] ([[User talk:Eryk Wdowiak|msg]]) 07:26, 22 apr 2023 (CEST) :Mantegnu un [[Utenti:Eryk Wdowiak|elencu dî mè traduzzioni miccanichi]] â mè paggina. [[Utenti:Eryk Wdowiak|Eryk Wdowiak]] ([[User talk:Eryk Wdowiak|msg]]) 00:06, 25 apr 2023 (CEST) :Pi dumannari na traduzzioni, vi preju di lassari un missaggiu ntâ [[Discussioni_utenti:Eryk_Wdowiak|discussioni]]. [[Utenti:Eryk Wdowiak|Eryk Wdowiak]] ([[User talk:Eryk Wdowiak|msg]]) 16:14, 25 apr 2023 (CEST) :: anche [https://traduttoresiciliano.blogspot.com/2016/07/traduttore-italiano-siciliano.html qui] e [http://www.salviamoilsiciliano.com/come-si-dice/dizionario/ glossario] [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:31, 19 giugn 2024 (CEST) == creare alias redirect namespace == Ciao, penso sia utile a tutti avere i namespace abbreviati (alias), analogamente a come avviene su itwiki e altri progetti (per comodità typing e linguistiche).<br> Ad esempio: T=Template C=CAT=Categoria=Category=Catigurìa (poi ci sarebbero anche DP e DW per le talk) Se è fattibile potremmo fare richiesta su phabricator :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 14:38, 28 sit 2024 (CEST) : Yes. Credo sia molto fattibile e sensato. Se ho capito correttamente si tratterebbe di modificare questo file per fare una cosa del genere: : https://phabricator.wikimedia.org/source/mediawiki-config/browse/master/wmf-config/core-Namespaces.php;b0c00bf7406275732056e3672d802f3c7f58ee8b$868-873 : quindi aggiungere qualcosa del genere: <pre> '+scnwiki' => [ 'CAT' => NS_CATEGORY, 'DP' => 103, 'DW' => NS_PROJECT_TALK, 'T' => NS_TEMPLATE, 'U' => NS_USER, ],</pre> Quindi si potrebbe aprire un task del genere: [[phabricator:T101274]] (alle gentili persone che frequentano [[phabricator:tag/wikimedia-site-requests/]]) asd --[[Utenti:Valerio Bozzolan|Valerio Bozzolan]] ([[User talk:Valerio Bozzolan|msg]]) 14:58, 28 sit 2024 (CEST) ::Sono d'accordo. [[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 13:52, 29 sit 2024 (CEST) :::haiu criatu a pàggina su phabricator: a truvati [[phabricator:T375979|cca]] [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 18:42, 29 sit 2024 (CEST) ::::Ho aggiunto DU => NS_USER_TALK. Per la storia di C o CAT CAT va bene lo stesso anzi per certi aspetti è meglio. Ho riprogrammato la richiesta di Developer perché nella sezione odierna erano impegnati --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 23:00, 30 sit 2024 (CEST) :::::grazie ∞ [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 00:54, 1 utt 2024 (CEST) == Politica dialettale == Una cosa che ho imparato su lmowiki è l'importanza di una politica dialettale fatta bene e di come prevenga problemi più avanti, vi suggerirei di adottarne una ben strutturata. Prima di tutto bisogna discutere di grafia: mi pare di capire che qui ci siano delle convenzioni ortografiche che, se hanno una base nella storia del siciliano, possono rimanere, ma bisogna anche capire se vi sono altre ortografie in uso che vanno accettate o usate. Soprattutto, per salentino e calabrese c'è da capire quali sono delle modalità di scrittura accettate e qual è la classificazione dialettale più comunemente accettata per essi. In Lombardia abbiamo un gruppo contiguo, quindi classifichiamo per grafia principalmente, ma nel vostro caso potrebbe aver senso dividere prima in siciliano, salentino e calabrese ed eventualmente poi fare sottoclassificazioni grafiche e dialettali. Una cosa da deprecare sono le voci scritte più volte in più dialetti. [[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 23:28, 1 utt 2024 (CEST) :sono d'accordo sul deprecare le voci scritte in più lingue. approfittando del flag temporaneo di admin che mi è stato concesso possiamo identificarle, risistemarle quando necessario ed eventualmente eliminarle (quando presenti in molteplici versioni). [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 17:34, 5 utt 2024 (CEST) ::Nell'edizione scn.wikipedia un consenso sull'ortografia è stato raggiunto una ventina di anni fa. Il risultato fu il frutto di un confronto costruttivo tra amministratori originari di varie parti della Sicilia, e ha preso in conto anche la problematica di poter essere compatibile con le varianti continentali di Clalbria e Salento. Molte voci sono d'altronde dedicate a spiegare bene l'uso dell'ortografia siciliana da preferire. L'uso episodico di altre ortografie è comunque tollerato nella misura in cui lo spirito del progetto wikipedia non è snaturato. Sono d'accordo che una voce deve essere scritta in una sola versione. [[User:Gmelfi|Peppi]] 10:47, 23 utt 2024 (CEST) :::penso che sfrutteremo anche il più recente documento sull'ortografia della [[Cademia Siciliana]]. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 13:08, 23 utt 2024 (CEST) :::: Ricordo che le basi ortografiche e grammaticali per questa edizione di wikipedia sono state poste diversi anni fa e figurani nelle pagine raggiungibili dal menu a sinistra [[Cumpenniu stilisticu|Wikipedia:Cumpenniu Stilisticu]] e [[Grammatica|Wikipedia:Grammatica]]. Si veda anche [[WP:Mutivi dî nostri scigghiuti ortugràfichi]] per maggior chiarezza. [[User:Gmelfi|Peppi]] 18:35, 27 utt 2024 (CET) == Ntirventi nti scn.wikipedia== Pi favuri, nun fari canci di massa senza aviri fattu na discussioni e aviri avutu nu cunsensu supra la quistioni cu l'autri utenti di wikipedia. Appi a rimettiri annarrèri tutti li pàggini di austu. L'azzioni di fari canci di massa senza consensu è assai dannusa pi lu proggettu. E sparti di chistu nun arricanusci lu trfvagghiu di qualitati fattu nti l'urtimi vint'anni. Pi esseri chiaru, si l'amici dâ Ccademia vonu contribbuiri sunu binvinuti, ma l'ortografìa nun si cancia di maniera massiva supra li pâggini criati nzinu a ora, e senza nu cunsensu adequatu. Esistunu già nu cumpenniu stilisticu e reguli ortografichi assai precisi, e s'hannu a rispittari. Naturalmenti articuli scritti cu na varianti di l'ortografia accittata sunu accittati (s'havi a mettiri nu disclaimer nti stu sensu), ntâ misura n cui nun snaturanu lu progettu ntê sò integritati. [[Utenti:Gmelfi]] ([[User talk:Gmelfi|msg]]) :Caru Giovanni. Ti vulìa scriviri a prupositu dâ qualitati ca avemu a tèniri nti sta wikipedia. Nzinu a ora, ni semu basati supra li documenta sritti n scilianu, e n particulari li vocabbulari n sicilianu ca sunu disponibbili su Google Libri. Avemu a tèniri nu liveddu di qualitati assai àutu pi stu pruggettu. E' funnamintali puru scriviri n sicilianu, puru ntê discussioni ntra nuautri. Ci sunu diversi cosi ca si ptutissiru discurriri supra li ntirventi ca hannu statu fatti ricintimenti. Per esempiu, la parola "mudeddu" in sicilianu nun l'haiu mai vista né scritta né orali. Tu usi sta parola di sta manera ? Hai nu documentu ? Ntâ lingua parrata si dici "modellu", e nun è nu neologgismu italianu! Se vai a taliari lu vocabbulariu di Pasqualino (ca havi cchiossai di 100 anni) (chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://books.googleusercontent.com/books/content?req=AKW5QaffEUJyww3-xhSrpvu5Ae8Q8i_iJwqcs5KqRNhvsT3nMxgGF7pLiudlP_-hgvFgyEgtByftSjMywsqL4EtmMA9tUbI_9PKnQ6NoxjdME6CyQmd9Hdp4egkfT96bqUU0S18QG2MriYEZ-nC6YHjCsEvZEPVQkRu7I0SAOI6fkATgMnB5Ow887ZtLIoaHbjovEkmdGQr2jOteSs7g-fK4bLdGaMTXhaDyu0OMcumkQ9GnADSE_f4_3XEtFpHI9G1Qn6scLEiGceihml1quzQ5B_yNZS_qHkzL_XH-dj_OVGfNQlslkso) c'è scrittu "modellu". perciò la regola ca s'havi sempri a scrivri la doppia ll cu la doppia dd nun è na regula ginirali, contrariamenti a chiddu ca si cridi. E nun s'hannu a nvintari paroli cu n'ortografia inesistenti, senno la qualitati ginirali s'abbassa. N'autra quistioni assai dubbia (secunnnu mia) è l'usu di la doppia dd cu lu puntu di sutta. Capisciu la ntinzioni di rènniri lu suonu particulari di la doppia dd n siclianu, ma secunnu mia è utopicu pinsari ca stu tipu di ortografia veni aduttata di tutti, pirchì è simpricimentu troppu cumpricatu. Na soluzioni raggiunevuli pir mia fussi chista: La doppia dd puntata si pò usari, ma nun si pò obbligari l'usu nti l'usu giniralizzatu ntâ scrittura siciliana. Sta soluzioni è usata n italianu, unni li paroli ntô vocabbulariu cuntenunu accenti gravi o acuti (quannu dannu nnicazzioni supra la prununcia), ma ntâ lingua scritta, currenti l'accenti sunu piazzati sulu pê paroli accintati all'urtima sillaba. [[User:Gmelfi|Peppi]] 11:23, 28 utt 2024 (CET) ::{{ping|gmelfi}} ::sono d'accordo con te e anch'io ritengo sia importante scrivere anche tra di noi nelle discussioni in siciliano (ma non mi sento particolarmente in grado e quindi anche per brevità scrivo in italiano) ::uso anche ad esempio l'interfaccia tradotta di firefox e telegram. ::le uniche cose che mi vengono da dire sono: le lingue evolvono (e tra queste anche il siciliano) difatti ci sono dei termini che non esistevano e che non sentirai mai dire "in giro"; le indicazioni sulla scrittura me le ha fornite {{ping|dapal}} seguendo il lavoro dei linguisti e della ''Cademia Siciliana'', quindi un documento seppur recente c'è. ::ps la tua firma sta volta ha funzionato correttamente. ::pps come detto altre voltre, imho le pagine personali non sono il posto migliore dove fare queste discussioni. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:51, 28 utt 2024 (CET) <div><span style="font-family: verdana, sans-serif; color: white; background: blue; font-weight: bold; border: 1px solid black; font-stretch: ultra-condensed">cb</span> ''La discussione proviene dalla pagina '''[[Discussioni_utenti:GiovanniPen#Ntirventi_nti_scn.wikipedia]]'''''.<small><br /> – Il [[Wikipedia:Cambusa|cambusiere]] --[[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) [fuori crono] 15:31, 28 utt 2024 (CET) </small></div> :Salutamu. :M'hâ pirdunari, ma anestu sintìrimi diri ca "mudeḍḍu" nun esisti, e chi mmeci àvi a siri ''mudellu'', è na fissarìa. [https://imgur.com/a/xTXWPWq Chista è na schirmata dû Vucabbulariu Sicilianu], unni è attistatu ''mudeḍḍu''. Cchiù assai, mudeḍḍu appatta cû ''vucalìsimu sicilianu'', mmeci ''modellu'' (chi speru fussi nu sbagghiu, vistu chi Pasqualinu dici mudellu) no, vidi pi scempru la O àtuna (puru chi cci sunnu eccizzioni a tipu l'accenti sicunnari o si a palora trasìu nnô sistema sicilianu 'n tempi ricenti). :Nuiautri dâ [[Cademia Siciliana]] àvi anni chi circamu palori pi adattalli â vita di oji, cunzidirannu macari chi a lingua è na cosa viva, e circamu d'adattari macari a lingua scritta. Si parri talianu, tu 'un parri comu Danti, adunca 'un capisciu st'attaccamentu â lingua dî pueti. Pueti chi poi, nun avennu nuḍḍa norma ortugràfica, scrivìanu ognidunu comu vulìa. :Sicunnu poi, a ḍḍ è na granni vittoria pâ lingua siciliana. Scrivilla è fàcili [https://cademiasiciliana.org/tools-it/sicilian-language-keyboard-layouts-microsoft-windows/ câ nostra tastera], e fìcimu mèttiri macari a littra nne Android, e si po' scrìviri macari di iOS. Si circamu a qualità, s'àvi a usari ḍḍ unni serbi. Vulennu, unu putissi scrìviri ddh/ddr, e poi fariccillu abbirsari ôn bot. :Pâ custioni lu/u: nuiautri pinzamu ca ''lu'' s'avissi a usari nnê testi furmali (statuti, liggi), o pi riprisintari ḍḍi dialetti unni si dici. Pi Wikipedia, puru tinennu 'n cuntu ca è na nciclupidìa, pinzamu ca è megghiu falla cchiù vicina a comu parra a genti, pi falla cchiù accissìbbili. E tû dici unu chi veni di unu di ḍḍi posti unni si ''dici'' lu ([[Mazzara]], ma macari nnô [[Girgenti|giurgintanu]]. Già a [[Marsala]], pi diri, dìcinu ''u'', e si vidìssiru scrittu ''lu'' parissi fausu e furzatu. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 15:02, 28 utt 2024 (CET) ::@[[Utenti:Gmelfi|Gmelfi]] @[[Utenti:GiovanniPen|GiovanniPen]] spustai cca a discurruta! [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 15:20, 28 utt 2024 (CET) :::<small>grazzi. abbissai comu u template ''Cambusa'' di itwiki.</small> [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 15:35, 28 utt 2024 (CET) :::Grazzî pâ discussioni. Ristamu costruttivi. Tuttu lu rispettu pô travagghiu dâ Ccademia. Arrispettu lu travagghiu pi la promuzzioni dû sicilianu, pi aviri travagghiatu pi interfacci di traduzzioni nti diversi applicazioni nfurmatichi. Ma resta lu fattu ca Wikipedia.scn (ca esisti di cchiossai di 20 anni) nun è n'organu dâ Ccademia, e la Ccademia nun mi pari ca havi na arricanusciuta a liveddu accademicu, macari ca porta lu nomu. Cu sunu li linguisti e li filùluggi ca travagghiunu ntâ Ccademia ? Ntâ pàggina "Cu siemu" nun c'è scrittu! M'agghiu ligghiutu lu documentu pi l'ortografia siciliana dâ Ccademia. E' nu travagghiu apprizzabbili, ma è assai cchiu riddottu di tuttu lu travagghiu ca fu fattu nti scn.wikipedia ntra l'utilizzatura ca accuminzarru lu progettu 20 anni fa. Se talìi li pàggini cu li reguli grammaticali e li formi prifiruti, ci sunu spiegazzioni ca s'abbasunu supra documenti scritti, vocabbulari e quant'autru, e nun sunu simpricimenti na scigghiuta di unu ca si suisu dû liettu. :::E ancora cu tuttu lu rispettu, la schirmata di "mudeddu" ca m'ammusciasti dici "vedi modellu", e veni a diri ca la forma cchiù usata è senza dubbiu modellu. Tô rici quarcunu ca ha usatu sta parola n sicilianu, pi esempiu quannu unu vâ ô comuni pi jinchiri nu modellu pi na autucertificazzioni. Ca la lingua siciliana evolvi nun lu mettu n dubbiu. Ma nun vor diri ca avemu a nvintari paroli ca nun esistunu né ntâ lingua parrata né ntâ lingua scritta o ca avemu a prumòviri paroli (comu mudeddu) ca puru se esistunu hannu n'usu minoritariu rispettu a formi assai cchiù usati (comu modellu). [[User:Gmelfi|Peppi]] 15:56, 28 utt 2024 (CET) ::::Amâ fari tanti cosi. chistu è u fattu. (tipo sistemare l'ortografia dei mesi) ::::appoi, secunnu mia, mmeci di prioccuparisi troppu, usamu direttamente "template" e bonu cchiu (anche picchì u namespace non lo possiamo cambiare, e sarebbe un lavorone). ::::d'autra banna nun putemu, secunnu mia, accittari palori grammaticamenti sbagghiati sulu picchì sunnu cchiù cumuni / cchiù diffusi. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:03, 28 utt 2024 (CET) ::::U Ducumentu pi l'Ortugrafìa dû Sicilianu fu uggettu di discurruta di tesi accadèmica, e ancora oji ci travàgghianu ricircaturi ca sunnu nnô munnu accadèmicu. Ntra tutti, @[[Utenti:Smb16|Smb16]]. Certu ca Wikipedia nun è na succursali di Cademia (cu na C sula pi favuri, è nomu propiu), ma a nostra ortugrafìa è bastanti stàbbili, e veni usata macari di genti chi câ Cademia nun cci tràsinu nenti. E nun sulu: fu pinzata macari pi èssiri leggia e fàcili di usari. ::::Ora, certu nuḍḍu àvi ntinzioni di supranijàriti, ma mancu putemu stari fermi a "u fìcimu vint'anni nn'arrè, àv'a stari accussì pi sempri", e pi chistu ti dissi chi viatu faraju na pruposta pi canciari u Cumpenniu Stilìsticu pi usari a nostra ortugrafìa. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 17:53, 28 utt 2024 (CET) :::::Lu cumpenniu stilisticu, cu la Grammatica e l'ortografia raccumannata pirmisiru di criari nu pruggetu stabbili e nun vidu pirchì s'havissi a canciari. Comunqui si quarchi contribbuturi voli scriviri cu n'autra ortografìa spirimintali, abbasta ca metti lu tag adequatu, e pir mia nun c'è probblema. Cô tempu si vidi se s'havi a canciari quarchi cosa ntê raccumannazioni ca damu ê utilizzatura. [[User:Gmelfi|Peppi]] 15:33, 29 utt 2024 (CET) ==Infobox disfunziunanti== Cari culleghi di scn, nutai ca diversi pàggini cuntênunu infobox ca nun funzionanu bonu. Per esempio la pàggina [[Etna]] nun pigghia li cuurdinati giografichi e l'infobox è strammu. Na cosa simili succedi pî prisidenti dê Stati Uniti e tanti autri catigurii di pàggini. Quarchid'unu di vuatri si fira a sistimari li bug ? Iu nun mi la firu (sugnu troppu viecchiu, forsi, :-) ). Diciemu ca tra na pàggina cu nu infubox disfunziunanti (ca nun è WIP) e na paggina senza infobox, è megghiu na pàggina senza infobox. Pirciò annunciu ca ntê prossimi jorna se nenti veni fattu, li infobox ca nun funzionanu currittamenti sunu distinati a essiri cancillati. [[User:Gmelfi|Peppi]] 22:49, 30 utt 2024 (CET) :salutamu, :staiu pruvannu cu @[[Utenti:Dapal|Dapal]] ad abbirsari diversi template e i Mòduli che non funzionano o che non sono tradotti. :accamora iddu sta rifacendo T:Bio (mi pare) :sono d’accordo che se gli info box non funzionano tanto vale levarli. Io mi sono accorto che ci sono assai template da scancillari direttamenti, tuttu arristau fermo a 10anni arrè. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 10:30, 31 utt 2024 (CET) ::@[[Utenti:Gmelfi|Gmelfi]] cunfermu, staju travagghiannu a chiḍḍu pî biugrafìi, e chiḍḍu usa {{tl|Infobox}}, chi dintra usa {{tl|Navbox}}. Abbisogna n'anticchia di tempu, ma a picca a picca abbirsamu tutti cosi. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 11:20, 31 utt 2024 (CET) :ps l'etna non ha le coordinate inserite e il template ancora non è stato aggiornato per prenderle da wikidata. lo faremo asap [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 04:40, 16 nuv 2024 (CET) ::diversi infobox funzionano, alcuni vanno semplicemente inseriti o sostituiti/aggiornati. altri purtroppo non sono ancora stati corretti e possono apparire "rotti" ::@[[Utenti:Dapal|Dapal]] stava sviluppando t:bio ma non è ancora stato pubblicato (è nelle sue sandbox mi pare) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 19:29, 5 fri 2025 (CET) :@[[Utenti:Gmelfi|Gmelfi]] abbissai i cuurdinati :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:29, 13 maj 2026 (CEST) ::abbissai n'annicchia macari na para di infobox ma ancora c'è assai di fari. @[[Utenti:GianAntonucci|GianAntonucci]] fici nu travagghiu bonu macari. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:30, 13 maj 2026 (CEST) == Proposal to enable the "Contribute" entry point in Sicilian Wikipedia == {{Int:Hello}} Sicilian Wikipedians, Apologies as this message is not in your language. {{Int:please-translate}}. The [[mediawikiwiki:Wikimedia_Language_and_Product_Localization|WMF Language and Product Localization]] team proposes enabling an entry point called "Contribute" to your Wikipedia. The [[:bn:বিশেষ:Contribute|Contribute]] entry point is based on collaborative work with other product teams in the Wikimedia Foundation on [[mediawikiwiki:Edit_Discovery|Edit discovery]], which validated the entry point as a persistent and constant path that contributors took to discover ways to contribute content in Wikipedia. Therefore, enabling this entry point in your Wikipedia will help contributors quickly discover available tools and immediately click to start using them. This entry point is designed to be a central point for discovering contribution tools in Sicilian Wikipedia. '''Who can access it''' Once it is enabled in your Wikipedia, newcomers can access the entry point automatically by just logging into their account, click on the User drop-down menu and choose the "Contribute" icon, which takes you to another menu where you will find a self-guided description of what you can do to contribute content, as shown in the image below. An option to "view contributions" is also available to access the list of your contributions. [[File:Mobile_Contribute_Page.png|Mobile Contribute Page]] [[File:Mobile_contribute_menu_(detailed).png|Mobile contribute menu (detailed)]] For experienced contributors, the Contribute icon is not automatically shown in their User drop-down menu. They will still see the "Contributions" option unless they change it to the "Contribute" manually. This feature is available in four Wikipedia (Albanian, Malayalam, Mongolian, and Tagalog). We have gotten valuable feedback that helped us improve its discoverability. Now, it is ready to be enabled in other Wikis. One major improvement was to [[phab:T369041|make the entry point optional for experienced contributors]] who still want to have the "Contributions" entry point as default.           We plan to enable it '''on mobile''' for Wikis, where the Section translation tool is enabled. In this way, we will provide a main entry point to the mobile translation dashboard, and the exposure can still be limited by targeting only the mobile platform for now. If there are no objections to having the entry point for mobile users from your community, we will enable it by 10th December 2024. We welcome your feedback and questions in this thread on our proposal to enable it here. Suppose there are no objections, we will deploy the "Contribute" entry point in your Wikipedia. We look forward to your response soon. Thank you! On behalf of the WMF Language and Product Localization team. [[Utenti:UOzurumba (WMF)|UOzurumba (WMF)]] ([[User talk:UOzurumba (WMF)|msg]]) 05:38, 28 nuv 2024 (CET) :imho it doesnt make sense that if i ckick on my account icon i'll not find my contributions immediatly but a generic "contribute" page. :Moreover [[Special:WantedPages]] is not reliable at all (expecially in our scn wikipedia). :i think it can be a good things for unexperienced user and to reach easier the translation, but no. thanks [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:40, 28 nuv 2024 (CET) ::Thank you @[[Utenti:GiovanniPen|GiovanniPen]], for your feedback. To clarify your comment: ::<blockquote>imho it doesnt make sense that if i ckick on my account icon i'll not find my contributions immediatly but a generic "contribute" page.</blockquote> ::For you with edits in Sicilian, Italian, and other Wikipedias, if you click on your account icon in those Wikis, you will still find your contributions icon immediately and not the "contribute" page (even after the "Contribute" is enabled there) because you have edits in those Wikipedias. The only scenario where you will find the "Contribute" entry point is if you go to the Albanian Wikipedia or any other Wikipedia you don't have any edits. It will then assume you are a new contributor and take you through that entry point to help you discover different ways to contribute. ::I hope the above clarifies that the "Contribute" entry point will only be seen by new contributors in any wikipedia where the entry point is enabled or if a contributor with edits decides to change their setting to the "Contribute" entry point. Please let me know if you have any questions. Thanks! [[Utenti:UOzurumba (WMF)|UOzurumba (WMF)]] ([[User talk:UOzurumba (WMF)|msg]]) 05:01, 3 dic 2024 (CET) == Cademia e quistioni di ortugrafìa == L'espirienzia di quarchi simana ammustra ca certi articuli ca portunu lu template "Cademia Sicialiana" sunnu scritti di na manera ca è cumpatibbili chê reguli grammaticali n usu nti l'autri pàggini. Nun havi tantu sensu distinguiri l'articuli ca hannu lu template e chiddi ca nun ci l'annu. Li quistioni cchiù mpurtanti mi parunu l'articulu determinativu (ca s'avissi a usari nti la forma littiraria, comu è usatu d'altrondi puru ntâ rivista ca la Cademia a traduciutu pi cuntu di l'Unescu, e venardiri "Lu, Li, La" nveci di "u i a"), e la duppia dd, ca si po tranquillamenti lassari libbira di putìrisi scriviri cû duppiu punti di sutta (pê wikipidiani esperti) o senza duppiu puntu di sutta (chiù facili pi cuegghié). Naturalmenti ci sunnu assai quistioni ca si putìssiru discurriri, e spissu l'utilizzatura si pigghiunu la libbirtati di scriviri comu sunnu abbituati a parrari ( e ci sinnu parrati assai diversi di na pruvincia all'autra). Ma la basi cumuni ca havemu (la grammatica, lu cumpenniu stilisticu, e ci junciu puru lu documentu dâ Ccademia, senza cuntari tutti li dizziunari antichi e no, li risursi n sicilianu dispunibbili unnegghié) dunanu na bona dirizzioni ca avemu a cuntinuari a sviluppari, nti nu spiritu cullabburaticu e custruttivu tutti nsemmula. [[User:Gmelfi|Peppi]] 14:38, 28 nuv 2024 (CET) :Salutamu Gmelfi! Ni prija assai ca ti piaci u nostru travagghiu e puru nuiautri, comu già sai, tannu partemmu propia dû Cumpenniu Stilìsticu dâ Wiki comu rifirimentu ntra l'autri. L'ortugrafìa dâ Cademia pirò nun è sulu lu/la/li (accittati dâ nostra pruposta comu "furmi auti") o i ḍḍ, ma è na pruposta ca stamu ammuttannu pi criari un criteriu d'arfabbitizzazzioni a liveḍḍu pupulari, vali a diri, nun putemu cchiù jiri avanti pinzannu a na lingua ca veni parrata tuttu u jornu, tutti i jorna ma unni nuḍḍu a sapi scrìviri. U Cumpenniu Stilìsticu dâ Wiki àvi assai punti ca foru attinziunati dintra â nostra assuciazzioni e certi cosi, ora mai, lassaru u so tempu (vidi l'h pû verbu aviri, usati 'n italianu pi spártiri u verbu di autri minutagghi, ma nùtili tutali ntô cuntestu sicilianu). Pigghiamu macari a cura chi s'àv'a aviri ntâ scigghiuta dî paroli. :A Wikipedia nun po e nun àvi a èssiri un rifirimentu linguìsticu picchì nun è a missioni di nuḍḍa Wiki nta nuḍḍa lingua. I liggi e i règuli di na lingua sunnu, di sòlitu, manijati di enti terzi, cumposti di spicialisti. L'ubbittivu dâ Wiki nun è diri comu s'àv'a scrìviri e comu no (ca tantu videmu ca sulu picca sicùtanu un criteriu), ma criari cuntinutu fruìbbili ntâ lingua. [[Utenti:Zoologo|Zoologo]] ([[User talk:Zoologo|msg]]) 20:43, 28 nuv 2024 (CET) ::@[[Utenti:Gmelfi|Gmelfi]] @[[Utenti:Zoologo|Zoologo]] se nun usati u ping... [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:45, 6 dic 2024 (CET) :::nun v'acchiappati (macari senza parrari... puru cu l'editwar) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 11:13, 7 sit 2025 (CEST) ::::Comu discussu ca supra lu template "Cademia" nun è nicissariu. Chiddi ca vòlunu scriviri chê reguli grammaticali e ortografici di la Cademia lu ponnu fari tranquillamenti e la cosa è sustanzialmenti cumpatibbili chê reguli fissati ntâ grammatica e ntô cumpenniu stilisticu. Arricordu ca lu templati fu intrudottu pi distinguiri l'articuli cunformi â scn.wiki di chiddi cunformi ê reguli dâ Cademia. Appressu la quistioni di l'articulu ditirminaticu fu discurruta a parti e ni '''misimu d'accordu supra l'usu di lu la li''' (e sparti, l'articuli lu la li foru usati dâ Cademia puru pi lu giurnali di l'Unescu di cui curau la traduzzioni n sicilianu): pi la quistioni di la doppia dd, si pò lassari la libbirtati di usu (nun è facili pi l'utilizzaturi cuegghé di usari la doppia dd chê punta di sutta). Anzi nvitu quarcunu di la cademia di cumpritari lu cumpenniu stilisticu pi l'usu di la duppia dd. Pi tutti l'autri quistioni, c'è na sustanziali cumpatibbilità tra li reguli di scn e di la Cademia. L'usu dû template è pirciò càducu. [[User:Gmelfi|Peppi]] 12:39, 7 sit 2025 (CEST) :::::il template imho è utile, sia per catalogare le voci "corrette" riviste o aggiornate ma anche per identificare una grafia da un'altra... lo stesso di come fa lmo wiki per le varianti etc (@[[Utenti:Sciking|Sciking]], no?). [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 14:41, 7 sit 2025 (CEST) :::::comunque andare a fare un rb quando la modifica è valida va contro alla policy [[:it:WP:MORDERE]] imho... [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 14:42, 7 sit 2025 (CEST) ::::::Cosa volete sapere sui TL di lmowiki? :) [[Utenti:Sciking|Sciking]] ([[User talk:Sciking|msg]]) 16:11, 7 sit 2025 (CEST) == [[User:GiovanniPen]]'s flag == Salutamu!<br> scrivo questo messaggio indirizzandolo principalmente a @[[Utenti:Melos|Melos]] e @[[Utenti:Gmelfi|Gmelfi]] che ho avuto il piacere di affiancare in questo periodo nel quale mi è stato concesso il flag temporaneo di amministratore.<br> Ringrazio anche @[[Utenti:Valerio Bozzolan|Valerio Bozzolan]] e @[[Utenti:Sciking|Sciking]] che mi hanno aiutato sin dall'inizio e @[[Utenti:ValterVB|ValterVB]] che mi ha dato una grossa mano col [[@[[Utenti:ValterVBot|suo bot]] e sopportato pazientemente ogni volta.<br> La mia è una richiesta per tutta la comunità siculofona, della quale fanno parte attivamente soprattutto @[[Utenti:Dapal|Dapal]] @[[Utenti:Zoologo|Zoologo]] @[[Utenti:GianAntonucci|GianAntonucci]] @[[Utenti:Qaqqu|Qaqqu]] (che ringrazio dell'aiuto e per il coinvolgimento della [[Cademia Siciliana]] insieme a @[[Utenti:Narkku|Narkku]] @[[Utenti:Paolorausch|Paolorausch]] @[[Utenti:Smb16|Smb16]]) ma anche saltuariamente (according to [[Special:RecentChanges]] and [[Special:ActiveUsers]]) i non siciliani @[[Utenti:Dostojewskij|Dostojewskij]] @[[Utenti:Mistico Dois|Mistico Dois]] e molto recentemente @[[Utenti:Terminisugnu|Terminisugnu]] e @[[Utenti:Cristiano Barone|Cristiano Barone]].<br> I rinnovi che mi potevano venire concessi automaticamente temporaneamente e senza una richiesta (o accettazione/proposta da parte della comunità) li ho "usati" tutti da settembre ad oggi (in realtà fino a fine mese), motivo per il quale apro oggi questa discussione (''discurruta'' ppi usari u sicilianu) sperando in un vostro riscontro positivo (a seguito della mia attività di questi mesi).<br> Se così fosse, idealmente il periodo di sysop temporaneo potrebbe venire esteso (intanto) a tutto il 2025; anno nel quale sarò anche coordinatore regionale di Wikimedia Italia per la Sicilia e che vedrà proprio Catania sede dell'evento internazionale [[:meta:ItWikiCon|itWikiCon]].<br> Sono ovviamente bene accetti ogni genere di pareri, suggerimenti, critiche, consigli e chi più ne ha più ne metta. -[[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 21:28, 5 jin 2025 (CET) *{{+1}} Giuvanni fu n'ajutu prizziusu assai! --[[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 21:34, 5 jin 2025 (CET) *{{+1}} Granni, Giuvanni. N'autru annu di crìscita! --[[Utenti:Narkku|Narkku]] ([[User talk:Narkku|msg]]) 21:41, 5 jin 2025 (CET) *{{+1}} A mprissioni ca c'haiu avutu è di nu picciottu ca ascuta i cunsigghi, chiddu chi c'hava diri a Giuvanni ci lu dissi già a sulu. I cosi vanu discussi e canciati senza prescia. Pi mia nun ci viru nienti di mali a fallu cuntinuari comu amministraturi tempuraniu pi n'autru annu. --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 23:48, 5 jin 2025 (CET) * {{+1}} Travagghiu assai apprizzatu e equilibbratu. --[[User:Gmelfi|Peppi]] 11:09, 6 jin 2025 (CET) * {{+1}} --[[Utenti:GianAntonucci|GianAntonucci]] ([[User talk:GianAntonucci|msg]]) 11:16, 6 jin 2025 (CET) * {{+1}} Troppu forti Giuvanni, oggiallannu travagghiau bonu bonu e sugnu sicuru ca macari avannu è a stissa cosa! --[[Utenti:Pow3redTheBest|Pow3redTheBest]] ([[User talk:Pow3redTheBest|msg]]) 12:02, 6 jin 2025 (CET) * {{+1}} Bravu e pacinziusu --[[Utenti:Zoologo|Zoologo]] ([[User talk:Zoologo|msg]]) 16:20, 6 jin 2025 (CET) * {{+1}} Nuautri avemu di bisognu di pirsuni forti e sperti, sinza livàri nenti ê nostri amministraturi, 'u to' travagghìu pi nuautri fu 'a megghiu cosa sti misi (armenu sicunnu mìa). Continuannu accussìni finarmenti Wikipedia SCN sarrà cchiù prutetta e furnita. [[Utenti:Cristiano Barone|Cristiano Barone]] ([[User talk:Cristiano Barone|msg]]) 14:15, 7 jin 2025 (CET) ::Grazie a tutti per i preziosi e graditi commenti :) ::buon wiki lavoro a tutti e spero tanto di incontrarvi presto durante i prossimi eventi/raduni. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 09:49, 22 jin 2025 (CET) :::{{fattu}} Auguru a Giuvanni nu bonu travagghiu --[[Utenti:Melos|Melos]] ([[User talk:Melos|msg]]) 04:48, 24 jin 2025 (CET) ::::Si avvicina la scadenza :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 21:51, 3 dic 2025 (CET) :::ciaooo, sembrava ieri ma è già volato un altro anno. se vi fa piacere io chiederei il diritto normalmente e non più temporaneo :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 13:59, 16 jin 2026 (CET) ::::{{+1}} [[Utenti:GianAntonucci|GianAntonucci]] ([[User talk:GianAntonucci|msg]]) 14:49, 16 jin 2026 (CET) ::::{{+1}} [[Utenti:Qaqqu|Qaqqu]] ([[User talk:Qaqqu|msg]]) 14:55, 16 jin 2026 (CET) ::::{{+1}} [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 15:00, 16 jin 2026 (CET) ::::{{+1}} [[Spiciali:Contributi/&#126;2026-34413-8|&#126;2026-34413-8]] ([[Discussioni utenti:&#126;2026-34413-8|discussione]]) 15:14, 16 jin 2026 (CET) :::::grazie ma non penso che dagli ip valga :/ [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:56, 16 jin 2026 (CET) ::::{{+1}} sempri avanzi, bon travagghiu Giuvà [[Utenti:Narkku|Narkku]] ([[User talk:Narkku|msg]]) 15:31, 16 jin 2026 (CET) ::::{{+1}} [[Utenti:Paolorausch|Paolorausch]] ([[User talk:Paolorausch|msg]]) 15:11, 16 jin 2026 (CET) ::::{{+1}} Avemu bisognu di pirsuni comu a tia [[User:Gmelfi|Peppi]] 23:00, 16 jin 2026 (CET) == Enabling Dark mode for logged-out users in this Wikipedia == <div lang="en" dir="ltr"> {{int:Hello}} Wikipedians, Apologies, as this message is not written in your native language. {{Int:please-translate}}. The [[mediawikiwiki:Reading/Web|Wikimedia Foundation Web team]] will be enabling [[mediawikiwiki:Special:MyLanguage/Reading/Web/Accessibility_for_reading|dark mode]] here on your Wikipedia by February 2025 now that pages on your wiki have passed our checks for accessibility and other quality checks. Congratulations! The plan to enable is made possible by the diligent work of editors and other technical contributors in your community who ensured that templates, gadgets, and other parts of pages can be accessible in dark mode. Thank you all for making dark mode available for everybody! For context, the Web team has concluded work on dark mode. If, on some wikis, the option is not yet available for logged-out users, this is likely because many pages do not yet display well in dark mode. As communities make progress on this work, we enable this feature on additional wikis once per month. If you notice any issues after enabling dark mode, please create a page: <code>Reading/Web/Accessibility for reading/Reporting/xx.wikipedia.org</code> in MediaWiki ([[mediawikiwiki:Reading/Web/Accessibility_for_reading/Reporting|like these pages]]), and report the issue in the created page. Thank you! On behalf of the [[mediawikiwiki:Reading/Web|Wikimedia Foundation Web team]]. </div> <bdi lang="en" dir="ltr">[[User:UOzurumba (WMF)|UOzurumba (WMF)]]</bdi> 23:15, 21 jin 2025 (CET) <!-- Messaggio inviato da User:UOzurumba (WMF)@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=User:UOzurumba_(WMF)/sandbox_Dark_mode_deployment_list_(February_2025)&oldid=28153450 --> :Thank you @[[Utenti:UOzurumba (WMF)|UOzurumba (WMF)]] :I request that Dark Mode be made available for non-logged users as well. :I've been using Dark Mode on this wiki by default for quite some time now and I haven't noticed any anomalies (anymore) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 09:47, 22 jin 2025 (CET) ::Thank you @[[Utenti:GiovanniPen|GiovanniPen]], for your feedback. [[Utenti:UOzurumba (WMF)|UOzurumba (WMF)]] ([[User talk:UOzurumba (WMF)|msg]]) 15:29, 22 jin 2025 (CET) == Traduzzioni dî noma dî cristiani: quali regula aduttari ? == Cari culleghi wikipidiani. Vitti ca ricintimenti quarchi biografia ha statu spustata pi prisirvari lu nomu (spissu in italianu) dû pirsunaggiu (pi esempiu [[Giorgio Chiellini]]). Nun sugnu contra lu principiu di lassari li noma in italianu, armenu pî pirsunaggi ca nun hannu liami particulari câ Sicilia. Capisciu li mutivazzioni ca foru misi pi giustificari lu spostamentu. Però, nun è dittu ca s'havi a applicari pi tutti li biografii. Pi esempiu se taliati la catiguria [[:Catigurìa:Biografìi|biografii]] tanti biografìi (forsi na cintinara) hannu lu nomu n sicilianu, speci pi pirsunaggi liati a Sicilia, ma nun sulu. Na scigghiuta raggiunevuli fussi ca pi li pirsuni ca chiaramenti la forma siciliana dû nomu è usata di manera usuali ntâ lingua parrata, la vuci s'havi a scriviri n Sicilianu (pi esempiu [[Francu Battiatu]], [[Cartesiu]], [[Sòcrati|Socrati]], [[Carlu III dû Regnu Unitu|Carlu III]], ecc.). Sta regula è in usu nti autri wikipedi, e nun ci trovu nenti di mali. Sparti di chistu secunnu mia fussi na bona cosa lassari nu rimannu quannu la vuci è n italianu e unu arricerca la pirsuna cû nomu n sicilianu. Pi esempiu ntâ wikipedia italiana, se unu cerca Giuseppe Stalin, o Abramo Lincoln, lu rimannu effettivamenti grapi la paggina cô nomu origginali forasteru. [[User:Gmelfi|Peppi]] 18:18, 16 fri 2025 (CET) :Si sunnu pirsunaggi storici o siciliani ci sta averli tradutti. Annunca i lassamu urigginali. IMHO [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 00:35, 17 fri 2025 (CET) ::U nomu 'n sicilianu sulu si è sturicamenti attistatu. Masinnò a Trump l'avìssimu a chiamari "Dunardu Trump", e ô so amicu "Iluni Musk". ::Si vulemu sicilianizzari i noma (ma pi mia no), ànn'a èssiri redirect â vuci cû nomu urigginali, comu affaccia a l'anàgrafi. Iu lassassi sempri i noma urigginali pirò, e lassassi jiri soccu fici u talianu picchì, nni l'èbbica fascista, tutti cosi foru italianizzati. ::Oji â scola nun si studìa Abramo Lincoln, ma Abraham Lincoln, e macari u re è Charles III, no Carlo III. Sparti, 'n italianu si dici Mariah Carey, e no Maria. Scempri cci nn'è quantu nni vuliti. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 00:58, 17 fri 2025 (CET) == Sub-referencing: User testing == <div lang="en" dir="ltr"> [[File:Sub-referencing reuse visual.png|400px|right]] <small>''Apologies for writing in English, please help us by providing a translation below''</small> Hi I’m Johannes from [[:m:Wikimedia Deutschland|Wikimedia Deutschland]]'s [[:m:WMDE Technical Wishes|Technical Wishes team]]. We are making great strides with the new [[:m:WMDE Technical Wishes/Sub-referencing|sub-referencing feature]] and we’d love to invite you to take part in two activities to help us move this work further: #'''Try it out and share your feedback''' #:[[:m:WMDE Technical Wishes/Sub-referencing# Test the prototype|Please try]] the updated ''wikitext'' feature [https://en.wikipedia.beta.wmflabs.org/wiki/Sub-referencing on the beta wiki] and let us know what you think, either [[:m:Talk:WMDE Technical Wishes/Sub-referencing|on our talk page]] or by [https://greatquestion.co/wikimediadeutschland/talktotechwish booking a call] with our UX researcher. #'''Get a sneak peak and help shape the ''Visual Editor'' user designs''' #:Help us test the new design prototypes by participating in user sessions – [https://greatquestion.co/wikimediadeutschland/gxk0taud/apply sign up here to receive an invite]. We're especially hoping to speak with people from underrepresented and diverse groups. If that's you, please consider signing up! No prior or extensive editing experience is required. User sessions will start ''May 14th''. We plan to bring this feature to Wikimedia wikis later this year. We’ll reach out to wikis for piloting in time for deployments. Creators and maintainers of reference-related tools and templates will be contacted beforehand as well. Thank you very much for your support and encouragement so far in helping bring this feature to life! </div> <bdi lang="en" dir="ltr">[[User:Johannes Richter (WMDE)|Johannes Richter (WMDE)]] ([[User talk:Johannes Richter (WMDE)|talk]])</bdi> 17:03, 28 apr 2025 (CEST) <!-- Messaggio inviato da User:Johannes Richter (WMDE)@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=User:Johannes_Richter_(WMDE)/Sub-referencing/massmessage_list&oldid=28628657 --> == migliorie == se non ci sono contrari, richiederei agli amministratori di interfaccia (quindi @[[Utenti:Melos|Melos]]) di:<br> modificare le impostazioni del software in modo che compaia l'iconcina dei progetti (nella barra laterale, strumenti, "in altri progetti") di fianco al nome, analogamente a quanto succede in wikipedia in francese;<br> inserire per tutti (così da averli attivabili) i gadget markAdmins (per il quale serve fare qualcosina col bot @[[Utenti:Valerio Bozzolan|Valerio Bozzolan]]), catalot (oltre il già attivabile hotcat), wikidatainfo, liveclock (purge) e qualunque altro si ritenga necessario.<br> grazie! [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 01:05, 19 maj 2025 (CEST) :{{+1}} [[Utenti:Cristiano Barone|Cristiano Barone]] ([[User talk:Cristiano Barone|msg]]) 11:09, 26 maj 2025 (CEST) :re-ping {{ping|melos}}. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 13:26, 7 gnt 2025 (CEST) ::sperando che prima o poi passi la patch [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 11:12, 7 sit 2025 (CEST) :::ricordiamoci che siamo una wiki "media" e non "small" (https://gerrit.wikimedia.org/g/operations/mediawiki-config/+/a2d2aaab9ace84280dd2f4c70a33bb69cd73850f/dblists/medium.dblist) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 20:31, 24 dic 2025 (CET) :quello che andava sistemato da gerrit è stato fatto. le icone di fianco ai progetti nella sidebar sono state aggiunte (come su wikipedia in fr e nl etc). tra gli accessori (al momento) ci sono solo i seguenti: :* Cat-a-lot (Nu strumentu pi aiutari a spustari chhiù file tra li categurii o junciri catigurii a li risultati di la ricerca) :* HotCat (untranslated: Permette di gestire le categorie di una pagina direttamente dalla modalità di visualizzazione.) :penso possa essere molto utile avere anche wikidatainfo e liveclock. poi vedremo che altro :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 19:34, 4 maj 2026 (CEST) == Wikidata Item and Property labels soon displayed in Wiki Watchlist/Recent Changes == ''(Apologies for posting in English, you can help by translating into your language)'' Hello everyone, the [[m:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Resolve_Labels|Wikidata For Wikimedia Projects]] team is excited to announce an upcoming change in how Wikidata edit changelogs are displayed in your [[Special:Watchlist|Watchlists]] and [[Special:RecentChanges|Recent Changes]] lists. If an edit is made on Wikidata that affects a page in another Wikimedia Project, the changelog will contain some information about the nature of the edit. This can include a QID (or Q-number), a PID (or P-number) and a value (which can be text, numbers, dates, or also QID or PID’s). Confused by these terms? See the [[d:Special:MyLanguage/Wikidata:Glossary|Wikidata:Glossary]] for further explanations. The upcoming change is scheduled for '''17.07.2025''', between '''1300 - 1500 UTC'''. The change will display the label (item name) alongside any QID or PIDs, as seen in the image below: [[File:Apr10 edit summary on Wikidata.png|An edit sum entry on Wikidata, labels display alongside their P- and Q-no.'s]] These changes will only be visible if you have Wikidata edits enabled in your User Preferences for Watchlists and Recent Changes, or have the active filter ‘Wikidata edits’ checkbox toggled on, directly on the Watchlist and Recent Changes pages. Your bot and gadget may be affected! There are thousands of bots, gadgets and user-scripts and whilst we have researched potential effects to many of them, we cannot guarantee there won’t be some that are broken or affected by this change. Further information and context about this change, including how your bot may be affected can be found on this [[m:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Resolve_Labels|project task page]]. We welcome your questions and feedback, please write to us on this dedicated [[m:Talk:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Resolve_Labels|Talk page]]. Thank you, - [[m:User:Danny_Benjafield_(WMDE)|Danny Benjafield (WMDE)]] on behalf of the Wikidata For Wikimedia Projects Team. [[Utenti:MediaWiki message delivery|MediaWiki message delivery]] ([[User talk:MediaWiki message delivery|msg]]) 14:45, 14 gnt 2025 (CEST) <!-- Messaggio inviato da User:Danny Benjafield (WMDE)@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=User:Danny_Benjafield_(WMDE)/MassMessage_Test_List&oldid=28981877 --> == neutralizzazione progetti == tanto non c'è comunità... restano tutte come pagine di servizio obsolete... pareri? [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 19:32, 23 agu 2025 (CEST) == AVVISU: Misa fora sirvizziu dû Template "Ortugrafìa dâ Cademia" == Lu template Ortugrafìa dâ Cademia è misu fora sirvizziu ntê prossimi jorna. Li pirsuni ntirissati ponnu fari nu backup di vuci e articuli a cui stu template è assuciatu. Lu template ha svurgiutu n compitu di classificazzioni utili, a un momentu unni na seri di quistioni eranu n discussioni. Ora nun è cchiù nicissariu, e supratuttu viola na seri di reguli di wikipedia: * '''<nowiki>[[WP:PROMO]]</nowiki> –''' ** Wikipedia nun è nu spazio pi pubblicizzari enti privati. Nu logu ricurrenti comu ntô template attuali è cunsideratu promozzioni. * '''<nowiki>[[WP:TEMPLATE]]</nowiki> – Usu dû template''' ** Li template hannu a sèrbiri sulu pi scopi nciclopedici, pi navigazzioni o manutinzioni. Nun si pò ammettiri di usàrili pi mettiri loghi o sponsorizzazioni. * '''<nowiki>[[WP:COI]]</nowiki> – Conflitto di interessi''' ** Siddu l’associazioni ca lu prumòvi cuntribuisci pi mutivi di mmagini o autopromozioni, chistu pò minari l’attendibilitati e la neutralitati dî cuntinuta. [[User:Gmelfi|Peppi]] 22:02, 7 sit 2025 (CEST) :@[[Utenti:Gmelfi|Gmelfi]] anche se tu eliminassi il template (per quanto imho deve sempre esserci parere concorde della comunità) il contenuto delle voci non dovrebbe venire inficiato, per cui non vedo perché “le persone interessate dovrebbero fare backup di voci srticoli a cui il template è associato” :aggiungo che non è cambiato niente (se non in minima parte) da quando il template è stato creato e iniziato a usare, ancora ci sono pagine in condizioni pietose… :infine, continuando così, rischiamo di perdere una buona fetta (se non la totalità) di quella estremamente risicata comunità che c’è ed è innegabile che l’aiuto che ci stanno dando i ragazzi della cademia è enorme! [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 08:40, 8 sit 2025 (CEST) :PS: anche all’opposto è sempre COI: sia che a favore di qualcosa sia se estremamente o palesemente contrari. Deve valere sempre [[:it:WP:NPOV]] (e il tuo sockpuppet su enwiki ha già mostrato tanta ostilità “preventiva” nei confronti della cademia forse) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 08:43, 8 sit 2025 (CEST) ::Supra lu pareri dâ cumunitati sugnu pirfittamenti d'accordu. Ma nun c'è dubbiu ca lu template è usatu di manera nun cunformi. Comu dittu supra viola diversi politici di usu. E sparti di chistu, lu template fa cridiri (a tortu), ca li vuci cu stu template ponnu essiri mudificati sulu usannu la grammatica e l'ortografia dû documentu (ca pirò nun è cumprensiva e nun è di facili appropriazzioni). L'usu dû logu è puru inappropriatu, pirchì nudda associazzioni, macari senza scopu di lucru, pò mettiri nu "stampu" nti na vuci di wikipedia, e spiru ca vuatri siti d'âccordu. E cumunqui, firmu ristannu ca lu template viola li reguli di wikipedia (e pi chissu s'havi a livari), li vuci restunu comu sunu. Comu dissi già, li reguli dû documentu sunu essenziarmenti cumpatibbili cu la grammatica e lu cumpenniu stilisticu. Apprezzu assi li cuntribbuti di l'utenti ca scrivunu cu reguli ortofrafici ca nun sunu cumpritamenti in adequazzioni cu lu cumpenniu stilisticu e la grammatica. Anzi, lu cumpenniu stilisticu e la grammatica sunu vuci di wikipedia ca si ponnu canciari siddu c'è nu cunsensu nti stu sensu. Pirsunarmenti iu sugnu di l'idea ca avissimu a discurriri di manera trasparenti e pùbbrica (ntô circulu o ntê pàggini di discussioni dê reguli di grammatica) supra eventuali canci o ntegrazzioni ca putissimu aduttari. Iu sugnu pi lu dialugu. [[User:Gmelfi|Peppi]] 15:27, 11 sit 2025 (CEST) :::Nuiautri pigghiammu pi spirazzioni i mudeḍḍi [[:lmo:Modell:SL|Modell:SL]], [[:lmo:Modell:NOL|Modell:NOL]], [[:lij:Template:Grafia_unitäia|Template:Grafia_unitäia]], [[:lij:Template:Grafîa_ofiçiâ|Template:Grafîa_ofiçiâ]] (e autri sìmili ca cci sunnu pi autri lingui). Superchiu avemu u nostru mercu, ma allura abbasta chi u livamu e semu a postu. Na pàggina avissi a èssiri scritta di manera cuirenti; adunca u mudeḍḍu signalija sulu chi si sta usannu n'ortugrafìa spicìfica. [[Utenti:Dapal|dapal]]<sup>(''[[Discussioni utenti:Dapal|scrìvimi]]'' [[Spiciali:InviaEMail/Dapal|@]])</sup> 17:59, 11 sit 2025 (CEST) ::::Grazzi pi li vostri risposti. Pi vèniri ncontru ê dumanni di mantinimentu dû template, e nti nu spiritu custruttivu, comu amministraturi e burocrati, e n certu sensu vardianu neutrali dî reguli di wikipedia, putiemu accittari la pruposta di rittificari lu template pi mittillu n cunfurmità, e n particulari livannu lu logu, accussì lu template si pò cunsidirari cunformi ê reguli (n quantu template di sirvizziu e manutinzioni). Mi pari comunqui un piccatu ca lu [[Wikipedia:Cumpenniu Stilìsticu|Cumpenniu stilisticu]], l'[[Ortografìa siciliana|Ortografia]], e la [[Wikipedia:Grammàtica|grammatica]] ca fu stabbiluta (e chi si pò puru canciari, evòrviri, discutiri) nun attrovanu l'unanimitati di l'utenzi. [[User:Gmelfi|Peppi]] 14:10, 18 sit 2025 (CEST) :::::che comunque non penso che si sia mai detto che non ci sia unanimità tra noi utenti attivi e conoscitori della lingua nei modi di scrittura ortografia grammatica etc. il problema è che nel tempo molte cose sono state fatte "male" o da chi non conosceva o non ha seguito le regole (stilistiche e non) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 19:30, 4 maj 2026 (CEST) == Missaggiu d'erruri nti circa ducentu pàggini == Signalu lu missaggiu d'erruri ca cumpari n particulari n capu ê pàggini dê stati: lu messaggiu è [[Cuurdinati giugràfichi|"Cuurdinati]]<nowiki>: missing longitude (dec format) in {{</nowiki>[[Template:Coord|Coord]]<nowiki>}} ". Stu missaggi cumpari praticamenti nti tutti li pàggini. Mi pari ca veni di l'infobox stati, ma nun mi firai a risorviri lu probblema. Quarcunu sapi comu risorviri lu probblema ? </nowiki>[[User:Gmelfi|Peppi]] 12:00, 22 sit 2025 (CEST) :È un problema di implementazione delle coordinate. Sapevo che esistesse ma speravo fosse risolto. A volte è perché mancano le coordinate nel template infobox stato (che andrebbe comunque rifatto o risistemato) mentre altre volte è perché le coordinate proprio non ci sono (nei parametri del template) e siccome l’implementazione non è corretta spunta l’errore. :L’ideale sarebbe averle automaticamente da wikidata, i’ll work on it appena posso. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:07, 22 sit 2025 (CEST) ::Lu probblema fu risurvutu. Filicitazzioni pi lu travagghiu di qualitati eccillenti. [[User:Gmelfi|Peppi]] 14:22, 1 utt 2025 (CEST) == Wikipedia 25: cercasi volontari per registrare un benvenuto sonoro == <div lang="en" dir="ltr"> <div lang="it" dir="ltr"> [[File:Work-in-progress sketch of the Confetti mascot easter egg.jpg|frameless|250px|right]] {{int:please-translate}} {{int:Hello}}, scusate se scrivo in italiano! Per il [[:m:Wikipedia 25|25° compleanno di Wikipedia]] e per creare delle [[:m:Wikipedia 25/Easter egg experiments|sorpresine per i lettori]] come proposto dalla Wikimedia Foundation, sto invitando i volontari delle varie Wikipedie dell'area italiana a registrare la frase "Ti diamo il benvenuto su Wikipedia" nella loro lingua regionale. Il messaggio audio comparirà "a sorpresa" sulla Wikipedia in italiano e sulle altre wikipedie aderenti al progetto degli [[:m:Wikipedia 25/Easter egg experiments|Ester eggs experiments]]. Farà parte di una raccolta di suoni che include tutte le registrazioni di "Ti diamo il benvenuto su Wikipedia" nelle varie lingue registrate, più alcuni altri suoni provenienti da Commons. Quando un utente cliccerà sulla mascotte del Globetto (Baby Globe) che suona con un sintetizzatore, verrà riprodotto un suono casuale da questa raccolta. Quindi, la frase nella tua lingua non verrà riprodotta ogni volta, ma solo alcune volte e in modo casuale. '''Briefing su come registrare il benvenuto sonoro su Wikipedia''' ([[:m:Talk:Wikipedia_25/Easter_egg_experiments#c-CDekock-WMF-20251209155700-Song_Ng%C6%B0-20251201160400|da qui]]): #la registrazione audio deve essere più corta di 10 secondi, e consistere solo nella frase "Benvenuti su Wikipedia" o "Ti diamo il benvenuto su Wikipedia" nella tua lingua regionale; #il file va caricato su [[:commons:Special:UploadWizard|Wikimedia Commons]] e bisogna chiederne la protezione da parte di un admin di modo da impedire che sia vandalizzato o spostato; #condividi il link del file su Commons [[:m:Talk:Wikipedia_25/Easter_egg_experiments#Are_there_ideas_or_elements_that_you_would_love_to_see_implemented_on_your_language_Wikipedia?|qui]] notificando l'utente CDekock-WMF; #'''deadline''' per fornire i link agli audio su Commons dei "Benvenuti su Wikipedia": '''mercoledi 21 gennaio 2026'''. Registriamo più audio possibile. {{Int:Feedback-thanks-title}} --[[User:Una tantum|Una tantum]] ([[User talk:Una tantum|talk]]) </div> </div> 16:44, 14 jin 2026 (CET) <!-- Messaggio inviato da User:Una tantum@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=User:Una_tantum/sandbox/MM/It_fallback_v2&oldid=29928398 --> == Central Notice Banner on Sicilian wiki on mobile == Hello! Sorry for not writing in your language. <br/> [[m:Wikipedia_25/Easter_egg_experiments#Participating_wikis|Your wiki has decided to activate the Birthday mode]] in celebration of Wikipedia’s 25th birthday. As part of the project, I wanted to let you know that the Wikimedia Foundation is planning to run Central Notice Banners from '''16 Feb - 16 Mar''' on your Wikipedia for ''both logged-in and logged-out users'' on ''mobile only''. <br/>The banner will let people know that [https://wikimediafoundation.org/it/wikipedia-mascot/ Birthday mode] is available on mobile (Minerva) and informs them how to turn them on.<br/> You can view more details of the banner campaign [https://phabricator.wikimedia.org/T410079 on Phabricator]. <br/> Please feel free to reply here with any questions. Thank you!<br/> [[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 14:52, 28 jin 2026 (CET) :thanks @[[Utenti:IKristiani-WMF|IKristiani-WMF]] :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:51, 28 jin 2026 (CET) :better link is https://wikimediafoundation.org/wikipedia25/wikipedia-mascot/ [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 16:51, 28 jin 2026 (CET) :Thanks @[[Utenti:GiovanniPen|GiovanniPen]]. You're right! Even better link is: https://wikimediafoundation.org/it/wikipedia-mascot/ [[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 04:36, 29 jin 2026 (CET) :dear @[[Utenti:IKristiani-WMF|IKristiani-WMF]], sorry for answering this late. the translations have already been done (as maybe you have seen). :I take this opportunity to point out a problem at the end of the link you sent (WP25 in Italiano), it appears just "Bildnachweis" (wrong language) with no photo credits below. [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 22:48, 4 fri 2026 (CET) ::Hello @[[Utenti:GiovanniPen|GiovanniPen]] Thank you so much for volunteering your time to help with the translation. I have noted the error you pointed out and will inform the team to fix this. ::[[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 08:08, 5 fri 2026 (CET) :::Thanks, and of course to @[[Utenti:GianAntonucci|GianAntonucci]] as well that managed the translation :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 11:54, 5 fri 2026 (CET) == Help us translate Birthday Mode for your wiki == Hello! We need your help in translating the Community Configuration for Birthday Mode from English to Sicilian. This is the setting that your community will use to customize the Baby Globe on your wiki.</br> You can help translate directly [https://translatewiki.net/w/i.php?title=Special%3ATranslate&group=ext-wp25eastereggs&language=scn&filter=&optional=1&action=translate here]. You need to create an account on Translate Wiki if you haven’t already.</br> Please feel free to reply here with any questions. Thank you! [[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 11:05, 10 fri 2026 (CET) :@[[Utenti:GianAntonucci|GianAntonucci]] @[[Utenti:Dapal|Dapal]] @[[Utenti:Qaqqu|Qaqqu]] [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 11:15, 11 fri 2026 (CET) ::Appò, u fici. [[Utenti:GianAntonucci|GianAntonucci]] ([[User talk:GianAntonucci|msg]]) 00:02, 12 fri 2026 (CET) :::Thanks @[[Utenti:GianAntonucci|GianAntonucci]]. :::@[[Utenti:IKristiani-WMF|IKristiani-WMF]] all done :) [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 12:04, 13 fri 2026 (CET) == Alcuni aggiornamenti importanti sulla Modalità compleanno == Ciao! '''Ora puoi attivare la modalità Compleanno!''' Con la presente desideriamo informarti di alcune importanti modifiche alla modalità Compleanno che la tua wiki ha deciso di adottare. Queste modifiche sono state apportate dopo aver testato la modalità Compleanno attraverso il cluster beta e Test Wikipedia e dopo essersi assicurati che fosse accessibile alle persone con problemi di sensibilità al movimento. Per informazioni dettagliate, consulta [[metawiki:Wikipedia_25/Easter_egg_experiments/Collaboration_process#Go-live_date_and_configuration_update_–_12_Feb|questa pagina]]. Alcune delle modifiche importanti includono: # L'elenco predefinito di voci (QID) in cui apparirà Baby Globe sarà limitato a 2500 per lingua su Wikipedia e non ci sarà alcun Baby Globe “neutro” che apparirà su tutte le pagine non configurate. Ciò significa che, quando troverete Baby Globe, vi sembrerà più un easter egg. È possibile visualizzare [[metawiki:Wikipedia_25/Easter_egg_experiments/article_configuration#Configuration_defaults|l'elenco delle voci predefinite]] che ogni lingua di Wikipedia può ulteriormente personalizzare tramite [[Spiciali:CommunityConfiguration/WP25EasterEggs|la configurazione della comunità]]. # Al fine di mostrare Baby Globe sul web mobile, abiliteremo gli [[phab:T416644|avvisi del sito a livello globale sui dispositivi mobili]]. # La Modalità compleanno sarà ora disponibile fino al 6 aprile. Non esitate a rispondere qui per qualsiasi domanda. Grazie! [[Utenti:IKristiani-WMF|IKristiani-WMF]] ([[User talk:IKristiani-WMF|msg]]) 17:39, 19 fri 2026 (CET) :Grazie! [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 22:39, 19 fri 2026 (CET) == Prossimi incontri: OSM a Messina, Wikipedia a Catania == [[File:Wikipedia 25 event in Palermo, Sicily 03.jpg|thumb|Partecipanti durante l'incontro di Wikipedia 25 a Palermo a gennaio]] Buongiorno a tutti, Appena completato il [[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Eventi_per_il_compleanno_di_Wikipedia|nostro tour di Sicilia con eventi per celebrare il compleanno di Wikipedia]], andiamo avanti con i nostri prossimi incontri per conoscerci di persona e migliorare insieme i nostri progetti collaborativi preferiti. Puoi raggiungerci prossimamente a queste occasioni: * '''[[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Mapping_Day_e_formazione_a_Messina,_28_Febbraio|Mapping Day a Messina, questo sabato 28 febbraio]]''': giornata di scoperta e di contribuzione alla mappa libera OpenStreetMaps attraverso vari strumenti che si usano dal telefono. * '''[[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Modifichiamo_Wikipedia_insieme!_Catania,_13_marzo|Incontro di contribuzione a Wikipedia a Catania il 13 marzo]]''': un raduno per modificare Wikipedia insieme. Se vuoi partecipare, non dimenticare di iscriverti nell'elenco di partecipanti per ogni evento, e di raggiungere il nostro gruppo Telegram per ricevere aggiornamenti. E come sempre, se hai un'idea o vuoi organizzare un incontro nella tua zona, non esitare a contattare me o [[it:utente:GiovanniPen|GiovanniPen]], ti supportiamo con gran piacere. A presto, [[it:utente:Auregann|Auregann]], 08:21, 25 fri 2026 (CET) <small>Ricevi questo messaggio perché sei iscritto/a nella [[m:lGlobal message delivery/Targets/Wikimediani in Sicilia|lista di diffusione dei Wikimediani in Sicilia]].</small> <!-- Messaggio inviato da User:Auregann@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Wikimediani_in_Sicilia&oldid=30124662 --> == Prossimi incontri di presenza in Sicilia (marzo-aprile 2026) == Ciao! Ecco i prossimi eventi che organizziamo per i volontari di Wikipedia in Sicilia. Se hai voglia di conoscere altri utenti di persona o di diventare più coinvolto/a nei nostri progetti, non esitare a partecipare! * [[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Wikimeet_palermitano_-_Palermo,_27_marzo|Wikimeet a '''Palermo, 27 marzo''']] * [[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Astrofotografia_e_licenze_libere,_Gruppo_Astrofili_Catanesi,_16_aprile|Incontro sull'astrofotografia e licenze libere a '''Catania, 16 aprile''']] * [[it:Wikipedia:Raduni/Raduni_in_Sicilia_2026#Modifichiamo_Wiki_e_OSM_insieme!_-_Catania,_23_aprile|Modifichiamo Wiki e OSM insieme! a '''Catania, 23 aprile''']] Per qualsiasi domanda su questi eventi, o se hai un idea per un prossimo evento, non esitare a contattare il nostro coordinatore regionale [[it:utente:GiovanniPen|GiovanniPen]]. A presto, [[it:utente:Auregann|Auregann]], 12:17, 24 mar 2026 (CET) <small>Ricevi questo messaggio perché sei iscritto/a nella [[m:lGlobal message delivery/Targets/Wikimediani in Sicilia|lista di diffusione dei Wikimediani in Sicilia]].</small> <!-- Messaggio inviato da User:Auregann@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Wikimediani_in_Sicilia&oldid=30244242 --> == Prossimi incontri wiki e OSM in provincia di Catania (aprile e maggio 2026) == Ciao! Il gruppo dei Wikimediani in Sicilia ha organizzato nuovi incontri per conoscere altri utenti di Wikipedia e OSM di persona e lavorare insieme sui nostri progetti preferiti. Ecco i prossimi raduni in zona di Catania ad aprile e maggio, tutte le informazioni e iscrizioni si trovano [[it:Wikipedia:Raduni/Raduni in Sicilia 2026|sulla pagina dei raduni in Sicilia]]. * '''Modifichiamo Wiki e OSM insieme!''' il 23 aprile sera da Localhost (Catania), per conoscere nuove persone e lavorare insieme * '''Editathon "Voci di carta, voci digitali"''' il 7 maggio pomeriggio al DISUM dell'Università di Catania, per migliorare insieme voci sugli autori italiani * '''Mappiamo le Aci''', 16 e 17 maggio ad Acireale, per arricchire i dati cartografici su OpenStreetMap, a piedi o in bici Per qualsiasi domanda su questi eventi, o se hai un idea per un prossimo evento, non esitare a contattare il nostro coordinatore regionale [[it:utente:GiovanniPen|GiovanniPen]]. A presto, [[it:utente:Auregann|Auregann]] 10:35, 22 apr 2026 (CEST) <small>Ricevi questo messaggio perché sei iscritto/a nella [[m:lGlobal message delivery/Targets/Wikimediani in Sicilia|lista di diffusione dei Wikimediani in Sicilia]].</small> <!-- Messaggio inviato da User:Auregann@metawiki usando l'elenco su https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Wikimediani_in_Sicilia&oldid=30244242 --> == Hiruwiki == Hello everyone, I’d like to ask if there is any interest within the Sicilian Wikipedia in using Hiruwiki. Hiruwiki is a collection of interactive, multilingual geometric and mathematical widgets designed for Wikimedia projects. It was originally developed by the Basque Wikimedia Chapter and later updated for broader international use. The goal is to allow editors to embed dynamic proofs, visualisations, and interactive elements directly into wiki pages, making learning content more engaging and easier to understand. Do you think this could be useful for courses or educational materials on this wiki? You can see an example on the Dutch wikipedia [[:nl:Wikipedia:Hiruwiki]] [[Utenti:ItsNyoty|ItsNyoty]] ([[User talk:ItsNyoty|msg]]) 22:13, 2 maj 2026 (CEST) :thanks. {{+1}} by me ofc (as said irl at the [[:mw:Wikimedia Hackathon 2026|hackathon]] 😊). [[Utenti:GiovanniPen|GiovanniPen]] ([[User talk:GiovanniPen|msg]]) 23:42, 2 maj 2026 (CEST) 5jnqbv0niwwc051uqpys8ib35fpdz1e San Feli 0 39515 781878 777141 2026-05-13T08:48:28Z ~2026-28829-53 50954 Sito 781878 wikitext text/x-wiki [[File:San Fele Vista Panoramica.jpg]] '''San Feli''' è nu cumuni di 3546 abbitanti dâ [[pruvincia di Putenza]]. {{pruvincia di Putenza}} https://www.comune.sanfele.pz.it/ 98xkjpm1w2s3vluid4b42gqjreo6kjo Cavazzo Carnico 0 41754 782050 666180 2026-05-13T11:00:10Z GiovanniPen 22308 782050 wikitext text/x-wiki {{Cumuni|nomucumuni=Cavazzo Carnico|nomuufficiali=Cavazzo Carnico |pruvincia=[[Pruvincia di Udine|Udine]] (UD) |riggiuni=Sicilia |superfici=38 |abbitanti=1.107 |dinsita=30 |cumunilimitrofi= Amaru,Bordano,Tolmezzo,Trasaghis,Verzone,Verzegnis,Vito D'Asio(PN) |cap=33020 |prifissutelefonicu=0433 }} '''Cavazzo Carnico''' ('''''Cjavaç''''' in friulanu) è un cumuni dâ [[pruvincia di Udine]] {{Pruvincia di Udini}} [[Catigurìa:Cumuna dâ pruvincia di Udini]] 6hj07bgh695jc4d52nhgs2542ijd8g9 782051 782050 2026-05-13T11:00:45Z GiovanniPen 22308 782051 wikitext text/x-wiki {{Cumuni|nomucumuni=Cavazzo Carnico|nomuufficiali=Cavazzo Carnico |pruvincia=[[Pruvincia di Udine|Udine]] (UD) |superfici=38 |abbitanti=1.107 |dinsita=30 |cumunilimitrofi=Amaru, Bordano, Tolmezzo, Trasaghis, Verzone, Verzegnis, Vito D'Asio(PN) |cap=33020 |prifissutelefonicu=0433 }} '''Cavazzo Carnico''' ('''''Cjavaç''''' in friulanu) è un cumuni dâ [[pruvincia di Udine]] {{Pruvincia di Udini}} [[Catigurìa:Cumuna dâ pruvincia di Udini]] kvcvcsrfz785c7dblqsva0ukvzilezg MuVumentu 5 Stiddi 0 48783 781877 779816 2026-05-13T00:19:20Z InternetArchiveBot 37902 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 781877 wikitext text/x-wiki [[File:M5S logo 2050.svg|thumb|200px|Logu di M5S]] Lu '''MuVumentu 5 Stiddi''' ('n [[lingua italiana|talianu]] '''MoVimento 5 Stelle''', '''M5S''') è nu [[partitu]] politicu [[talianu]], cca rifiuta la qualificazzioni di partitu, lu portavuci nazziunali, prìcisa cca lu M5S nun è nu partitu puliticu ntô lu sò blog, ma na "assimbrea libbira di cittadini"<ref>[http://www.beppegrillo.it/listeciviche/liste/fabriano/chi-siamo.html Cca Semu - Blog di Beppi Grillu]</ref>. Fu funnatu ntô [[2009]] si [[Beppi Grillu]], ca ni è lu leader (o megghiu portavuci nazziunali). ==Storia== Lu [[16 di giugnettu]] [[2005]], [[Beppi Grillu]] dâ li sò blog BeppeGrillo.it la nasciuta di nu social network ''Meetup''. ==Idioluggìa== L'idioluggìa dû '''M5S''' sunnu: ambientalismu, e-democracy, dicriscita. ===Rifiutu di rimbursi eletturali=== Unica carattiristica dû '''M5S''' è lu rifiutu di rimbrursi eletturali. Ntô elezzioni riggiunali 'n [[Piemunti]] e 'n [[Emilia Rumagna|Emilia-Rumagna]] di circa 320.000 euro<ref>[http://photos1.meetupstatic.com/photos/event/8/b/c/0/highres_16955776.jpeg Gazzetta ufficiali dâ Ripubbrica Taliana n° 175 29/7/2010]</ref> e 'n [[Sicilia]], dâ l'elezzioni riggiunali dû [[2012]] di circa 700.000-800.000 euru<ref>[https://web.archive.org/web/20121117001814/http://www.ilmessaggero.it/primopiano/politica/sicilia_grillo_movimento_5_stelle_rimborsi_elettorali/notizie/231761.shtml IlMessaggero.it: Grillu, ú eletti dû M5S 'n Sicilia rìstituiscunu ù rimborsi ma sbagghianu cifra]</ref>. ===Puliticanti cumu dipindinti=== N virtù dâ [[Custituzzioni dâ Ripùbbrica Taliana|Custituzzioni]] dâ [[Talia|Ripubbrica Taliana]], û diputati e cunzigghiuri sunnu cumu ''dipintiti da li cittadini''<ref>[http://www.governo.it/Governo/Costituzione/CostituzioneRepubblicaItaliana.pdf (PDF) Custuzzioni di la Ripubbrica Taliana - Artìculu 67]</ref>. ==Curiusitati== Macari ntâ [[San Marinu|Ripubbrica di San Marinu]] esisti lu '''M5S SM''', nasciu lu [[11 di austu]] [[2012]] ppi fari nesciri da nu scandalu dî la ripubbrica e di la situazziuni pulìtica lucali. Lu [[1 di uttùviru]] [[2012]] lu ''M5S - San Marinu'' dicidunu di nun participari â li elezzioni ripubbricani dû [[11 di nuvèmmiru]] [[2012]] ppi na mancanza di risurtati da 1/3 ppi quote ruse<ref>[https://web.archive.org/web/20121031081820/http://www.giornale.sm/movimento-5-stelle-san-marino-non-si-presentera-alle-prossime-elezioni-politiche-dell11-novembre-2012/#.UNxbuqx0EW- GiornaleSanMarino.it: Muvumentu Cincu Stiddi San Marinu: M5S SAn Marinu nun presentìra â li elezzioni pulìtichi dê 11 nuvèmmiru 2012]</ref>. ==Membri attivisti== ===Sinatu=== Â lu Sinatu lu capu-gruppu è Vito Crimi, di [[Lummardia]]. U Sinaturi sugnu 54, ô 30 di avrili, doppu spulzu di Mastrangeli sugnu passau a 53 sinaturi attivisti M5S. Ô [[30 di avrili]] [[2013]] è statu spulzu lu sinaturi Marino Germano Mastrangeli picchi hava participatu 'n prugrammi televisivi e cchiu voti assenti 'n Parramentu Talianu. ===Càmmira=== La capu-gruppu parramentari è Roberta Lombardi, di [[Tuscana]]. U diputati sugnu 'n tutali 109. ===EuruParramentu=== ===[[Samprea Riggiunali Siciliana]]=== # Giancarlo Cancellieri, purtavuci e capu-gruppu ARS # Valentina Zafarana # Giannina Ciancio # Vanessa Ferrara # Angela Foti # Claudia La Rocca # Valentina Palmieri # Francesaco Cappello # Giorgio Ciaccio # Matteo Mangiacavallo # Salvatore Siragusa # Giampiero Trizzino # Sergio Troisi # Antonio Venturino<ref>[http://www.sicilia5stelle.it/2013/05/antonio-venturino-si-pone-fuori-dal-movimento-5-stelle-ha-ignorato-una-regola-fondante/ Sicilia5Stiddi: Antonio Venturi è fora da lu M5S Sicilia]</ref><ref>[http://www.ilfattonisseno.it/2013/05/regione-venturino-e-fuori-dal-m5s-non-ha-effettuato-restituzione-delleccedenza-dello-stipendio/ Il Fatto Nisseno: Ars, Venturino è fuori dal M5S: non ha restituito l’eccedenza dello stipendio]</ref><ref>Lu Prisidenti havu rifiutatu di cuntribbuiri ppi surdi</ref>, Prisidenti Assimbrea # Stefano Zito ===Cunzigghiu Riggiunali di Talia=== Ô [[2005]] â [[2013]] i cunzigghiuri riggiunali su nu tutali di 1078 havanu di circa 40 attivisti. == Elezzioni == {| class="wikitable |colspan=2; width=50%| [[File:M5S logo 2050.svg|center|30px|Logo M5S]] !width=20%|Voti !width=15%|% !width=15%|Seggi |- !colspan=2; align=left|Elezzioni riggiunali taliani dû 2010<ref>Solo 'n [[Campania]]], [[Emilia-Rumagna]], [[Piemunti]], [[Venetu]] e [[Lummardia]]</ref> |align=center|390.097 |align=center|1,74 |align=center|4<ref>Giovanni Favia e Fabrizio Biolè, sunnu stati 'n siguitu spulzi.</ref> |- !colspan=2; align=left|Elezzioni riggiunali 'n [[Mulisi]] dû 2011 |align=center|10.650 |align=center|5,60 |align=center|0 |- !colspan=2; align=left|Elezzioni riggiunali 'n [[Sicilia]] dû 2012 |align=center|368.006 |align=center|18,17 |align=center|15 |- !colspan=2; align=left|Elezzioni riggiunali 'n [[Lazziu]] dû 2013 |align=center|661.865 |align=center|20,22 |align=center|7 |- !colspan=2; align=left|Elezzioni riggiunali 'n [[Lummardia]] dû 2013 |align=center|782.007 |align=center|13,62 |align=center|9 |- !colspan=2; align=left|Elezzioni riggiunali 'n [[Mulisi]] dû 2013 |align=center|32.200 |align=center|16,76 |align=center|2 |- !rowspan=2; align=left|Elezzioni pulìtichi taliani dû 2013 !align=left|<small>[[Càmmira]]</small> |align=center|8.689.458 |align=center|25,55 |align=center|109 |- !align=left|<small>[[Sinatu]]</small> |align=center|7.285.850 |align=center|23,79 |align=center|53<ref>Lu sinaturi Marino Germano Mastrangeli è statu 'n siguitu spulzo.</ref> |- !colspan=2; align=left|Elezzioni riggiunali 'n [[Friuli Venezzia Giulia]] dû 2013 |align=center|103.135 |align=center|19,21 |align=center|5 |} ==Noti== <references/> == Lijami di fora == * [https://web.archive.org/web/20180613012747/http://www.movimentocinquestelle.it/ Situ ufficiali dû Muvumentu Cincu Stiddi] * [http://www.beppegrillo.it Blog di Beppi Grillu lu funnaturi] [[Catigurìa:Pulìtica]] 73wueaqdbpdu9mjji45zor6nnqg9rxz Ulassai 0 49030 782052 730407 2026-05-13T11:01:12Z GiovanniPen 22308 782052 wikitext text/x-wiki {{Cumuni|nomucumuni=Ulassai|nomuufficiali=Ulassai |pruvincia=[[Pruvincia di Nuoro|Nuoro]] |superfici=122,41 |abbitanti=1.423 |dinsita=11,62 |cumunilimitrofi=[[Esterzili]], [[Gairo]], [[Jerzu]], [[Osini]], [[Perdasdefogu]], [[Seui]], [[Tertenia]], [[Ussassai]], [[Villagrande Strisaili]], [[Villaputzu]] |cap=091098<ref>[https://www.ilcapdi.it/catania/fiumefreddo-di-sicilia CAP di Ciumifriddu, Catania]</ref> |prifissutelefonicu=0782 }} '''Ulassai''' è un [[cumuni talianu]] dâ [[pruvincia di l'Ogliastra]] ntâ [[Sardigna]]. == Note == <references /> {{Pruvincia di l'Ogliastra}} [[Catigurìa:Cumuna dâ pruvincia di l'Ogliastra]] 6heug5oz89pjmdmmkv0bcbwi46ddvxp 782053 782052 2026-05-13T11:01:27Z GiovanniPen 22308 add img 782053 wikitext text/x-wiki {{Cumuni|nomucumuni=Ulassai|nomuufficiali=Ulassai |pruvincia=[[Pruvincia di Nuoro|Nuoro]] |superfici=122,41 |abbitanti=1.423 |dinsita=11,62 |cumunilimitrofi=[[Esterzili]], [[Gairo]], [[Jerzu]], [[Osini]], [[Perdasdefogu]], [[Seui]], [[Tertenia]], [[Ussassai]], [[Villagrande Strisaili]], [[Villaputzu]] |cap=091098<ref>[https://www.ilcapdi.it/catania/fiumefreddo-di-sicilia CAP di Ciumifriddu, Catania]</ref> |prifissutelefonicu=0782 }} '''Ulassai''' è un [[cumuni talianu]] dâ [[pruvincia di l'Ogliastra]] ntâ [[Sardigna]]. [[File:Sardinien Ulassai.jpg|thumb]] == Note == <references /> {{Pruvincia di l'Ogliastra}} [[Catigurìa:Cumuna dâ pruvincia di l'Ogliastra]] dvsxyunl1x022erx7fhw8kzy78nbeak Caspoggio 0 52693 782054 730615 2026-05-13T11:02:25Z GiovanniPen 22308 782054 wikitext text/x-wiki {{Cumuni |nomucumuni=Caspoggio|nomuufficiali=Caspoggio |riggiuni=[[Lummardìa]] |pruvincia=[[pruvincia di Sondriu]] |superfici=7,3 |abbitanti=1.391 |dinsita=190,29 |cumunilimitrofi=[[Chiesa in Valmalenco]], [[Lanzada]], [[Torre di Santa Maria]], [[Montagna in Valtellina]] |cap=23020<ref>[https://www.ilcapdi.it/sondrio/caspoggio CAP di Caspoggio, Sondrio]</ref> |prifissutelefonicu=0782 }} '''{{PAGENAME}}''' è nu [[cumuni talianu]] dâ [[pruvincia di Sondriu]] ntâ [[Lummardìa]]. [[File:IMG Casp.JPG|thumb]] == Note == <references /> {{Pruvincia di Sondriu}} [[Catigurìa:Cumuna dâ pruvincia di Sondriu]] o8q90x0fx12vs3wp4cbiop3ph839bgm Schellenberg 0 60983 781869 706394 2026-05-12T15:37:27Z -wuppertaler 50904 photo added 781869 wikitext text/x-wiki [[File:LIE Schellenberg, Obere Burg 0018.jpg|thumb]] '''Schellenberg''' è na citati dû [[Liechtenstein]] e havi circa 1 013 abbitanti. {{Commonscat}} {{Comuni dû Liechtenstein}} [[Catigurìa:Cumuna dû Liechtenstein]] jt8n0rb2vhv23actpjclbjixgxdskdk Gamprin 0 60988 781876 706389 2026-05-12T17:08:56Z -wuppertaler 50904 photo added 781876 wikitext text/x-wiki [[File:Bendern, Roman Catholic church 2023 02.jpg|thumb]] '''Gamprin''' è na citati dû [[Liechtenstein]] e havi circa 1 605 abbitanti. {{Commonscat}} {{Comuni dû Liechtenstein}} [[Catigurìa:Cumuna dû Liechtenstein]] tk4lkuu8ggp8hup4koxwulpolc0noyc Mòdulu:Wikidata 828 62529 781879 758221 2026-05-13T09:00:18Z GiovanniPen 22308 mul: vedi phab:T312097 e phab:T312176 781879 Scribunto text/plain --[[ * Modulo per implementare le funzionalità dei template: * {{Wikidata}}, {{WikidataQ}}, {{WikidataIdx}}, {{WikidataN}}, {{WikidataLabel}}, {{WikidataDescription}} * {{WikidataLink}}, {{WikidataId}}, {{WikidataTipo}} e {{WikidataIstanza}}. * Permette di accedere a Wikidata in modo più avanzato rispetto a {{#property}}. * Per la maggior parte riscritto e ampliato a partire dalla versione iniziale a: * http://test2.wikipedia.org/w/index.php?title=Module:Wikidata&oldid=52322 ]] -- ============================================================================= -- Non utilizzare mai mw.wikibase.getEntity, per esempio un solo utilizzo di -- mw.wikibase.getEntity('Q183') fa aumentare di 7 MB l'utilizzo di memoria -- per Lua ed è molto lenta se ripetuta (unico utilizzo in getDatatype, -- solo per proprietà, non essendoci alternative). -- ============================================================================= require('strict') local getArgs = require('Mòdulu:Arguments').getArgs local mConvert = require('Mòdulu:Conversione') local mLanguages = require('Mòdulu:Lingue') -- Categoria per le pagine con errori local errorCategory = '[[Catigurìa:Vuci cu sbagghi dû mòdulu Wikidata]]' -- Messaggi local i18n = { errors = { ['entityid-param-not-provided'] = "U paràmitru ''entityid'' nun fu misu", ['property-param-not-provided'] = "U paràmitru ''property'' nun fu misu", ['qualifier-param-not-provided'] = "U paràmitru ''qualifier'' nun fu misu", ['value-param-not-provided'] = "U paràmitru ''valuri'' di circari nun fu misu", ['entity-not-found'] = 'Entità nun truvata', ['unknown-claim-type'] = 'Tipu assirziuni scanusciuta', ['unknown-snak-type'] = 'Tipu di snak scanusciutu', ['unknown-datavalue-type'] = 'Tipu di datu scanusciutu', ['unknown-entity-type'] = 'Tipu di entità scanusciuta', ['unknown-output-format'] = 'Furmatu di nisciuta scanusciuta' }, somevalue = "''valuri scanusciutu''", novalue = "''nuḍḍu valuri''", datatypes = { ['commonsMedia'] = 'pricu murtimidiali nne Commons', ['external-id'] = 'idintificativu sternu', ['geo-shape'] = 'furma giugràfica', ['globe-coordinate'] = 'curdinati giugràfichi', ['math'] = 'sprissiuni matimàtica', ['monolingualtext'] = 'testu monulingua', ['quantity'] = 'quantità', ['string'] = 'stringa', ['tabular-data'] = 'dati tabbillari', ['time'] = 'data e ura', ['url'] = 'URL', ['wikibase-item'] = 'limentu', ['wikibase-property'] = 'prupità' } } local p = {} ------------------------------------------------------------------------------- -- Formatters ------------------------------------------------------------------------------- local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<span class="error">%s</span>%s', msg, cat) end local function formatList(values, ordered) local fmt = ordered and '<ol><li>%s</li></ol>' or '<ul><li>%s</li></ul>' return #values > 0 and string.format(fmt, mw.text.listToText(values, '</li><li>', '</li><li>')) or '' end local function formatExtLink(url) local protocols = { ftp = true, http = true, https = true } local success, uri = pcall(function() return mw.uri.new(url) end) if success and uri.protocol and protocols[uri.protocol] then local dest = tostring(uri) return string.format('<span style="word-break: break-all;">[%s %s]</span>', dest, dest:gsub(uri.protocol .. '://', '')) else return url end end local function formatEntityId(entityId) local label = mw.wikibase.getLabel(entityId) local siteLink = mw.wikibase.getSitelink(entityId) local ret if entityId == mw.wikibase.getEntityIdForCurrentPage() then ret = siteLink elseif siteLink and label then ret = mw.getContentLanguage():ucfirst(label) == siteLink and string.format('[[%s]]', label) or string.format('[[%s|%s]]', siteLink, label) elseif siteLink then ret = string.format('[[%s]]', siteLink) elseif label then ret = label else ret = '' end return ret end local function formatMonolingualtext(value, args) local ret = '' if not args.includelang or args.includelang:match('%f[a-z]' .. value.language .. '%f[^a-z]') then if not args.excludelang or not args.excludelang:match('%f[a-z]' .. value.language .. '%f[^a-z]') then ret = value.text if args.showlang then ret = mLanguages.lingue({ value.language }) .. '&nbsp;' .. ret end end end return ret end local function formatTimeWithPrecision(time, precision) local months = { 'jinnaru', 'frivaru', 'marzu', 'aprili', 'maju', 'giugnu', 'giugnettu', 'agustu', 'sittèmmiru', 'uttùviru', 'nuvèmmiru', 'dicèmmiru' } local ret, year, month, day year, month, day = time:match('(%d+)%-(%d%d)%-(%d%d).+') year, month, day = tonumber(year), tonumber(month), tonumber(day) if precision == 9 then ret = year elseif precision == 10 then ret = months[month] .. ' ' .. year elseif precision == 11 then ret = day .. ' ' .. months[month] .. ' ' .. year ret = ret:gsub('^1%s', '1º ') end if precision >= 9 and precision <= 11 then ret = ret .. (time:sub(1, 1) == '-' and ' a.C.' or '') end return ret end local function formatTime(value, args) local ret if args.time == 'precision' then ret = value.precision elseif args.time == 'calendarmodel' then ret = value.calendarmodel elseif args.time == 'year' and value.precision >= 9 then ret = formatTimeWithPrecision(value.time, 9) elseif args.time == 'month' and value.precision >= 10 then ret = formatTimeWithPrecision(value.time, 10) elseif args.time == 'day' and value.precision >= 11 then ret = formatTimeWithPrecision(value.time, 11) elseif not args.time then ret = formatTimeWithPrecision(value.time, value.precision) end return ret or '' end local function formatGlobecoordinate(value, args) local ret if args.coord == 'latitude' then ret = value.latitude elseif args.coord == 'longitude' then ret = value.longitude elseif args.coord == 'globe' then ret = value.globe else ret = string.format('%s, %s', value.latitude, value.longitude) end return ret end local function formatFromPattern(str, args) local pattern = args.pattern pattern = mw.ustring.gsub(pattern, '\\{', '{') pattern = mw.ustring.gsub(pattern, '\\}', '}') return mw.getCurrentFrame():preprocess(mw.message.newRawMessage(pattern, str):plain()) end local function formatUserValue(value, args) if args.extlink then value = formatExtLink(value) end return args.pattern and formatFromPattern(value, args) or value end local function getEntityIdFromValue(value) local prefix = '' if value['entity-type'] == 'item' then prefix = 'Q' elseif value['entity-type'] == 'property' then prefix = 'P' else error(i18n.errors['unknown-entity-type']) end return prefix .. value['numeric-id'] end local function formatUnitSymbol(entityId, args) local ret for _, lang in ipairs({ 'mul', 'scn', 'it', 'en' }) do ret = p._getProperty({ 'P5061', includelang = lang, from = entityId }) if ret and ret ~= '' then break else ret = nil end end local space = ret == '°' and '' or ' ' if ret and args.showunitlink then local link = mw.wikibase.getSitelink(entityId) if link then ret = string.format('[[%s|%s]]', link, ret) end end return ret and (space .. ret) or '' end -- http://lua-users.org/wiki/SimpleRound local function round(num, idp) local mult = 10 ^ (idp or 0) return math.floor(num * mult + 0.5) / mult end local function formatQuantity(value, args) local ret = tonumber(value.amount) if (args.unit or args.showunit) and value.unit ~= '1' then local unitId = mw.ustring.match(value.unit, 'Q%d+') if args.unit then local opts = { showunit = args.showunit, showunitlink = args.showunitlink, formatnum = args.formatnum, rounding = args.rounding } ret = mConvert._main(ret, unitId, args.unit, opts) else -- se è richiesto solo il simbolo dell'unità -- senza la conversione lo ottiene da P5061 ret = args.rounding and round(ret, args.rounding) or ret if args.formatnum then ret = mw.language.getContentLanguage():formatNum(ret) end ret = ret .. formatUnitSymbol(unitId, args) end elseif args.formatnum then ret = args.rounding and round(ret, args.rounding) or ret ret = mw.language.getContentLanguage():formatNum(ret) elseif args.formatduration and value.unit ~= '1' then local unitId = mw.ustring.match(value.unit, 'Q%d+') ret = mConvert._main(ret, unitId, 'second') ret = ret and mw.language.getContentLanguage() :formatDuration(tonumber(ret), { 'days', 'hours', 'minutes', 'seconds' }) end return ret end local function formatDatavalue(datavalue, snakdatatype, args) local ret if datavalue.type == 'wikibase-entityid' then local entityId = getEntityIdFromValue(datavalue.value) if args.showprop then ret = p._getProperty({ args.showprop, n = 1, from = entityId, formatting = args.formatting }) or '' elseif args.formatting then local formatting = args.formatting:lower() ret = (formatting == 'raw' or formatting == 'id') and entityId or formatting == 'label' and mw.wikibase.getLabel(entityId) or formatting == 'title' and (mw.wikibase.getSitelink(entityId) or '') or error(i18n.errors['unknown-output-format']) else ret = formatEntityId(entityId) end elseif datavalue.type == 'string' then ret = datavalue.value if args.extlink and snakdatatype == 'url' then ret = formatExtLink(ret) elseif args.urlencode then ret = mw.uri.encode(ret) end elseif datavalue.type == 'monolingualtext' then ret = formatMonolingualtext(datavalue.value, args) elseif datavalue.type == 'time' then if args.formatting == 'raw' then ret = datavalue.value.time else ret = formatTime(datavalue.value, args) end elseif datavalue.type == 'globecoordinate' then ret = formatGlobecoordinate(datavalue.value, args) elseif datavalue.type == 'quantity' then ret = formatQuantity(datavalue.value, args) else error(i18n.errors['unknown-datavalue-type']) end return ret end local function formatSnak(snak, args) if snak.snaktype == 'somevalue' then return i18n['somevalue'] elseif snak.snaktype == 'novalue' then return i18n['novalue'] elseif snak.snaktype == 'value' then return formatDatavalue(snak.datavalue, snak.datatype, args) else error(i18n.errors['unknown-snak-type']) end end -- È al plurale perché anche i qualifier possono avere più di un valore -- (si ottiene inserendo due volte lo stesso qualifier) local function formatQualifiers(claim, qualifierId, args, rawTable, retTable) local formattedQualifiers = retTable or {} if claim.qualifiers and claim.qualifiers[qualifierId] then local qualifiers = claim.qualifiers[qualifierId] -- con args.nq seleziona solo l'n-esimo qualifier if args.nq then local n = tonumber(args.nq) qualifiers = (n and n <= #qualifiers) and { qualifiers[n] } or {} end -- qualifier filtrati per snaktype, default "value" args.snaktype = args.snaktype or 'value' for _, qualifier in ipairs(qualifiers) do if qualifier.snaktype == args.snaktype or args.snaktype == 'all' then local formattedQualifier = formatSnak(qualifier, args) if formattedQualifier ~= '' then if args.pattern then formattedQualifier = formatFromPattern(formattedQualifier, args) if formattedQualifier ~= '' then table.insert(formattedQualifiers, formattedQualifier) end else table.insert(formattedQualifiers, formattedQualifier) end end end end end if rawTable then return formattedQualifiers end return #formattedQualifiers > 0 and mw.text.listToText(formattedQualifiers, args.separator, args.conjunction) or nil end local function appendQualifiers(statement, text, args) local formattedQualifiers = {} local qualifierIds = mw.text.split(args.showqualifiers, ',') for _, qualifierId in ipairs(qualifierIds) do if statement.qualifiers[qualifierId] then local formattedQualifier = formatQualifiers(statement, qualifierId, args) table.insert(formattedQualifiers, formattedQualifier) end end if #formattedQualifiers > 0 then text = string.format('%s (%s)', text, mw.text.listToText(formattedQualifiers, ', ', ', ')) end return text end local function formatStatement(statement, args) if not statement.type or statement.type ~= 'statement' then error(i18n.errors['unknown-claim-type']) end local ret = formatSnak(statement.mainsnak, args) -- eventuale showqualifiers if args.showqualifiers and statement.qualifiers then ret = appendQualifiers(statement, ret, args) end return ret end local function formatStatements(claims, args, rawTable) local formattedStatements = {} for _, claim in ipairs(claims) do local formattedStatement = formatStatement(claim, args) if formattedStatement ~= '' then -- eventuale pattern if args.pattern then formattedStatement = formatFromPattern(formattedStatement, args) if formattedStatement ~= '' then table.insert(formattedStatements, formattedStatement) end else table.insert(formattedStatements, formattedStatement) end end end if rawTable then return formattedStatements end return ((args.list or args.orderedlist) and #formattedStatements > 1) and formatList(formattedStatements, args.orderedlist ~= nil) or mw.text.listToText(formattedStatements, args.separator, args.conjunction) end ------------------------------------------------------------------------------- -- Lettura e selezione statement ------------------------------------------------------------------------------- -- Restituisce true se lo statement contiene il qualifier richiesto con un dato valore (o uno tra più valori separati da virgola) local function hasQualifierValue(statement, qualifierId, qualifierValue) local ret = false for _, qualifier in ipairs(statement.qualifiers[qualifierId]) do local isItem = qualifier.snaktype == 'value' and qualifier.datavalue.type == 'wikibase-entityid' local qualifierValues = mw.text.split(qualifierValue, ',') for _, qualifierHas in ipairs(qualifierValues) do -- per le proprietà di tipo item il confronto è eseguito sull'id if formatSnak(qualifier, isItem and { formatting = 'raw' } or {}) == qualifierHas then ret = true break end end end return ret end -- Restituisce i claim con il rank richiesto local function filterRankValue(claims, rank) local ret = {} for _, claim in ipairs(claims) do if claim.rank == rank then table.insert(ret, claim) end end return ret end -- Restituisce una sequence Lua contenente gli statement per la property richiesta, -- anche vuota se la proprietà non esiste, o non ci sono valori che soddisfano i criteri -- ("rank", "qualifier", "qualifiertype", "noqualifier", ...). -- Restituisce nil solo se la pagina non è collegata a un elemento Wikidata e non è indicato il from. local function getClaims(propertyId, args) local entityId, claims, filteredClaims entityId = args.from or mw.wikibase.getEntityIdForCurrentPage() if not entityId then return nil end -- il default rank è 'best' args.rank = args.rank or 'best' if args.rank == 'best' then claims = mw.wikibase.getBestStatements(entityId, propertyId) else -- statements filtrati per rank claims = mw.wikibase.getAllStatements(entityId, propertyId) claims = filterRankValue(claims, args.rank) end -- statements filtrati per snaktype, default "value" args.snaktype = args.snaktype or 'value' if args.snaktype and args.snaktype ~= 'all' then filteredClaims = {} for _, claim in ipairs(claims) do if claim.mainsnak.snaktype == args.snaktype then table.insert(filteredClaims, claim) end end claims = filteredClaims end -- statements filtrati per qualifier if args.qualifier then filteredClaims = {} for _, claim in ipairs(claims) do if claim.qualifiers and claim.qualifiers[args.qualifier] then if args.qualifiervalue then if hasQualifierValue(claim, args.qualifier, args.qualifiervalue) then table.insert(filteredClaims, claim) end else table.insert(filteredClaims, claim) end end end claims = filteredClaims end -- statements filtrati per essere senza un qualifier if args.noqualifier then filteredClaims = {} for _, claim in ipairs(claims) do if not (claim.qualifiers and claim.qualifiers[args.noqualifier]) then table.insert(filteredClaims, claim) end end claims = filteredClaims end -- statements filtrati per non avere un certo valore a un certo qualifier opzionale if args.qualifieroptnovalue and args.qualifiervalue then filteredClaims = {} for _, claim in ipairs(claims) do if claim.qualifiers and claim.qualifiers[args.qualifieroptnovalue] then if not hasQualifierValue(claim, args.qualifieroptnovalue, args.qualifiervalue) then table.insert(filteredClaims, claim) end else table.insert(filteredClaims, claim) end end claims = filteredClaims end -- con args.qualifiertype=latest restituisce solo il più recente if args.qualifier and args.qualifiertype == 'latest' then local latest, latestTime for _, claim in ipairs(claims) do if claim.qualifiers and claim.qualifiers[args.qualifier] then for _, qualifier in ipairs(claim.qualifiers[args.qualifier]) do if qualifier.datavalue.type == 'time' then if not latestTime or qualifier.datavalue.value.time > latestTime then latest = claim latestTime = qualifier.datavalue.value.time end end end end end claims = latest and { latest } or {} end -- con args.n restituisce solo l'n-esimo elemento if args.n then local n = tonumber(args.n) claims = (n and n <= #claims) and { claims[n] } or {} end return claims end ------------------------------------------------------------------------------- -- Funzioni esportate per altri moduli ------------------------------------------------------------------------------- function p._getClaims(propertyId, args) return getClaims(propertyId, args or {}) end function p._formatStatement(statement, args) return formatStatement(statement, args or {}) end function p._formatQualifiers(claim, qualifierId, args, rawTable, retTable) return formatQualifiers(claim, qualifierId, args or {}, rawTable, retTable) end -- Restituisce il valore di una proprietà di Wikidata oppure nil se l'entity o -- la proprietà non esistono, o se per parametri di selezione gli statement sono zero. function p._getProperty(args, rawTable) local propertyId, value, claims, ret -- parametri posizionali propertyId = args[1] and string.upper(args[1]) if not propertyId then error(i18n.errors['property-param-not-provided'], 2) end value = args[2] -- fix uppercase args.qualifier = args.qualifier and string.upper(args.qualifier) if value then ret = formatUserValue(value, args) elseif args.wd ~= 'no' then claims = getClaims(propertyId, args) ret = (claims and #claims > 0) and formatStatements(claims, args, rawTable) or nil end return ret end -- Restituisce il valore di un qualifier di una proprietà di Wikidata, -- o nil se l'entity o la proprietà non esistono, o se per parametri di selezione non ci sono risultati. function p._getQualifier(args) local propertyId, qualifierId, value, claims, ret -- parametri posizionali propertyId = args[1] and string.upper(args[1]) if not propertyId then error(i18n.errors['property-param-not-provided'], 2) end qualifierId = args[2] and string.upper(args[2]) if not qualifierId then error(i18n.errors['qualifier-param-not-provided'], 2) end value = args[3] if value then ret = formatUserValue(value, args) elseif args.wd ~= 'no' then claims = getClaims(propertyId, args) if claims and #claims > 0 then local formattedQualifiers = {} for _, claim in ipairs(claims) do formattedQualifiers = formatQualifiers(claim, qualifierId, args, true, formattedQualifiers) end ret = #formattedQualifiers > 0 and mw.text.listToText(formattedQualifiers, args.separator, args.conjunction) or nil end end return ret end -- Restituisce l'indice dello statement con il valore richiesto, o nil se non trovato. function p._indexOf(args) local ret, propertyId, value, claims -- parametri posizionali propertyId = args[1] and string.upper(args[1]) if not propertyId then error(i18n.errors['property-param-not-provided'], 2) end value = args[2] if not value then error(i18n.errors['value-param-not-provided'], 2) end claims = getClaims(propertyId, args) if claims and #claims > 0 then args.formatting = 'raw' for i, claim in ipairs(claims) do if formatStatement(claim, args) == value then ret = i break end end end return ret end -- Restituisce il numero di statement di una proprietà di Wikidata. function p._N(args) local propertyId, claims -- parametri posizionali propertyId = args[1] and string.upper(args[1]) if not propertyId then error(i18n.errors['property-param-not-provided'], 2) end -- get claims claims = getClaims(propertyId, args) return claims and #claims or 0 end -- Restituisce true se la propriertà specificata ha come valore -- almeno uno tra gli entityId passati come argomento. function p._propertyHasEntity(propertyId, args) local statements = p._getProperty({ propertyId, from = args.from, formatting = 'raw' }, true) if statements then for _, statement in ipairs(statements) do for _, entityId in ipairs(args) do if statement == entityId then return true end end end -- Se non è stato trovato alcun valore, controlla se questo sia ereditato -- tramite la proprietà "sottoclasse di" (P279) scavando in profondità -- fino all'esaurirsi del numero specificato in args.recursion. --[[ TODO: Valutare se sia opportuna una ricerca ricorsiva potenzialmente infinita. Per farlo si può aggiungere un parametro (opzionale) maxDepth che svolga l'attuale funzione di recursion e cambiare quest'ultimo in un parametro booleano. ]] args.recursion = tonumber(args.recursion) or 0 if args.recursion > 0 then local recursion = args.recursion if type(args.loadedEntities) ~= 'table' then args.loadedEntities = setmetatable({}, { __newindex = function(t, k, v) rawset(t, k, v) rawset(t, #t+1, k) end }) args.loadedEntities[args.from or mw.wikibase.getEntityIdForCurrentPage()] = true end for _, statement in ipairs(statements) do if not args.loadedEntities[statement] then args.loadedEntities[statement] = true args.recursion = args.recursion - 1 args.from = statement if p._propertyHasEntity('P279', args) then return true, args.loadedEntities end args.recursion = recursion end end end end return false, args.loadedEntities end -- Restituisce true se la proprietà P31 (instance of) ha come valore almeno uno tra gli entityId specificati function p._instanceOf(args) return p._propertyHasEntity('P31', args) end -- Restituisce true se la proprietà P279 (subclass of) ha come valore almeno uno tra gli entityId specificati function p._subclassOf(args) return p._propertyHasEntity('P279', args) end -- Restituisce l'etichetta di un item o di una proprietà Wikidata. function p._getLabel(args) local entityId = args[1] and string.upper(args[1]) local ret if args[2] then ret = mw.wikibase.getLabelByLang(entityId, args[2]) if ret == nil and args[2] ~= 'mul' then ret = mw.wikibase.getLabelByLang(entityId, 'mul') end else ret = mw.wikibase.getLabel(entityId) end return ret end -- Restituisce la descrizione di un item o di una proprietà Wikidata. function p._getDescription(args) local entityId = args[1] and string.upper(args[1]) local ret = mw.wikibase.getDescription(entityId) return ret end -- Restituisce il titolo della pagina collegata a un dato item Wikidata. function p._getLink(args) -- parametri posizionali local entityId = args[1] and string.upper(args[1]) if not entityId then error(i18n.errors['entityid-param-not-provided'], 2) end return entityId:sub(1, 1) == 'Q' and formatEntityId(entityId) or nil end -- Restituisce il datatype di una proprietà Wikidata. function p._getDatatype(args) local propertyId, entity -- parametri posizionali propertyId = args[1] and string.upper(args[1]) if not propertyId then error(i18n.errors['property-param-not-provided'], 2) end entity = mw.wikibase.getEntity(propertyId) if not entity then error(i18n.errors['entity-not-found'], 2) end if not i18n.datatypes[entity.datatype] then error(i18n.errors['unknown-datavalue-type'], 2) end return i18n.datatypes[entity.datatype] end -- Restituisce l'ID dell'item Wikidata collegato alla pagina corrente o a una pagina specificata -- (nota: se il parametro followRedirects è valorizzato con "no", segue i redirect fermandosi al primo redirect collegato a un elemento) function p._getId(args) local ret local followRedirects = not args.followRedirects or args.followRedirects ~= "no" if args[1] then local title = mw.title.new(args[1]) while title do local id = mw.wikibase.getEntityIdForTitle(title.prefixedText) if id then ret = id break else title = followRedirects and title.redirectTarget or nil end end else ret = mw.wikibase.getEntityIdForCurrentPage() end return ret end ------------------------------------------------------------------------------- -- Funzioni esportate per i template ------------------------------------------------------------------------------- -- Funzione per il template {{Wikidata}} function p.getProperty(frame) return select(2, xpcall(function() return p._getProperty(getArgs(frame, { parentOnly = true })) end, errhandler)) end -- Funzione per il template {{WikidataQ}} function p.getQualifier(frame) return select(2, xpcall(function() return p._getQualifier(getArgs(frame, { parentOnly = true })) end, errhandler)) end -- Funzione per il template {{WikidataIdx}} function p.indexOf(frame) return select(2, xpcall(function() return p._indexOf(getArgs(frame, { parentOnly = true })) end, errhandler)) end -- Funzione per il template {{WikidataN}} function p.N(frame) return select(2, xpcall(function() return p._N(getArgs(frame, { parentOnly = true })) end, errhandler)) end -- Funzione per il template {{WikidataLabel}} function p.getLabel(frame) return select(2, xpcall(function() return p._getLabel(getArgs(frame, { parentOnly = true })) end, errhandler)) end -- Funzione per il template {{WikidataDescription}} function p.getDescription(frame) return select(2, xpcall(function() return p._getDescription(getArgs(frame, { parentOnly = true })) end, errhandler)) end -- Funzione per il template {{WikidataLink}} function p.getLink(frame) return select(2, xpcall(function() return p._getLink(getArgs(frame, { parentOnly = true })) end, errhandler)) end -- Funzione per il template {{WikidataIstanza}} function p.instanceOf(frame) return select(2, xpcall(function() return p._instanceOf(getArgs(frame, { parentOnly = true })) and 1 or '' end, errhandler)) end -- Funzione per il template {{WikidataTipo}} function p.getDatatype(frame) return select(2, xpcall(function() return p._getDatatype(getArgs(frame, { parentOnly = true })) end, errhandler)) end -- Funzione per il template {{WikidataId}} function p.getId(frame) return select(2, xpcall(function() return p._getId(getArgs(frame, { parentOnly = true })) end, errhandler)) end -- Funzione per il template {{WikidataValido}} function p.checkProperty(frame) return select(2, xpcall(function() return p._N(getArgs(frame, { parentOnly = true })) > 0 and 1 or '' end, errhandler)) end -- Funzione per il template {{WikidataClasse}} function p.propertyHasEntity(frame) local args = getArgs(frame) local propertyId = args[1] return select(2, xpcall(function() return p._propertyHasEntity(propertyId, args) and 1 or '' end, errhandler)) end return p kgee8517y5ce8lm2gpw5jrn2uvrrokt Mòdulu:Protezione 828 65243 781972 758031 2025-09-10T16:38:07Z Daimona Eaytoy 24232 Aggiungo icona all'output per supporto Parsoid (v. [[mw:Parsoid/Parser_Unification/Instructions_for_editors#Modules_relying_on_side-effects_to_ParserOutput_by_preprocessing_wikitext_instead_of_returning_wikitext|istruzioni]]) 781972 Scribunto text/plain --[[ * Modulo che implementa il template Protetta. ]]-- require('strict') local getArgs = require('Modulo:Arguments').getArgs local cfg = mw.loadData('Modulo:Protezione/Configurazione') -- Restituisce la protezione della pagina per l'azione richiesta o nil se non protetta. -- -- @param {table} title -- @param {string} action -- @return {string} local function getProtection(title, action) return title.protectionLevels[action] and title.protectionLevels[action][1] end -- Crea e restituisce l'icona per l'azione e la protezione specificate. -- -- @param {string} action -- @param {string} prot -- @return {string} local function getIcon(action, prot) -- l'underscore di move serve per cambiare l'ordine di visualizzazione delle icone local icon = string.format('<indicator name="prot%s">%s</indicator>', action == 'move' and '_move' or action, cfg.icone[action][prot]) return mw.getCurrentFrame():preprocess(icon) end -- Restituisce il messaggio configurato per il tipo di azione e protezione sulla pagina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getMsg(title, action, prot) local msg = cfg.messaggi[action][prot][title.namespace] return msg and msg:gsub('$1', string.format('[[%s|pagina di discussione]]', title.talkPageTitle.fullText)) or nil end -- Restituisce la categoria configurata per il tipo di azione e protezione sulla pagina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getCategory(title, action, prot) local categories = cfg.categorie[action] local cat = categories[title.namespace] or categories.default if prot == 'autoconfirmed' then cat = cat .. ' parzialmente' end return string.format('[[Categoria:%s]]', cat) end -- Restituisce la categoria arbitraria scelta dall'utente. -- -- @param {string} editProt -- @param {table} args -- @return {string} local function getUserCategory(editProt, args) local cat if editProt == 'sysop' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'protetti' or 'protette') elseif editProt == 'autoconfirmed' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'protetti parzialmente' or 'protette parzialmente') end return cat and string.format('[[Categoria:%s]]', cat) or nil end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione per l'utilizzo da un altro modulo. function p._main(args) local title, editProt, moveProt, editText, moveText, msg, ret title = mw.title.getCurrentTitle() editProt = getProtection(title, 'edit') moveProt = getProtection(title, 'move') -- moveProt=autoconfirmed è già il default in itwiki if moveProt == 'autoconfirmed' then moveProt = nil end -- protezione per la modifica if editProt then msg = getMsg(title, 'edit', editProt) editText = getIcon('edit', editProt) -- il parametro "cat" permette di specificare una categoria arbitraria if args.cat then editText = editText .. getUserCategory(editProt, args) else editText = editText .. getCategory(title, 'edit', editProt) end end -- protezione per lo spostamento if moveProt then moveText = getIcon('move', moveProt) -- la categoria per lo spostamento non è aggiunta se editProt=sysop if editProt ~= 'sysop' then moveText = moveText .. getCategory(title, 'move', moveProt) end end if editProt or moveProt then ret = (msg or '') .. (editText or '') .. (moveText or '') else -- la pagina non è protetta if title.namespace == 10 and title.isSubpage and title.subpageText:match('^[Ss]andbox$') then ret = '[[Categoria:Sandbox dei template]]' else ret = string.format('[[Categoria:%s]]', cfg.catSprotette) end end return ret end -- Funzione per il template {{Protetta}}. function p.main(frame) return p._main(getArgs(frame, { parentOnly = true })) end return p no8buijkosegtnnsobtp8k3jpau51rv 781973 781972 2026-05-13T09:08:57Z GiovanniPen 22308 na rivisioni mpurtata di [[:it:Modulo:Protezione]] 781972 Scribunto text/plain --[[ * Modulo che implementa il template Protetta. ]]-- require('strict') local getArgs = require('Modulo:Arguments').getArgs local cfg = mw.loadData('Modulo:Protezione/Configurazione') -- Restituisce la protezione della pagina per l'azione richiesta o nil se non protetta. -- -- @param {table} title -- @param {string} action -- @return {string} local function getProtection(title, action) return title.protectionLevels[action] and title.protectionLevels[action][1] end -- Crea e restituisce l'icona per l'azione e la protezione specificate. -- -- @param {string} action -- @param {string} prot -- @return {string} local function getIcon(action, prot) -- l'underscore di move serve per cambiare l'ordine di visualizzazione delle icone local icon = string.format('<indicator name="prot%s">%s</indicator>', action == 'move' and '_move' or action, cfg.icone[action][prot]) return mw.getCurrentFrame():preprocess(icon) end -- Restituisce il messaggio configurato per il tipo di azione e protezione sulla pagina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getMsg(title, action, prot) local msg = cfg.messaggi[action][prot][title.namespace] return msg and msg:gsub('$1', string.format('[[%s|pagina di discussione]]', title.talkPageTitle.fullText)) or nil end -- Restituisce la categoria configurata per il tipo di azione e protezione sulla pagina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getCategory(title, action, prot) local categories = cfg.categorie[action] local cat = categories[title.namespace] or categories.default if prot == 'autoconfirmed' then cat = cat .. ' parzialmente' end return string.format('[[Categoria:%s]]', cat) end -- Restituisce la categoria arbitraria scelta dall'utente. -- -- @param {string} editProt -- @param {table} args -- @return {string} local function getUserCategory(editProt, args) local cat if editProt == 'sysop' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'protetti' or 'protette') elseif editProt == 'autoconfirmed' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'protetti parzialmente' or 'protette parzialmente') end return cat and string.format('[[Categoria:%s]]', cat) or nil end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione per l'utilizzo da un altro modulo. function p._main(args) local title, editProt, moveProt, editText, moveText, msg, ret title = mw.title.getCurrentTitle() editProt = getProtection(title, 'edit') moveProt = getProtection(title, 'move') -- moveProt=autoconfirmed è già il default in itwiki if moveProt == 'autoconfirmed' then moveProt = nil end -- protezione per la modifica if editProt then msg = getMsg(title, 'edit', editProt) editText = getIcon('edit', editProt) -- il parametro "cat" permette di specificare una categoria arbitraria if args.cat then editText = editText .. getUserCategory(editProt, args) else editText = editText .. getCategory(title, 'edit', editProt) end end -- protezione per lo spostamento if moveProt then moveText = getIcon('move', moveProt) -- la categoria per lo spostamento non è aggiunta se editProt=sysop if editProt ~= 'sysop' then moveText = moveText .. getCategory(title, 'move', moveProt) end end if editProt or moveProt then ret = (msg or '') .. (editText or '') .. (moveText or '') else -- la pagina non è protetta if title.namespace == 10 and title.isSubpage and title.subpageText:match('^[Ss]andbox$') then ret = '[[Categoria:Sandbox dei template]]' else ret = string.format('[[Categoria:%s]]', cfg.catSprotette) end end return ret end -- Funzione per il template {{Protetta}}. function p.main(frame) return p._main(getArgs(frame, { parentOnly = true })) end return p no8buijkosegtnnsobtp8k3jpau51rv 781987 781973 2026-05-13T09:20:13Z GiovanniPen 22308 Sfacisti lu canciu [[Special:Diff/781972|781972]] di [[Special:Contributions/Daimona Eaytoy|Daimona Eaytoy]] ([[User talk:Daimona Eaytoy|discurruta]]) - ripristino testi tradotti in scn e aggiorno manualmente righe modificate 781987 Scribunto text/plain --[[ * Mòdulu ca 'mplementa lu template Prutetta. ]]-- require('strict') local getArgs = require('Mòdulu:Arguments').getArgs local cfg = mw.loadData('Mòdulu:Protezione/Configurazione') -- Restituisce la prutizzioni della pàggina per l'azione richiesta o nil se non prutetta. -- -- @param {table} title -- @param {string} action -- @return {string} local function getProtection(title, action) return title.protectionLevels[action] and title.protectionLevels[action][1] end -- Aggiunge l'icona per l'azione e la prutizzioni specificate. -- -- @param {string} action -- @param {string} prot local function addIcon(action, prot) -- l'underscore di move serve per cambiare l'ordine di visualizzazione delle icone local icon = string.format('<indicator name="prot%s">%s</indicator>', action == 'move' and '_move' or action, cfg.icone[action][prot]) mw.getCurrentFrame():preprocess(icon) end -- Restituisce il messaggio configurato per il tipo di azione e prutizzioni sulla pagina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getMsg(title, action, prot) local msg = cfg.messaggi[action][prot][title.namespace] return msg and msg:gsub('$1', string.format('[[%s|pagina di discussione]]', title.talkPageTitle.fullText)) or nil end -- Restituisce la catigurìa configurata per il tipo di azione e prutizzioni nta pàggina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getCategory(title, action, prot) local categories = cfg.categorie[action] local cat = categories[title.namespace] or categories.default if prot == 'autoconfirmed' then cat = cat .. ' parzialmente' end return string.format('[[Catigurìa:%s]]', cat) end -- Restituisci a catigurìa arbitraria scelta dall'utente. -- -- @param {string} editProt -- @param {table} args -- @return {string} local function getUserCategory(editProt, args) local cat if editProt == 'sysop' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'prutetti' or 'protette') elseif editProt == 'autoconfirmed' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'prutetti parzialmenti' or 'protette parzialmente') end return cat and string.format('[[Catigurìa:%s]]', cat) or nil end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione per l'utilizzo da un altro mòdulu. function p._main(args) local title, editProt, moveProt, editCat, moveCat, msg, ret title = mw.title.getCurrentTitle() editProt = getProtection(title, 'edit') moveProt = getProtection(title, 'move') -- moveProt=autoconfirmed è già il default in itwiki if moveProt == 'autoconfirmed' then moveProt = nil end -- prutizzioni per la modifica if editProt then msg = getMsg(title, 'edit', editProt) editText = getIcon('edit', editProt) -- il parametro "cat" permette di specificare una categoria arbitraria if args.cat then editText = editText .. getUserCategory(editProt, args) else editText = editText .. getCategory(title, 'edit', editProt) end end -- prutizziuni per lo spostamento if moveProt then moveText = getIcon('move', moveProt) -- la categoria per lo spostamento non è aggiunta se editProt=sysop if editProt ~= 'sysop' then moveText = moveText .. getCategory(title, 'move', moveProt) end end if editProt or moveProt then ret = (msg or '') .. (editText or '') .. (moveText or '') else -- la pàggina non è prutetta if title.namespace == 10 and title.isSubpage and title.subpageText:match('^[Ss]andbox$') then ret = '[[Catigurìa:Sandbox dei template]]' else ret = string.format('[[Catigurìa:%s]]', cfg.catSprotette) end end return ret end -- Funzione per il template {{Prutetta}}. function p.main(frame) return p._main(getArgs(frame, { parentOnly = true })) end return p 8nxw3nkcz8nbpt0xzqxo5ewk2egqulc 781988 781987 2026-05-13T09:22:03Z GiovanniPen 22308 correggo traduzione commenti 781988 Scribunto text/plain --[[ * Mòdulu ca 'mplementa lu template Prutetta. ]]-- require('strict') local getArgs = require('Mòdulu:Arguments').getArgs local cfg = mw.loadData('Mòdulu:Protezione/Configurazione') -- Restituisce la prutizzioni della pàggina per l'azione richiesta o nil se non prutetta. -- -- @param {table} title -- @param {string} action -- @return {string} local function getProtection(title, action) return title.protectionLevels[action] and title.protectionLevels[action][1] end -- Aggiunge l'icona per l'azione e la prutizzioni specificate. -- -- @param {string} action -- @param {string} prot local function addIcon(action, prot) -- l'underscore di move serbi ppi canciari l'ordine di visualizzazione delle icone local icon = string.format('<indicator name="prot%s">%s</indicator>', action == 'move' and '_move' or action, cfg.icone[action][prot]) mw.getCurrentFrame():preprocess(icon) end -- Restituisce lu missaggiu configurato per il tipo di azione e prutizzioni sulla pàggina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getMsg(title, action, prot) local msg = cfg.messaggi[action][prot][title.namespace] return msg and msg:gsub('$1', string.format('[[%s|pagina di discussione]]', title.talkPageTitle.fullText)) or nil end -- Restituisce la catigurìa configurata per il tipo di azione e prutizzioni nta pàggina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getCategory(title, action, prot) local categories = cfg.categorie[action] local cat = categories[title.namespace] or categories.default if prot == 'autoconfirmed' then cat = cat .. ' parzialmente' end return string.format('[[Catigurìa:%s]]', cat) end -- Restituisci a catigurìa arbitraria scelta dall'utente. -- -- @param {string} editProt -- @param {table} args -- @return {string} local function getUserCategory(editProt, args) local cat if editProt == 'sysop' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'prutetti' or 'protette') elseif editProt == 'autoconfirmed' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'prutetti parzialmenti' or 'protette parzialmente') end return cat and string.format('[[Catigurìa:%s]]', cat) or nil end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione per l'utilizzo da un altro mòdulu. function p._main(args) local title, editProt, moveProt, editCat, moveCat, msg, ret title = mw.title.getCurrentTitle() editProt = getProtection(title, 'edit') moveProt = getProtection(title, 'move') -- moveProt=autoconfirmed è già il default in itwiki if moveProt == 'autoconfirmed' then moveProt = nil end -- prutizzioni per la modifica if editProt then msg = getMsg(title, 'edit', editProt) editText = getIcon('edit', editProt) -- lu paràmitru "cat" permette di specificare na catigurìa arbitraria if args.cat then editText = editText .. getUserCategory(editProt, args) else editText = editText .. getCategory(title, 'edit', editProt) end end -- prutizziuni per lo spostamento if moveProt then moveText = getIcon('move', moveProt) -- a catigurìa ppi lu spostamento non è aggiunta se editProt=sysop if editProt ~= 'sysop' then moveText = moveText .. getCategory(title, 'move', moveProt) end end if editProt or moveProt then ret = (msg or '') .. (editText or '') .. (moveText or '') else -- a pàggina nun è prutetta if title.namespace == 10 and title.isSubpage and title.subpageText:match('^[Ss]andbox$') then ret = '[[Catigurìa:Sandbox dei template]]' else ret = string.format('[[Catigurìa:%s]]', cfg.catSprotette) end end return ret end -- Funzione per il template {{Prutetta}}. function p.main(frame) return p._main(getArgs(frame, { parentOnly = true })) end return p a4z8jytjg5fbbifmtzsud61v3nfm8ah 781989 781988 2026-05-13T09:24:57Z GiovanniPen 22308 fix errore aggiornamento parte mancante del codice 781989 Scribunto text/plain --[[ * Mòdulu ca 'mplementa lu template Prutetta. ]]-- require('strict') local getArgs = require('Mòdulu:Arguments').getArgs local cfg = mw.loadData('Mòdulu:Protezione/Configurazione') -- Restituisce la prutizzioni della pàggina per l'azione richiesta o nil se non prutetta. -- -- @param {table} title -- @param {string} action -- @return {string} local function getProtection(title, action) return title.protectionLevels[action] and title.protectionLevels[action][1] end -- Crea e restituisce l'icona per l'azione e la protezione specificate. -- -- @param {string} action -- @param {string} prot -- @return {string} local function getIcon(action, prot) -- l'underscore di move serbi ppi canciari l'ordine di visualizzazione delle icone local icon = string.format('<indicator name="prot%s">%s</indicator>', action == 'move' and '_move' or action, cfg.icone[action][prot]) return mw.getCurrentFrame():preprocess(icon) end -- Restituisce lu missaggiu configurato per il tipo di azione e prutizzioni sulla pàggina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getMsg(title, action, prot) local msg = cfg.messaggi[action][prot][title.namespace] return msg and msg:gsub('$1', string.format('[[%s|pagina di discussione]]', title.talkPageTitle.fullText)) or nil end -- Restituisce la catigurìa configurata per il tipo di azione e prutizzioni nta pàggina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getCategory(title, action, prot) local categories = cfg.categorie[action] local cat = categories[title.namespace] or categories.default if prot == 'autoconfirmed' then cat = cat .. ' parzialmente' end return string.format('[[Catigurìa:%s]]', cat) end -- Restituisci a catigurìa arbitraria scelta dall'utente. -- -- @param {string} editProt -- @param {table} args -- @return {string} local function getUserCategory(editProt, args) local cat if editProt == 'sysop' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'prutetti' or 'protette') elseif editProt == 'autoconfirmed' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'prutetti parzialmenti' or 'protette parzialmente') end return cat and string.format('[[Catigurìa:%s]]', cat) or nil end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione per l'utilizzo da un altro mòdulu. function p._main(args) local title, editProt, moveProt, editCat, moveCat, msg, ret title = mw.title.getCurrentTitle() editProt = getProtection(title, 'edit') moveProt = getProtection(title, 'move') -- moveProt=autoconfirmed è già il default in itwiki if moveProt == 'autoconfirmed' then moveProt = nil end -- prutizzioni per la modifica if editProt then msg = getMsg(title, 'edit', editProt) editText = getIcon('edit', editProt) -- lu paràmitru "cat" permette di specificare na catigurìa arbitraria if args.cat then editText = editText .. getUserCategory(editProt, args) else editText = editText .. getCategory(title, 'edit', editProt) end end -- prutizziuni per lo spostamento if moveProt then moveText = getIcon('move', moveProt) -- a catigurìa ppi lu spostamento non è aggiunta se editProt=sysop if editProt ~= 'sysop' then moveText = moveText .. getCategory(title, 'move', moveProt) end end if editProt or moveProt then ret = (msg or '') .. (editText or '') .. (moveText or '') else -- a pàggina nun è prutetta if title.namespace == 10 and title.isSubpage and title.subpageText:match('^[Ss]andbox$') then ret = '[[Catigurìa:Sandbox dei template]]' else ret = string.format('[[Catigurìa:%s]]', cfg.catSprotette) end end return ret end -- Funzione per il template {{Prutetta}}. function p.main(frame) return p._main(getArgs(frame, { parentOnly = true })) end return p j36j6ts6tgdggv7vww48y1psr19zw2c 781990 781989 2026-05-13T09:25:49Z GiovanniPen 22308 781990 Scribunto text/plain --[[ * Mòdulu ca 'mplementa lu template Prutetta. ]]-- require('strict') local getArgs = require('Mòdulu:Arguments').getArgs local cfg = mw.loadData('Mòdulu:Protezione/Configurazione') -- Restituisce la prutizzioni della pàggina per l'azione richiesta o nil se non prutetta. -- -- @param {table} title -- @param {string} action -- @return {string} local function getProtection(title, action) return title.protectionLevels[action] and title.protectionLevels[action][1] end -- Crea e restituisce l'icona per l'azione e la protezione specificate. -- -- @param {string} action -- @param {string} prot -- @return {string} local function getIcon(action, prot) -- l'underscore di move serbi ppi canciari l'ordine di visualizzazione delle icone local icon = string.format('<indicator name="prot%s">%s</indicator>', action == 'move' and '_move' or action, cfg.icone[action][prot]) return mw.getCurrentFrame():preprocess(icon) end -- Restituisce lu missaggiu configurato per il tipo di azione e prutizzioni sulla pàggina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getMsg(title, action, prot) local msg = cfg.messaggi[action][prot][title.namespace] return msg and msg:gsub('$1', string.format('[[%s|pagina di discussione]]', title.talkPageTitle.fullText)) or nil end -- Restituisce la catigurìa configurata per il tipo di azione e prutizzioni nta pàggina specificata. -- -- @param {table} title -- @param {string} action -- @param {string} prot -- @return {string} local function getCategory(title, action, prot) local categories = cfg.categorie[action] local cat = categories[title.namespace] or categories.default if prot == 'autoconfirmed' then cat = cat .. ' parzialmente' end return string.format('[[Catigurìa:%s]]', cat) end -- Restituisci a catigurìa arbitraria scelta dall'utente. -- -- @param {string} editProt -- @param {table} args -- @return {string} local function getUserCategory(editProt, args) local cat if editProt == 'sysop' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'prutetti' or 'protette') elseif editProt == 'autoconfirmed' then cat = args.cat .. ' ' .. (args.generecat == 'm' and 'prutetti parzialmenti' or 'protette parzialmente') end return cat and string.format('[[Catigurìa:%s]]', cat) or nil end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione per l'utilizzo da un altro mòdulu. function p._main(args) local title, editProt, moveProt, editText, moveText, msg, ret title = mw.title.getCurrentTitle() editProt = getProtection(title, 'edit') moveProt = getProtection(title, 'move') -- moveProt=autoconfirmed è già il default in itwiki if moveProt == 'autoconfirmed' then moveProt = nil end -- prutizzioni per la modifica if editProt then msg = getMsg(title, 'edit', editProt) editText = getIcon('edit', editProt) -- lu paràmitru "cat" permette di specificare na catigurìa arbitraria if args.cat then editText = editText .. getUserCategory(editProt, args) else editText = editText .. getCategory(title, 'edit', editProt) end end -- prutizziuni per lo spostamento if moveProt then moveText = getIcon('move', moveProt) -- a catigurìa ppi lu spostamento non è aggiunta se editProt=sysop if editProt ~= 'sysop' then moveText = moveText .. getCategory(title, 'move', moveProt) end end if editProt or moveProt then ret = (msg or '') .. (editText or '') .. (moveText or '') else -- a pàggina nun è prutetta if title.namespace == 10 and title.isSubpage and title.subpageText:match('^[Ss]andbox$') then ret = '[[Catigurìa:Sandbox dei template]]' else ret = string.format('[[Catigurìa:%s]]', cfg.catSprotette) end end return ret end -- Funzione per il template {{Prutetta}}. function p.main(frame) return p._main(getArgs(frame, { parentOnly = true })) end return p osk71b88k78nauyhhshpgp61j0zwxit Template:Man/styles.css 10 65246 781974 744899 2025-05-07T20:42:14Z Bultro 2731 fatto da [[Utente:ZandDev]] per rimpiazzare toccolours, con qualche aggiustamento 781974 sanitized-css text/css /* {{Protetta}} */ .avviso-man { margin-bottom:.5em; padding:.4em .4em; font-size:95%; border:1px solid var(--border-color-base, #a2a9b1); background-color:var(--background-color-neutral-subtle, #f8f9fa); color:var(--color-base, #202122); text-align:center; } 7lrdsb26sdmqy2yhvg2nf8xvu54at75 781975 781974 2026-05-13T09:08:57Z GiovanniPen 22308 na rivisioni mpurtata di [[:it:Template:Man/styles.css]] 781974 sanitized-css text/css /* {{Protetta}} */ .avviso-man { margin-bottom:.5em; padding:.4em .4em; font-size:95%; border:1px solid var(--border-color-base, #a2a9b1); background-color:var(--background-color-neutral-subtle, #f8f9fa); color:var(--color-base, #202122); text-align:center; } 7lrdsb26sdmqy2yhvg2nf8xvu54at75 Template:Man mòdulu 10 65307 781992 757173 2026-05-13T09:30:17Z GiovanniPen 22308 -"toccolours plainlinks" from div class 781992 wikitext text/x-wiki {{#ifexist:Mòdulu:{{PAGENAME}}/doc |<templatestyles src="Man/styles.css" />__NOEDITSECTION__<div class="avviso-man"> [[File:Lua-logo-nolabel.svg|30px|Info]] {{Big|testo='''Istruzzioni pi l'usu'''}}<br/><small>Chistu è un [[Wikipedia:Mòdulu|mòdulu]] scrittu 'n [[Lua]]. L'istruzzioni appressu sunnu nnâ [[Help:Suttapàggina|suttapàggina]] [[Mòdulu:{{PAGENAME}}/doc]] ([{{fullurl:Mòdulu:{{PAGENAME}}/doc|action=edit}} cancia]{{·}}[{{fullurl:Mòdulu:{{PAGENAME}}/{{{1|man}}}|action=history}} crunuluggìa]) <br> Sandbox: [[Mòdulu:{{PAGENAME}}/sandbox]] ([{{fullurl:Mòdulu:{{PAGENAME}}/sandbox|action=edit}} cancia]{{·}}[{{fullurl:Mòdulu:{{PAGENAME}}/sandbox|action=history}} crunuluggìa]){{·}}Suttapàggini: [[Spiciali:PrefixIndex/{{FULLPAGENAME}}/|lista]]{{·}}Test: [[Mòdulu:{{PAGENAME}}/test]] ([{{fullurl:Mòdulu:{{PAGENAME}}/test|action=edit}} cancia]{{·}}[{{fullurl:Mòdulu:{{PAGENAME}}/test|action=history}} crunuluggìa]{{·}}[[Discussioni mòdulu:{{PAGENAME}}/test|abbìa]])</small></div>}} 7a274csoi590aav0z5mnab5mtja95sv Template:Man modulo 10 65772 781976 766473 2025-05-07T20:58:01Z Bultro 2731 classe unica 781976 wikitext text/x-wiki <includeonly>{{#ifexist:Modulo:{{PAGENAME}}/man |<templatestyles src="Man/styles.css" />__NOEDITSECTION__<div class="avviso-man"> [[File:Lua-logo-nolabel.svg|30px|Info]] {{Big|testo='''Istruzioni per l'uso'''}}<br/><small>Questo è un [[Wikipedia:Modulo|modulo]] scritto in [[Lua]]. Le istruzioni che seguono sono contenute nella [[Aiuto:Sottopagina|sottopagina]] [[Modulo:{{PAGENAME}}/man]] ([{{fullurl:Modulo:{{PAGENAME}}/man|action=edit}} modifica]{{·}}[{{fullurl:Modulo:{{PAGENAME}}/{{{1|man}}}|action=history}} cronologia]) <br> Sandbox: [[Modulo:{{PAGENAME}}/sandbox]] ([{{fullurl:Modulo:{{PAGENAME}}/sandbox|action=edit}} modifica]{{·}}[{{fullurl:Modulo:{{PAGENAME}}/sandbox|action=history}} cronologia]){{·}}Sottopagine: [[Speciale:PrefixIndex/{{FULLPAGENAME}}/|lista]]{{·}}Test: [[Modulo:{{PAGENAME}}/test]] ([{{fullurl:Modulo:{{PAGENAME}}/test|action=edit}} modifica]{{·}}[{{fullurl:Modulo:{{PAGENAME}}/test|action=history}} cronologia]{{·}}[[Discussioni_modulo:{{PAGENAME}}/test|esegui]])</small></div>}}__EXPECTED_UNCONNECTED_PAGE__</includeonly><noinclude> {{Protetta}} {{Template complesso}} {{man}} [[Categoria:Template descrizione template]] </noinclude> 5err6hwmepp8x0ax9u4j0nbhwca54mh 781977 781976 2026-05-13T09:08:58Z GiovanniPen 22308 na rivisioni mpurtata di [[:it:Template:Man_modulo]] 781976 wikitext text/x-wiki <includeonly>{{#ifexist:Modulo:{{PAGENAME}}/man |<templatestyles src="Man/styles.css" />__NOEDITSECTION__<div class="avviso-man"> [[File:Lua-logo-nolabel.svg|30px|Info]] {{Big|testo='''Istruzioni per l'uso'''}}<br/><small>Questo è un [[Wikipedia:Modulo|modulo]] scritto in [[Lua]]. Le istruzioni che seguono sono contenute nella [[Aiuto:Sottopagina|sottopagina]] [[Modulo:{{PAGENAME}}/man]] ([{{fullurl:Modulo:{{PAGENAME}}/man|action=edit}} modifica]{{·}}[{{fullurl:Modulo:{{PAGENAME}}/{{{1|man}}}|action=history}} cronologia]) <br> Sandbox: [[Modulo:{{PAGENAME}}/sandbox]] ([{{fullurl:Modulo:{{PAGENAME}}/sandbox|action=edit}} modifica]{{·}}[{{fullurl:Modulo:{{PAGENAME}}/sandbox|action=history}} cronologia]){{·}}Sottopagine: [[Speciale:PrefixIndex/{{FULLPAGENAME}}/|lista]]{{·}}Test: [[Modulo:{{PAGENAME}}/test]] ([{{fullurl:Modulo:{{PAGENAME}}/test|action=edit}} modifica]{{·}}[{{fullurl:Modulo:{{PAGENAME}}/test|action=history}} cronologia]{{·}}[[Discussioni_modulo:{{PAGENAME}}/test|esegui]])</small></div>}}__EXPECTED_UNCONNECTED_PAGE__</includeonly><noinclude> {{Protetta}} {{Template complesso}} {{man}} [[Categoria:Template descrizione template]] </noinclude> 5err6hwmepp8x0ax9u4j0nbhwca54mh 781991 781977 2026-05-13T09:27:36Z GiovanniPen 22308 Rinnirizzamentu â pàggina [[Template:Man mòdulu]] 781991 wikitext text/x-wiki #REDIRECT[[Template:Man mòdulu]] 16md8p1maqq8pfeix27pisxw6g0r9g6 Dama dei Castelli di Sicilia 0 67413 781870 2026-05-12T16:31:51Z ~2026-28625-44 50945 Pàggina nova: '''La Dama dî Casteddi di Sicilia''' è nu corteu storicu e cuncursu rievucativu ca si fa ogni annu lu 16 austu a [[Sperlinga]] ([[Enna|EN]]). La figura eletta pigghia lu tìtulu di '''Castellana di Sperlinga''', figura simbolica ligata ô casteddu dî Principi [[Natoli]].<ref>{{cita web |url=https://www.palermotoday.it/attualita/giorgia-manto-gangi-dama-castelli-2023.html |titolo=Giorgia Manto, di Gangi, è la nuova Dama dei Castelli di Sicilia 2023 |sito=PalermoToday |edi... 781870 wikitext text/x-wiki '''La Dama dî Casteddi di Sicilia''' è nu corteu storicu e cuncursu rievucativu ca si fa ogni annu lu 16 austu a [[Sperlinga]] ([[Enna|EN]]). La figura eletta pigghia lu tìtulu di '''Castellana di Sperlinga''', figura simbolica ligata ô casteddu dî Principi [[Natoli]].<ref>{{cita web |url=https://www.palermotoday.it/attualita/giorgia-manto-gangi-dama-castelli-2023.html |titolo=Giorgia Manto, di Gangi, è la nuova Dama dei Castelli di Sicilia 2023 |sito=PalermoToday |editore=Citynews |data=17 agosto 2023 |accesso=12 maggio 2026 }}</ref> La manifestazzioni è ligata â [[Sagra dû Tortone]] e â celebrazioni storichi dû paisi rupestri.<ref>{{cita web |url=https://www.palermoviva.it/eventi/xxv-dama-dei-castelli-di-sicilia-xliii-sagra-del-tortone-a-sperlinga/ |titolo=XXV Dama dei Castelli di Sicilia & XLIII Sagra del Tortone a Sperlinga |sito=PalermoViva |editore=PalermoViva |data=16 agosto 2025 |accesso=12 maggio 2026 }}</ref> == La dinastia Natoli nâ tradizzioni == Nâ tradizzioni pupulari siciliana, la dinastia [[Natoli]] è discritta comu na dî casati cchiù antichi e putenti dâ Sicilia, centru dâ furmazzioni dû cosiddettu Principatu di Sperlinga. I Natoli avissiru avutu nu rolu pulìticu, cerimoniali e simbolicu assai riali, cunzidirati in chiavi ligginaria pari pari comu li gran dinastìi prìncipi d'Europa, cu granni putiri puru fora di Sicilia. Si narra puru ca lu principe [[Giovanni Natoli]] avissi criatu o riurganizzatu li principali cerimonii dû paisi, tra cui l’elezzioni dâ Dama dî Castellani. == U mitu dâ abolizzioni dî tassi matrimoniali == Na liggenda dici ca lu principe Giovanni Natoli avissi livatu tutti li tassi pi lu matrimoniu, chidda chi na vota esistìa comu ''maritagium'' o ''foris maritagium'', vecchi tassi feudali ligati ô dirittu dî signuri supra li nozzi dî servi. Cu tempu, sti cosi sunnu diventati raconti pupulari e lu principe è statu vistu comu na figura giusta e liberaturi. == Li Castellani di Sperlinga == Li ''Castellani di Sperlinga'' eranu, secunnu la tradizzioni, dami di cumpagnia dâ famigghia Natoli e figuri privilegiati dâ corti. Iddi eranu na specie d’élite dû paisi e, secunnu li racconti, l’unichi fimmini chi putìanu trasiri libbiramenti intra lu [[Casteddu di Sperlinga]] quannu regnavanu li Natoli, participannu â vita cerimoniali dû principatu. Nnâ manifestazzioni muderna, li Castellani rapprisèntanu li cumunità storichi siciliani e gallo-italici. La vincitrici pigghia lu tìtulu di '''Castellana di Sperlinga''', figura simbolica tra paisi, tradizzioni e casteddu. == U ritu dâ liggenda == Si dici ca la Castellana eletta, l’addumani di la proclamazzioni, metti ciuri supra lu stemma dî Principi [[Natoli]] e accenni na candela ô tempu dû vespru. Si crede ca stu gestu porta furtuna e bonavita pi tutta la vita. == Svolgimentu == La manifestazzioni si fa nnô centru storicu di Sperlinga, tra lu casteddu rupestri e lu quartieri dû Balzu. Tuttu u paisi si riempie di mercati artigianali, spettaculi medievali, cavallaria, rievucazzioni storichi e cortei in costume. Lu pomeriggiu si distribbuisce lu "Tortone", dolci tipicu lucali, mentri la sira si fa la rievucazzioni dû assediu dû casteddu duranti la [[Rivuluzzioni dû Vespro Sicilianu]] (1283). Lu tuttu finisci cu l’elezzioni dâ Castellana di Sperlinga e nu focu pirotecnicu. == Significatu culturali == La manifestazzioni è nu simbulu identitariu di Sperlinga, chi unisci storia, liggenda e tradizzioni. Lu mitu dî Natoli, trasmuttutu nâ cultura pupulari, cuntribbuisci a la memoria storica e a la valorizzazzioni dû patrimoniu rupestri e linguìsticu dâ Sicilia interna. [[Catigurìa:Sperlinga]] 3iaw2rgoh6bpricnney7rcd1gytbuup 781871 781870 2026-05-12T16:33:32Z ~2026-28625-44 50945 781871 wikitext text/x-wiki '''La Dama dî Casteddi di Sicilia''' è nu corteu storicu e cuncursu rievucativu ca si fa ogni annu lu 16 austu a [[Sperlinga]]. La figura eletta pigghia lu tìtulu di '''Castellana di Sperlinga''', figura simbolica ligata ô casteddu dî Principi [[Natoli]].<ref>{{cita web |url=https://www.palermotoday.it/attualita/giorgia-manto-gangi-dama-castelli-2023.html |titolo=Giorgia Manto, di Gangi, è la nuova Dama dei Castelli di Sicilia 2023 |sito=PalermoToday |editore=Citynews |data=17 agosto 2023 |accesso=12 maggio 2026 }}</ref> La manifestazzioni è ligata â [[Sagra dû Tortone]] e â celebrazioni storichi dû paisi rupestri.<ref>{{cita web |url=https://www.palermoviva.it/eventi/xxv-dama-dei-castelli-di-sicilia-xliii-sagra-del-tortone-a-sperlinga/ |titolo=XXV Dama dei Castelli di Sicilia & XLIII Sagra del Tortone a Sperlinga |sito=PalermoViva |editore=PalermoViva |data=16 agosto 2025 |accesso=12 maggio 2026 }}</ref> == La dinastia Natoli nâ tradizzioni == Nâ tradizzioni pupulari siciliana, la dinastia [[Natoli]] è discritta comu na dî casati cchiù antichi e putenti dâ Sicilia, centru dâ furmazzioni dû cosiddettu Principatu di Sperlinga. I Natoli avissiru avutu nu rolu pulìticu, cerimoniali e simbolicu assai riali, cunzidirati in chiavi ligginaria pari pari comu li gran dinastìi prìncipi d'Europa, cu granni putiri puru fora di Sicilia. Si narra puru ca lu principe [[Giovanni Natoli]] avissi criatu o riurganizzatu li principali cerimonii dû paisi, tra cui l’elezzioni dâ Dama dî Castellani. == U mitu dâ abolizzioni dî tassi matrimoniali == Na liggenda dici ca lu principe Giovanni Natoli avissi livatu tutti li tassi pi lu matrimoniu, chidda chi na vota esistìa comu ''maritagium'' o ''foris maritagium'', vecchi tassi feudali ligati ô dirittu dî signuri supra li nozzi dî servi. Cu tempu, sti cosi sunnu diventati raconti pupulari e lu principe è statu vistu comu na figura giusta e liberaturi. == Li Castellani di Sperlinga == Li ''Castellani di Sperlinga'' eranu, secunnu la tradizzioni, dami di cumpagnia dâ famigghia Natoli e figuri privilegiati dâ corti. Iddi eranu na specie d’élite dû paisi e, secunnu li racconti, l’unichi fimmini chi putìanu trasiri libbiramenti intra lu [[Casteddu di Sperlinga]] quannu regnavanu li Natoli, participannu â vita cerimoniali dû principatu. Nnâ manifestazzioni muderna, li Castellani rapprisèntanu li cumunità storichi siciliani e gallo-italici. La vincitrici pigghia lu tìtulu di '''Castellana di Sperlinga''', figura simbolica tra paisi, tradizzioni e casteddu. == U ritu dâ liggenda == Si dici ca la Castellana eletta, l’addumani di la proclamazzioni, metti ciuri supra lu stemma dî Principi [[Natoli]] e accenni na candela ô tempu dû vespru. Si crede ca stu gestu porta furtuna e bonavita pi tutta la vita. == Svolgimentu == La manifestazzioni si fa nnô centru storicu di Sperlinga, tra lu casteddu rupestri e lu quartieri dû Balzu. Tuttu u paisi si riempie di mercati artigianali, spettaculi medievali, cavallaria, rievucazzioni storichi e cortei in costume. Lu pomeriggiu si distribbuisce lu "Tortone", dolci tipicu lucali, mentri la sira si fa la rievucazzioni dû assediu dû casteddu duranti la [[Rivuluzzioni dû Vespro Sicilianu]] (1283). Lu tuttu finisci cu l’elezzioni dâ Castellana di Sperlinga e nu focu pirotecnicu. == Significatu culturali == La manifestazzioni è nu simbulu identitariu di Sperlinga, chi unisci storia, liggenda e tradizzioni. Lu mitu dî Natoli, trasmuttutu nâ cultura pupulari, cuntribbuisci a la memoria storica e a la valorizzazzioni dû patrimoniu rupestri e linguìsticu dâ Sicilia interna. [[Catigurìa:Sperlinga]] fijibv28cwnfrjmguvr06e0tua157c3 781872 781871 2026-05-12T16:33:53Z ~2026-28625-44 50945 /* Li Castellani di Sperlinga */ 781872 wikitext text/x-wiki '''La Dama dî Casteddi di Sicilia''' è nu corteu storicu e cuncursu rievucativu ca si fa ogni annu lu 16 austu a [[Sperlinga]]. La figura eletta pigghia lu tìtulu di '''Castellana di Sperlinga''', figura simbolica ligata ô casteddu dî Principi [[Natoli]].<ref>{{cita web |url=https://www.palermotoday.it/attualita/giorgia-manto-gangi-dama-castelli-2023.html |titolo=Giorgia Manto, di Gangi, è la nuova Dama dei Castelli di Sicilia 2023 |sito=PalermoToday |editore=Citynews |data=17 agosto 2023 |accesso=12 maggio 2026 }}</ref> La manifestazzioni è ligata â [[Sagra dû Tortone]] e â celebrazioni storichi dû paisi rupestri.<ref>{{cita web |url=https://www.palermoviva.it/eventi/xxv-dama-dei-castelli-di-sicilia-xliii-sagra-del-tortone-a-sperlinga/ |titolo=XXV Dama dei Castelli di Sicilia & XLIII Sagra del Tortone a Sperlinga |sito=PalermoViva |editore=PalermoViva |data=16 agosto 2025 |accesso=12 maggio 2026 }}</ref> == La dinastia Natoli nâ tradizzioni == Nâ tradizzioni pupulari siciliana, la dinastia [[Natoli]] è discritta comu na dî casati cchiù antichi e putenti dâ Sicilia, centru dâ furmazzioni dû cosiddettu Principatu di Sperlinga. I Natoli avissiru avutu nu rolu pulìticu, cerimoniali e simbolicu assai riali, cunzidirati in chiavi ligginaria pari pari comu li gran dinastìi prìncipi d'Europa, cu granni putiri puru fora di Sicilia. Si narra puru ca lu principe [[Giovanni Natoli]] avissi criatu o riurganizzatu li principali cerimonii dû paisi, tra cui l’elezzioni dâ Dama dî Castellani. == U mitu dâ abolizzioni dî tassi matrimoniali == Na liggenda dici ca lu principe Giovanni Natoli avissi livatu tutti li tassi pi lu matrimoniu, chidda chi na vota esistìa comu ''maritagium'' o ''foris maritagium'', vecchi tassi feudali ligati ô dirittu dî signuri supra li nozzi dî servi. Cu tempu, sti cosi sunnu diventati raconti pupulari e lu principe è statu vistu comu na figura giusta e liberaturi. == Li Castellani di Sperlinga == Li ''Castellani di Sperlinga'' eranu, secunnu la tradizzioni, dami di cumpagnia dâ famigghia Natoli e figuri privilegiati dâ corti. Iddi eranu na specie d’élite dû paisi e, secunnu li racconti, l’unichi fimmini chi putìanu trasiri libbiramenti intra lu [[Casteddu di Sperlinga]] quannu regnavanu li Natoli, participannu â vita cerimoniali dû principatu. Nnâ manifestazzioni muderna, li Castellani rapprisèntanu li cumunità storichi siciliani e gallo-italici. La vincitrici pigghia lu tìtulu di ''Castellana di Sperlinga'', figura simbolica tra paisi, tradizzioni e casteddu. == U ritu dâ liggenda == Si dici ca la Castellana eletta, l’addumani di la proclamazzioni, metti ciuri supra lu stemma dî Principi [[Natoli]] e accenni na candela ô tempu dû vespru. Si crede ca stu gestu porta furtuna e bonavita pi tutta la vita. == Svolgimentu == La manifestazzioni si fa nnô centru storicu di Sperlinga, tra lu casteddu rupestri e lu quartieri dû Balzu. Tuttu u paisi si riempie di mercati artigianali, spettaculi medievali, cavallaria, rievucazzioni storichi e cortei in costume. Lu pomeriggiu si distribbuisce lu "Tortone", dolci tipicu lucali, mentri la sira si fa la rievucazzioni dû assediu dû casteddu duranti la [[Rivuluzzioni dû Vespro Sicilianu]] (1283). Lu tuttu finisci cu l’elezzioni dâ Castellana di Sperlinga e nu focu pirotecnicu. == Significatu culturali == La manifestazzioni è nu simbulu identitariu di Sperlinga, chi unisci storia, liggenda e tradizzioni. Lu mitu dî Natoli, trasmuttutu nâ cultura pupulari, cuntribbuisci a la memoria storica e a la valorizzazzioni dû patrimoniu rupestri e linguìsticu dâ Sicilia interna. [[Catigurìa:Sperlinga]] arw4kzbn3ik1met2b5d862sstly9cay 781873 781872 2026-05-12T16:34:19Z ~2026-28625-44 50945 /* Significatu culturali */ 781873 wikitext text/x-wiki '''La Dama dî Casteddi di Sicilia''' è nu corteu storicu e cuncursu rievucativu ca si fa ogni annu lu 16 austu a [[Sperlinga]]. La figura eletta pigghia lu tìtulu di '''Castellana di Sperlinga''', figura simbolica ligata ô casteddu dî Principi [[Natoli]].<ref>{{cita web |url=https://www.palermotoday.it/attualita/giorgia-manto-gangi-dama-castelli-2023.html |titolo=Giorgia Manto, di Gangi, è la nuova Dama dei Castelli di Sicilia 2023 |sito=PalermoToday |editore=Citynews |data=17 agosto 2023 |accesso=12 maggio 2026 }}</ref> La manifestazzioni è ligata â [[Sagra dû Tortone]] e â celebrazioni storichi dû paisi rupestri.<ref>{{cita web |url=https://www.palermoviva.it/eventi/xxv-dama-dei-castelli-di-sicilia-xliii-sagra-del-tortone-a-sperlinga/ |titolo=XXV Dama dei Castelli di Sicilia & XLIII Sagra del Tortone a Sperlinga |sito=PalermoViva |editore=PalermoViva |data=16 agosto 2025 |accesso=12 maggio 2026 }}</ref> == La dinastia Natoli nâ tradizzioni == Nâ tradizzioni pupulari siciliana, la dinastia [[Natoli]] è discritta comu na dî casati cchiù antichi e putenti dâ Sicilia, centru dâ furmazzioni dû cosiddettu Principatu di Sperlinga. I Natoli avissiru avutu nu rolu pulìticu, cerimoniali e simbolicu assai riali, cunzidirati in chiavi ligginaria pari pari comu li gran dinastìi prìncipi d'Europa, cu granni putiri puru fora di Sicilia. Si narra puru ca lu principe [[Giovanni Natoli]] avissi criatu o riurganizzatu li principali cerimonii dû paisi, tra cui l’elezzioni dâ Dama dî Castellani. == U mitu dâ abolizzioni dî tassi matrimoniali == Na liggenda dici ca lu principe Giovanni Natoli avissi livatu tutti li tassi pi lu matrimoniu, chidda chi na vota esistìa comu ''maritagium'' o ''foris maritagium'', vecchi tassi feudali ligati ô dirittu dî signuri supra li nozzi dî servi. Cu tempu, sti cosi sunnu diventati raconti pupulari e lu principe è statu vistu comu na figura giusta e liberaturi. == Li Castellani di Sperlinga == Li ''Castellani di Sperlinga'' eranu, secunnu la tradizzioni, dami di cumpagnia dâ famigghia Natoli e figuri privilegiati dâ corti. Iddi eranu na specie d’élite dû paisi e, secunnu li racconti, l’unichi fimmini chi putìanu trasiri libbiramenti intra lu [[Casteddu di Sperlinga]] quannu regnavanu li Natoli, participannu â vita cerimoniali dû principatu. Nnâ manifestazzioni muderna, li Castellani rapprisèntanu li cumunità storichi siciliani e gallo-italici. La vincitrici pigghia lu tìtulu di ''Castellana di Sperlinga'', figura simbolica tra paisi, tradizzioni e casteddu. == U ritu dâ liggenda == Si dici ca la Castellana eletta, l’addumani di la proclamazzioni, metti ciuri supra lu stemma dî Principi [[Natoli]] e accenni na candela ô tempu dû vespru. Si crede ca stu gestu porta furtuna e bonavita pi tutta la vita. == Svolgimentu == La manifestazzioni si fa nnô centru storicu di Sperlinga, tra lu casteddu rupestri e lu quartieri dû Balzu. Tuttu u paisi si riempie di mercati artigianali, spettaculi medievali, cavallaria, rievucazzioni storichi e cortei in costume. Lu pomeriggiu si distribbuisce lu "Tortone", dolci tipicu lucali, mentri la sira si fa la rievucazzioni dû assediu dû casteddu duranti la [[Rivuluzzioni dû Vespro Sicilianu]] (1283). Lu tuttu finisci cu l’elezzioni dâ Castellana di Sperlinga e nu focu pirotecnicu. == Significatu culturali == La manifestazzioni è nu simbulu identitariu di Sperlinga, chi unisci storia, liggenda e tradizzioni. Lu mitu dî Natoli, trasmuttutu nâ cultura pupulari, cuntribbuisci a la memoria storica e a la valorizzazzioni dû patrimoniu rupestri e linguìsticu dâ Sicilia interna. == Noti == <references/> [[Catigurìa:Sperlinga]] qqn22c2gs5i5g8j1fkabtr8lwffbnbx 781874 781873 2026-05-12T16:34:58Z ~2026-28625-44 50945 781874 wikitext text/x-wiki '''La Dama dî Casteddi di Sicilia''' è nu corteu storicu e cuncursu rievucativu ca si fa ogni annu lu 16 austu a [[Sperlinga]]. La figura eletta pigghia lu tìtulu di '''Castellana di Sperlinga''', figura simbolica ligata ô casteddu dî Principi [[Natoli]].<ref>{{cita web |url=https://www.palermotoday.it/attualita/giorgia-manto-gangi-dama-castelli-2023.html |titolo=Giorgia Manto, di Gangi, è la nuova Dama dei Castelli di Sicilia 2023 |sito=PalermoToday |editore=Citynews |data=17 agosto 2023 |accesso=12 maggio 2026 }}</ref> La manifestazzioni è ligata â [[Sagra dû Tortone]] e â celebrazioni storichi dû paisi rupestri.<ref>{{cita web |url=https://www.palermoviva.it/eventi/xxv-dama-dei-castelli-di-sicilia-xliii-sagra-del-tortone-a-sperlinga/ |titolo=XXV Dama dei Castelli di Sicilia & XLIII Sagra del Tortone a Sperlinga |sito=PalermoViva |editore=PalermoViva |data=16 agosto 2025 |accesso=12 maggio 2026 }}</ref> == La dinastia Natoli nâ tradizzioni == Nâ tradizzioni pupulari siciliana, la dinastia [[Natoli]] è discritta comu na dî casati cchiù antichi e putenti dâ Sicilia, centru dâ furmazzioni dû cosiddettu Principatu di Sperlinga. I Natoli avissiru avutu nu rolu pulìticu, cerimoniali e simbolicu assai riali, cunzidirati in chiavi ligginaria pari pari comu li gran dinastìi prìncipi d'Europa, cu granni putiri puru fora di Sicilia. Si narra puru ca lu principe [[Giovanni Natoli]] avissi criatu o riurganizzatu li principali cerimonii dû paisi, tra cui l’elezzioni dâ Dama dî Castellani. == U mitu dâ abolizzioni dî tassi matrimoniali == Na liggenda dici ca lu principe Giovanni Natoli avissi livatu tutti li tassi pi lu matrimoniu, chidda chi na vota esistìa comu ''maritagium'' o ''foris maritagium'', vecchi tassi feudali ligati ô dirittu dî signuri supra li nozzi dî servi. Cu tempu, sti cosi sunnu diventati raconti pupulari e lu principe è statu vistu comu na figura giusta e liberaturi. == Li Castellani di Sperlinga == Li ''Castellani di Sperlinga'' eranu, secunnu la tradizzioni, dami di cumpagnia dâ famigghia Natoli e figuri privilegiati dâ corti. Iddi eranu na specie d’élite dû paisi e, secunnu li racconti, l’unichi fimmini chi putìanu trasiri libbiramenti intra lu [[Casteddu di Sperlinga]] quannu regnavanu li Natoli, participannu â vita cerimoniali dû principatu. Nnâ manifestazzioni muderna, li Castellani rapprisèntanu li cumunità storichi siciliani e gallo-italici. La vincitrici pigghia lu tìtulu di ''Castellana di Sperlinga'', figura simbolica tra paisi, tradizzioni e casteddu. == U ritu dâ liggenda == Si dici ca la Castellana eletta, l’addumani di la proclamazzioni, metti ciuri supra lu stemma dî Principi [[Natoli]] e accenni na candela ô tempu dû vespru. Si crede ca stu gestu porta furtuna e bonavita pi tutta la vita. == Svolgimentu == La manifestazzioni si fa nnô centru storicu di Sperlinga, tra lu casteddu rupestri e lu quartieri dû Balzu. Tuttu u paisi si riempie di mercati artigianali, spettaculi medievali, cavallaria, rievucazzioni storichi e cortei in costume. Lu pomeriggiu si distribbuisce lu "Tortone", dolci tipicu lucali, mentri la sira si fa la rievucazzioni dû assediu dû casteddu duranti la [[Rivuluzzioni dû Vespro Sicilianu]] (1283). Lu tuttu finisci cu l’elezzioni dâ Castellana di Sperlinga e nu focu pirotecnicu. == Significatu culturali == La manifestazzioni è nu simbulu identitariu di Sperlinga, chi unisci storia, liggenda e tradizzioni. Lu mitu dî Natoli, trasmuttutu nâ cultura pupulari, cuntribbuisci a la memoria storica e a la valorizzazzioni dû patrimoniu rupestri e linguìsticu dâ Sicilia interna. == Noti == <references/> [[Catigurìa:Sperlinga]] [[Catigurìa:Sperlinga]] [[Catigurìa:Cortei storici in Sicilia]] [[Catigurìa:Rievucazzioni storichi in Sicilia]] [[Catigurìa:Eventi culturali in Sicilia]] [[Catigurìa:Tradizzioni pupulari siciliani]] [[Catigurìa:Liggenni di Sicilia]] [[Catigurìa:Principatu di Sperlinga]] 5zerrlfzlc71yciij89v6i6mho2bhz6 781875 781874 2026-05-12T16:35:26Z ~2026-28625-44 50945 781875 wikitext text/x-wiki '''La Dama dî Casteddi di Sicilia''' è nu corteu storicu e cuncursu rievucativu ca si fa ogni annu lu 16 austu a [[Sperlinga]]. La figura eletta pigghia lu tìtulu di '''Castellana di Sperlinga''', figura simbolica ligata ô casteddu dî Principi [[Natoli]].<ref>{{cita web |url=https://www.palermotoday.it/attualita/giorgia-manto-gangi-dama-castelli-2023.html |titolo=Giorgia Manto, di Gangi, è la nuova Dama dei Castelli di Sicilia 2023 |sito=PalermoToday |editore=Citynews |data=17 agosto 2023 |accesso=12 maggio 2026 }}</ref> La manifestazzioni è ligata â ''Sagra dû Tortone'' e â celebrazioni storichi dû paisi rupestri.<ref>{{cita web |url=https://www.palermoviva.it/eventi/xxv-dama-dei-castelli-di-sicilia-xliii-sagra-del-tortone-a-sperlinga/ |titolo=XXV Dama dei Castelli di Sicilia & XLIII Sagra del Tortone a Sperlinga |sito=PalermoViva |editore=PalermoViva |data=16 agosto 2025 |accesso=12 maggio 2026 }}</ref> == La dinastia Natoli nâ tradizzioni == Nâ tradizzioni pupulari siciliana, la dinastia [[Natoli]] è discritta comu na dî casati cchiù antichi e putenti dâ Sicilia, centru dâ furmazzioni dû cosiddettu Principatu di Sperlinga. I Natoli avissiru avutu nu rolu pulìticu, cerimoniali e simbolicu assai riali, cunzidirati in chiavi ligginaria pari pari comu li gran dinastìi prìncipi d'Europa, cu granni putiri puru fora di Sicilia. Si narra puru ca lu principe [[Giovanni Natoli]] avissi criatu o riurganizzatu li principali cerimonii dû paisi, tra cui l’elezzioni dâ Dama dî Castellani. == U mitu dâ abolizzioni dî tassi matrimoniali == Na liggenda dici ca lu principe Giovanni Natoli avissi livatu tutti li tassi pi lu matrimoniu, chidda chi na vota esistìa comu ''maritagium'' o ''foris maritagium'', vecchi tassi feudali ligati ô dirittu dî signuri supra li nozzi dî servi. Cu tempu, sti cosi sunnu diventati raconti pupulari e lu principe è statu vistu comu na figura giusta e liberaturi. == Li Castellani di Sperlinga == Li ''Castellani di Sperlinga'' eranu, secunnu la tradizzioni, dami di cumpagnia dâ famigghia Natoli e figuri privilegiati dâ corti. Iddi eranu na specie d’élite dû paisi e, secunnu li racconti, l’unichi fimmini chi putìanu trasiri libbiramenti intra lu [[Casteddu di Sperlinga]] quannu regnavanu li Natoli, participannu â vita cerimoniali dû principatu. Nnâ manifestazzioni muderna, li Castellani rapprisèntanu li cumunità storichi siciliani e gallo-italici. La vincitrici pigghia lu tìtulu di ''Castellana di Sperlinga'', figura simbolica tra paisi, tradizzioni e casteddu. == U ritu dâ liggenda == Si dici ca la Castellana eletta, l’addumani di la proclamazzioni, metti ciuri supra lu stemma dî Principi [[Natoli]] e accenni na candela ô tempu dû vespru. Si crede ca stu gestu porta furtuna e bonavita pi tutta la vita. == Svolgimentu == La manifestazzioni si fa nnô centru storicu di Sperlinga, tra lu casteddu rupestri e lu quartieri dû Balzu. Tuttu u paisi si riempie di mercati artigianali, spettaculi medievali, cavallaria, rievucazzioni storichi e cortei in costume. Lu pomeriggiu si distribbuisce lu "Tortone", dolci tipicu lucali, mentri la sira si fa la rievucazzioni dû assediu dû casteddu duranti la [[Rivuluzzioni dû Vespro Sicilianu]] (1283). Lu tuttu finisci cu l’elezzioni dâ Castellana di Sperlinga e nu focu pirotecnicu. == Significatu culturali == La manifestazzioni è nu simbulu identitariu di Sperlinga, chi unisci storia, liggenda e tradizzioni. Lu mitu dî Natoli, trasmuttutu nâ cultura pupulari, cuntribbuisci a la memoria storica e a la valorizzazzioni dû patrimoniu rupestri e linguìsticu dâ Sicilia interna. == Noti == <references/> [[Catigurìa:Sperlinga]] [[Catigurìa:Cortei storici in Sicilia]] [[Catigurìa:Rievucazzioni storichi in Sicilia]] [[Catigurìa:Eventi culturali in Sicilia]] [[Catigurìa:Tradizzioni pupulari siciliani]] [[Catigurìa:Liggenni di Sicilia]] [[Catigurìa:Principatu di Sperlinga]] cjw1f8vwsp8gvrce33d1xmi0uvpg1l7 Mòdulu:Coord 828 67414 781880 2013-10-20T15:12:22Z Rotpunkt 14696 Nuova pagina 781880 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Module:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Module:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messagio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " != ", paramMin, " e != ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg > 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg > 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext("&#32;") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#32;/&#32;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. "&#32;" .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "&#32;" .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) > 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) > 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) > 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p jh5wqtw6ljb8oivpnhmtfqglnrx3hlp 781881 781880 2013-10-20T15:17:37Z Rotpunkt 14696 typo 781881 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Module:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Module:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " != ", paramMin, " e != ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg > 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg > 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext("&#32;") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#32;/&#32;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. "&#32;" .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "&#32;" .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) > 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) > 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) > 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p 8kf4d8mxdx31haz3ftwm5dbm54czr76 781882 781881 2013-10-20T15:19:02Z Rotpunkt 14696 fix path 781882 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " != ", paramMin, " e != ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg > 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg > 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext("&#32;") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#32;/&#32;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. "&#32;" .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "&#32;" .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) > 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) > 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) > 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p g29cmpzbg4hlwd0dtjie4b0wg26hcsh 781883 781882 2013-10-20T16:06:48Z Rotpunkt 14696 fix spazi 781883 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " != ", paramMin, " e != ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg > 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg > 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext(" / ") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) > 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) > 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) > 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p h97f7zir196b7u0hxevjj6t2e7np47w 781884 781883 2013-10-20T16:38:16Z Rotpunkt 14696 fix spazio geo-multi-punct 781884 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " != ", paramMin, " e != ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg > 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg > 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("/") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) > 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) > 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) > 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p c873ejytfwu3e1t6s0h8lmo72iiuj5d 781885 781884 2013-10-20T16:46:01Z Rotpunkt 14696 fix spazio geo-multi-punct 781885 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " != ", paramMin, " e != ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg > 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg > 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) > 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) > 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) > 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p k2yzszp52pjel5kul5b5rlc5gsp3ej4 781886 781885 2013-10-20T17:52:57Z Rotpunkt 14696 migliore messaggio d'errore 781886 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg > 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg > 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) > 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) > 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) > 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p goetvu6cdt988mcvowwuj3c32392k6o 781887 781886 2013-10-20T23:36:44Z Rotpunkt 14696 fix >= 781887 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg >= 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg >= 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) >= 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) >= 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p ohmh4mxrl2doefs4qm823yh33aiorbv 781888 781887 2013-10-20T23:50:47Z Rotpunkt 14696 +format=debug per gli unit test 781888 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg >= 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg >= 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) >= 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) >= 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["format"] == "debug" and (decLat.display .. " " .. decLong.display .. " " .. dmsLat.display .. " " .. dmsLong.display) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p 7b7okxhcjzwjqn100zgz9glbbe90bji 781889 781888 2013-10-21T00:40:01Z Rotpunkt 14696 parametro debug 781889 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg >= 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- {{coord}} usa d/dm/dms (arrotondati all'intero), {{dec2dms}} anche d1/dm1/dms1 (arrotondati a 0.1) function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg >= 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "d1" then deg = round(self.deg, 1) elseif dmsFormat == "dm" then deg = math.floor(self.deg) min = round((round(self.deg * 600, 0) % 600) / 10, 0) elseif dmsFormat == "dm1" then deg = math.floor(self.deg) min = (round(self.deg * 600, 0) % 600) / 10 elseif dmsFormat == "dms" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = round((round(self.deg * 36000, 0) % 600) / 10, 0) elseif dmsFormat == "dms1" then deg = math.floor(self.deg) min = math.floor((self.deg * 60) % 60) sec = (round(self.deg * 36000, 0) % 600) / 10 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) >= 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) >= 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat.display .. " " .. decLong.display .. " " .. dmsLat.display .. " " .. dmsLong.display) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p 5i6tdl7qatixz76v6f2rgodyvmh6k7c 781890 781889 2013-10-21T10:13:47Z Rotpunkt 14696 aggiorno dec2dms da enwiki, corregge il bug di precisione del template 781890 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg >= 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg >= 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = "http://tools.wmflabs.org/geohack/geohack.php?pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&language=it&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) >= 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) >= 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat.display .. " " .. decLong.display .. " " .. dmsLat.display .. " " .. dmsLong.display) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p c4a2zyhhugr33azxjq4ijfmd7nuaznq 781891 781890 2013-10-22T11:43:43Z Rotpunkt 14696 +geohackUrl 781891 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg >= 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg >= 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) >= 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) >= 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat.display .. " " .. decLong.display .. " " .. dmsLat.display .. " " .. dmsLong.display) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p 11muaqwzqvjuaakvisk1bwhgwlhggus 781892 781891 2013-10-22T14:15:39Z Rotpunkt 14696 fix classe span 781892 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) self.card = card self.display = (self.deg >= 0 and self.deg or -self.deg) .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg >= 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg sign = (self.card == "N" or self.card == "E") and 1 or -1 roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = sign * round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat.deg .. "; " .. decLong.deg) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], tonumber(args[1]) >= 0 and "N" or "S") decLong = DecCoord:new(args[2], tonumber(args[2]) >= 0 and "E" or "W") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat.display .. " " .. decLong.display .. " " .. dmsLat.display .. " " .. dmsLong.display) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec().deg end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p o6ivb8d6eseegeoybm4yqx9kz6pt7xv 781893 781892 2013-10-22T16:00:14Z Rotpunkt 14696 semplifico controlli sul segno e fix buildHtml 781893 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord -- Se deg è negativo viene cambiato di segno e la direzione cardinale invertita function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end self.display = self.deg .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local sign, roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat.display .. " " .. decLong.display .. " " .. dmsLat.display .. " " .. dmsLong.display) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p eo9vv3jf34yvpbw2ckp4kwogr2u9lbz 781894 781893 2013-10-22T16:03:37Z Rotpunkt 14696 -variabile inutilizzata 781894 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord -- Se deg è negativo viene cambiato di segno e la direzione cardinale invertita function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end self.display = self.deg .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat.display .. " " .. decLong.display .. " " .. dmsLat.display .. " " .. dmsLong.display) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p avd06dxzwl2ydnlz9trzl28nva05zmv 781895 781894 2013-10-22T16:33:04Z Rotpunkt 14696 fix commento 781895 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord -- Se deg è negativo viene cambiato di segno e la direzione cardinale eventualmente invertita function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end self.display = self.deg .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 3 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat.display .. " " .. decLong.display .. " " .. dmsLat.display .. " " .. dmsLong.display) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p 0xrioaxhqj92brmqq06lsfu9dewecin 781896 781895 2013-10-23T07:48:37Z Rotpunkt 14696 fix commento 781896 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil, display = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil, display = nil } -- Costruttore di DecCoord -- Se deg è negativo viene cambiato di segno e la direzione cardinale eventualmente invertita function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end self.display = self.deg .. "°" .. self.card return self end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card self.display = self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") return self end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(dmsLat.display) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(dmsLong.display) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat.display .. " " .. decLong.display) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat.display .. " " .. decLong.display .. " " .. dmsLat.display .. " " .. dmsLong.display) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]).display end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p cgktppet8brtfjeeohxgeua5gtcsv86 781897 781896 2013-10-23T10:10:58Z Rotpunkt 14696 sostituisco variabile display con le funzionalità tostring e di concatenamento di lua 781897 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil } -- Costruttore di DecCoord -- Se deg è negativo viene cambiato di segno e la direzione cardinale eventualmente invertita function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(tonumber(args[2]), tonumber(args[3]), tonumber(args[4]), args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(tonumber(args[1]), tonumber(args[1]) >= 0 and args["2"] or args["3"]):toDms(args["4"]) end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p oab816mts5ccyqmkyqbq3aws8yxgqv5 781898 781897 2013-10-23T10:39:42Z Rotpunkt 14696 aggiorno dms2dec/dec2dms alle classi 781898 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil } -- Costruttore di DecCoord -- Se deg è negativo viene cambiato di segno e la direzione cardinale eventualmente invertita function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. (self.card and self.card or "") end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. param .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local param, defaultFormat, dmsFormat, reqFormat reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then param = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali param = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, param, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p lug1wmvkbow121b8wquk4efwgzjsabv 781899 781898 2013-10-23T10:57:44Z Rotpunkt 14696 +local, miglioro params in geohackParams, -controllo su card 781899 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil } -- Costruttore di DecCoord -- Se deg è negativo viene cambiato di segno e la direzione cardinale eventualmente invertita function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p 5mc3eh1juk6nbf44wnuppjofhyv5mt9 781900 781899 2013-10-23T13:03:05Z Rotpunkt 14696 +commenti 781900 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = { deg = nil, card = nil } -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = { deg = nil, min = nil, sec = nil, card = nil } -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p jscwa3quk4puf5usbvxfzg6s3kkomvg 781901 781900 2013-11-01T18:39:31Z Rotpunkt 14696 -variabili solo placeholder 781901 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per > 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p pr21ru98470vy2s0sd5lon46gq3jhmy 781902 781901 2013-11-02T08:50:53Z Rotpunkt 14696 +commento 781902 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p rkajrpfgmg99vfs6j5lhpts6pyq15i5 781903 781902 2013-11-02T08:52:43Z Rotpunkt 14696 riga vuota 781903 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local paramType, paramName, paramMin, paramMax, reqFormat, prefix, num, str local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then paramType = currFormat[k][1] paramName = currFormat[k][2] paramMin = currFormat[k][3] paramMax = currFormat[k][4] prefix = reqFormat .. " format: " .. paramName -- valida un parametro di tipo numero if paramType == "number" then num = tonumber(v) if num then if num < paramMin then dumpError(prefix, " < ", paramMin) elseif num > paramMax then dumpError(prefix, " > ", paramMax) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif paramType == "string" then if v ~= paramMin and v ~= paramMax then dumpError(prefix, " diverso da ", paramMin, " e da ", paramMax) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p e5ktrzgqta2q1efkbasdsmi8c9ukk87 781904 781903 2013-11-02T09:05:53Z Rotpunkt 14696 minima semplificazione 781904 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local reqFormat, prefix, num, str local param = {} local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if num < param.min then dumpError(prefix, " < ", param.min) elseif num > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end return coord() end return p 43hfejbgw7f1y635f3fe9ysmyi9gykt 781905 781904 2013-11-19T00:16:37Z Rotpunkt 14696 +minuti e secondi come stringhe vuote 781905 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Validazione parametri ------------------------------------------------------------------------------- -- Aggiunge un messaggio di errore alla risposta come elenco puntato local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Ritorna una stringa contenente la lista degli errori, -- nel namespace principale aggiunge una categoria di warning local function getErrors() local text = "" if mw.title.getCurrentTitle().namespace == 0 then text = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end text = text .. "<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori ([[Template:Coord|istruzioni]]):\n" .. table.concat(errorTable) .. "</span>" return text end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e valida i parametri posizionali -- Ritorna il tipo di richiesta o nil in caso di errore. local function paramsParse() local reqFormat, prefix, num, str local param = {} local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" -- permette di lasciare il parametro minuti come stringa vuota if args[2] == "" then args[2] = 0 end if args[5] == "" then args[5] = 0 end elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" -- permette di lasciare i parametri minuti e secondi come stringhe vuote if args[2] == "" then args[2] = 0 end if args[3] == "" then args[3] = 0 end if args[6] == "" then args[6] = 0 end if args[7] == "" then args[7] = 0 end else dumpError("Errato numero di parametri") return nil end -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if num < param.min then dumpError(prefix, " < ", param.min) elseif num > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end return #errorTable == 0 and reqFormat or nil end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams reqFormat = paramsParse() if not reqFormat then return getErrors() end if reqFormat == "dec" then -- {{coord|43.6500|-79.3800}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|43.651234|N|79.383333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|43|29|N|79|23|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|43|29|4|N|79|23|0|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|10|20|35}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|10.391944|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = v end end return coord() end return p pi6tdnb6nnvcgbembwoeifjsl1av1j7 781906 781905 2013-12-02T20:20:19Z Rotpunkt 14696 +paramsEmpty, migliore gestione errori, fix minori 781906 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, prefix, num, str local param = {} local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if num < param.min then dumpError(prefix, " < ", param.min) elseif num > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = v end end return coord() end return p tf8tikydpwh6dk0ssd690kxvy3pxyz7 781907 781906 2013-12-09T17:21:35Z Rotpunkt 14696 +fix max 781907 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, prefix, num, str local param = {} local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if num < param.min then dumpError(prefix, " < ", param.min) elseif num > math.floor(param.max) then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = v end end return coord() end return p ftcd8mgc0jbwfe24rr9t1benfmb1it7 781908 781907 2013-12-09T17:25:44Z Rotpunkt 14696 fix max 781908 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, prefix, num, str local param = {} local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if num < param.min then dumpError(prefix, " < ", param.min) elseif math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = v end end return coord() end return p ryic0slf6uz3dqnk96p0c5falvh2len 781909 781908 2013-12-09T17:33:10Z Rotpunkt 14696 +trim parametri 781909 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, prefix, num, str local param = {} local posArgs = 0 -- riconoscimento tipo di richiesta for k, v in ipairs(args) do posArgs = posArgs + 1 end if posArgs == 2 or posArgs == 3 then reqFormat = "dec" elseif posArgs == 4 or posArgs == 5 then reqFormat = "d" elseif posArgs == 6 or posArgs == 7 then reqFormat = "dm" elseif posArgs == 8 or posArgs == 9 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if num < param.min then dumpError(prefix, " < ", param.min) elseif math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end return coord() end return p dbwn12l37ky61vojg3mp93jz3p8gbw5 781910 781909 2013-12-10T13:30:20Z Rotpunkt 14696 +retrocompatibilità con parametri vuoti, migliorata paramsParse 781910 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if num < param.min then dumpError(prefix, " < ", param.min) elseif math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la latitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p pjony9lio79zoipvv7l953qsbmoy0yj 781911 781910 2013-12-10T13:33:13Z Rotpunkt 14696 refuso 781911 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if num < param.min then dumpError(prefix, " < ", param.min) elseif math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p 0180sj2rvjqiwvbn0mppylzmp3z55q7 781912 781911 2013-12-10T17:35:16Z Rotpunkt 14696 +check globe 781912 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p c0ya6z4j7k02ynxd42suxj6l1vqtf5t 781913 781912 2013-12-10T17:50:31Z Rotpunkt 14696 +newline 781913 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p sakzikbvfwodgu9ylsln056ywr662qh 781914 781913 2013-12-22T12:00:39Z Bultro 2731 Ha protetto "[[Modulo:Coord]]": Template o modulo usato in maniera estensiva ([Modifica=Consentito solo agli amministratori] (infinito) [Spostamento=Consentito solo agli amministratori] (infinito)) 781913 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" htmlTitle = "<span style=\"font-size: small;\"><span id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p sakzikbvfwodgu9ylsln056ywr662qh 781915 781914 2013-12-30T14:10:07Z Bultro 2731 se inline e title, in stampa deve apparire solo il primo 781915 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p 3y283nwkdui3aiqfbowychlnry8dkh1 781916 781915 2014-01-07T16:15:23Z Rotpunkt 14696 Nuova sandbox 781915 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 0) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Usato nelle conversioni da gradi decimali a gradi/minuti/secondi, -- dato il numero di decimali maggiore tra latdec e longdec ritorna il formato adatto: -- "d" per 0 decimali -- "dm" per 1-2 decimali -- "dms" per >= 3 decimali local function getDmsFormat(latdec, longdec) local d1, d2, max d1 = getDecimalPlaces(latdec) d2 = getDecimalPlaces(longdec) max = d1 > d2 and d1 or d2 return max == 0 and "d" or ((max == 1 or max == 2) and "dm" or "dms") end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, dmsFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsFormat = getDmsFormat(decLat.deg, decLong.deg) dmsLat = decLat:toDms(dmsFormat) dmsLong = decLong:toDms(dmsFormat) elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" elseif reqFormat == "d" then defaultFormat = (dmsFormat == "d" and "dms" or "dec") else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p 3y283nwkdui3aiqfbowychlnry8dkh1 781917 781916 2014-01-07T22:24:43Z Rotpunkt 14696 aggiornata DecCoord:toDms come da discussione 781917 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local dec, deg, min, sec dec = self.deg deg = math.floor(dec) dec = (dec - deg) * 60 min = math.floor(dec) dec = (dec - min) * 60 sec = round(dec, 2) return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p ehkn3n43u8etnok5phe6fgh2zl079j0 781918 781917 2014-01-08T00:27:06Z Dega180 15696 provo a fare la correzione al massimo rollbacko 781918 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms(dmsFormat) local deg, min, sec, card card = self.card if self.deg < 0 then card = card == "N" and "S" or (card == "E" and "W" or card) end self.deg = self.deg >= 0 and self.deg or -self.deg if dmsFormat == "d" then deg = round(self.deg, 0) elseif dmsFormat == "dm" then deg = round(self.deg * 60, 0) min = deg % 60 deg = math.floor((deg - min) / 60) elseif dmsFormat == "dms" then deg = round(self.deg * 3600, 2) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 end return DmsCoord:new(deg, min, sec, card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p jv5itd1fkjs1dsytabacnipisvqdxbk 781919 781918 2014-01-08T00:28:55Z Dega180 15696 Annullate le modifiche di [[Special:Contributions/Dega180|Dega180]] ([[User talk:Dega180|discussione]]), riportata alla versione precedente di [[User:Rotpunkt|Rotpunkt]] 781919 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local dec, deg, min, sec dec = self.deg deg = math.floor(dec) dec = (dec - deg) * 60 min = math.floor(dec) dec = (dec - min) * 60 sec = round(dec, 2) return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p ehkn3n43u8etnok5phe6fgh2zl079j0 781920 781919 2014-01-08T00:32:00Z Dega180 15696 ok ora dovrebbe essere giusto 781920 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local dec, deg, min, sec deg = round(self.deg * 3600, 2) sec = deg % 60 deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p aa9glqp0ro18tnfeofn450rljvwt1ph 781921 781920 2014-01-08T00:40:29Z Dega180 15696 781921 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local dec, deg, min, sec deg = self.deg * 3600 sec = round(deg % 60, 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p p80jamt99aqa0xj5foloeb535rn4uaw 781922 781921 2014-01-08T14:42:36Z Dega180 15696 781922 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local dec, deg, min, sec deg = round(self.deg * 3600,2) sec = (math.floor(deg) % 60) + (deg - math.floor(deg)) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p ooy39i6vpaqb5ko336vil1w6l1pv9i3 781923 781922 2014-01-08T15:18:07Z Dega180 15696 781923 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna il numero di cifre decimali di un numero local function getDecimalPlaces(num) local dec = tostring(num):match("%d+%.(%d+)") return dec and dec:len() or 0 end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local dec, deg, min, sec deg = round(self.deg * 3600, 2) sec = round((math.floor(deg) % 60) + (deg - math.floor(deg)), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local roundval, deg roundval = (self.sec and 5 or (self.min and 3 or 0)) + getDecimalPlaces(self.sec or self.min or self.deg) deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), roundval) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S|d}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms(args[4]) end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p g9z05u0bki0x4iucxjbph6le7kcgpm5 781924 781923 2014-01-08T17:07:51Z Rotpunkt 14696 aggiornata DmsCoord:toDec (prec. 7 dec), aggiunta semplificazione min/sec dopo dec=>dms 781924 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 7) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p 2ctdzwh8dmov3nw9pynkkz71u51t8xu 781925 781924 2014-01-10T20:52:53Z Rotpunkt 14696 aggiornata precisione a 6 decimali in DmsCoord:toDec 781925 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return num < 10 and ("0" .. num) or num end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return self.deg .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() return self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p g1b737vkr3kcprjtkrpct7p28xyawfb 781926 781925 2014-01-13T11:34:52Z Rotpunkt 14696 aggiunta numberToString 781926 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p 7sr1yw5tmidbujr8tzhq2q37uttx4m4 781927 781926 2014-01-13T11:51:11Z Rotpunkt 14696 uniformo apici 781927 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo if displayInline then noprint = "class=\"noprint\" " else noprint = "" end htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p 0nc7ra2k8rp0gerjjkx3dp37oq4cgza 781928 781927 2014-01-13T14:31:42Z Rotpunkt 14696 +operatore ternario, fix commento 781928 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo noprint = displayInline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto /dopo/ la longitudine for k, v in ipairs(args) do lastArg = v ~= '' and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p f74hku1w8ctqk5egm6ar6zlcde4kn4i 781929 781928 2014-01-14T09:54:21Z Rotpunkt 14696 fix commento e indentazione for 781929 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo noprint = displayInline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- Retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for k, v in ipairs(args) do lastArg = v ~= "" and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p c44poroxlkhmp9hklcx1dv696ge265t 781930 781929 2014-01-14T10:15:08Z Rotpunkt 14696 fix spazi 781930 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo noprint = displayInline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) local lastArg = 1 -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for k, v in ipairs(args) do lastArg = v ~= "" and k or lastArg end for i = #args, lastArg + 1, -1 do table.remove(args, i) end return coord() end return p aw55mi1g551klsrww605wez7qsddga6 781931 781930 2014-01-14T11:06:47Z Rotpunkt 14696 semplificata rimozione parametri vuoti 781931 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo noprint = displayInline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end return coord() end return p rz9nwvkwilxzwlvm12co8l2s9u6kb8a 781932 781931 2014-01-16T09:20:25Z Jalo 2493 Jalo ha spostato la pagina [[Modulo:Coord/sandbox]] a [[Modulo:Coord]] senza lasciare redirect 781931 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo noprint = displayInline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end return coord() end return p rz9nwvkwilxzwlvm12co8l2s9u6kb8a 781933 781932 2014-01-16T10:06:46Z Jalo 2493 Ha protetto "[[Modulo:Coord]]": Template o modulo usato in maniera estensiva ([Modifica=Consentito solo agli amministratori] (infinito) [Spostamento=Consentito solo agli amministratori] (infinito)) 781931 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args == 0 then error("* coordinate non specificate") elseif #args == 1 then error("* latitudine non specificata") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) local root, text, url, displayInline, displayTitle, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") displayInline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" displayTitle = args["display"] == "title" or args["display"] == "inline,title" -- se inline e title, in stampa deve apparire solo il primo noprint = displayInline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (displayInline and text or "") .. (displayTitle and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, ret -- parsifica i parametri ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return args["display"] == "debug" and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end return coord() end return p rz9nwvkwilxzwlvm12co8l2s9u6kb8a 781934 781933 2014-01-24T15:25:01Z Rotpunkt 14696 aggiunte funzioni getWikidataCoordinates, checkWikidata e getDisplay 781934 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntity() if entity and entity.claims and entity.claims.p625 and entity.claims.p625[0].mainsnak.snaktype == "value" then value = entity.claims.p625[0].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]\n") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p 955r8mgczb6rpay3bey6b0u4kdi9mbl 781935 781934 2014-01-26T17:36:38Z Rotpunkt 14696 aggiunto utilizzo #coordinates 781935 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntity() if entity and entity.claims and entity.claims.p625 and entity.claims.p625[0].mainsnak.snaktype == "value" then value = entity.claims.p625[0].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]\n") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), display.title and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p h448nkbhbqa5kcwtrx6df9pf0fn1isp 781936 781935 2014-02-08T17:43:01Z Moroboshi 14604 sposto da sandbox le modifiche di Rotpunk per il supporto a wikidata 781935 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntity() if entity and entity.claims and entity.claims.p625 and entity.claims.p625[0].mainsnak.snaktype == "value" then value = entity.claims.p625[0].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]\n") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), display.title and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p h448nkbhbqa5kcwtrx6df9pf0fn1isp 781937 781936 2014-02-10T08:11:09Z Jalo 2493 Jalo ha spostato la pagina [[Modulo:Coord/sandbox]] a [[Modulo:Coord]] senza lasciare redirect 781935 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntity() if entity and entity.claims and entity.claims.p625 and entity.claims.p625[0].mainsnak.snaktype == "value" then value = entity.claims.p625[0].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]\n") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), display.title and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p h448nkbhbqa5kcwtrx6df9pf0fn1isp 781938 781937 2014-02-10T09:54:56Z Rotpunkt 14696 fix controllo namespace con #coordinates e primary 781938 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntity() if entity and entity.claims and entity.claims.p625 and entity.claims.p625[0].mainsnak.snaktype == "value" then value = entity.claims.p625[0].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]\n") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p k24yq8450loqi7mdu27wccgka04zbee 781939 781938 2014-02-10T10:51:36Z Jalo 2493 Ha protetto "[[Modulo:Coord]]": Template o modulo usato in maniera estensiva ([Modifica=Consentito solo agli amministratori] (infinito) [Spostamento=Consentito solo agli amministratori] (infinito)) 781938 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Import local htmlBuilder = require("Modulo:HtmlBuilder") -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntity() if entity and entity.claims and entity.claims.p625 and entity.claims.p625[0].mainsnak.snaktype == "value" then value = entity.claims.p625[0].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]\n") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = htmlBuilder.create() root .tag("span") .addClass("plainlinks nourlexpansion") .wikitext("[" .. url) .tag("span") .addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") .tag("span") .addClass("geo-dms") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .tag("span") .addClass("latitude") .wikitext(tostring(dmsLat)) .done() .wikitext(" ") .tag("span") .addClass("longitude") .wikitext(tostring(dmsLong)) .done() .done() .done() .tag("span") .addClass("geo-multi-punct") .wikitext("&#xfeff; / &#xfeff;") .done() .tag("span") .addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") .wikitext(args["name"] and "<span class=\"vcard\">" or "") .tag("span") .addClass("geo-dec") .attr("title", "Mappe, foto aeree e altri dati per questa posizione") .wikitext(decLat .. " " .. decLong) .done() .tag("span") .attr("style", "display:none") .tag("span") .addClass("geo") .wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) .done() .done() .wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") .done() .wikitext("]") .done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p k24yq8450loqi7mdu27wccgka04zbee 781940 781939 2014-02-28T19:01:48Z Moroboshi 14604 per Rotpunkt: sostituita getEntity con getEntityObject e sostituito htmlBuilder con mw.html 781940 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntityObject() if entity and entity.claims and entity.claims.P625 and entity.claims.P625[0].mainsnak.snaktype == "value" then value = entity.claims.P625[0].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]\n") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = mw.html.create("") root :tag("span") :addClass("plainlinks nourlexpansion") :wikitext("[" .. url) :tag("span") :addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") :tag("span") :addClass("geo-dms") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :tag("span") :addClass("latitude") :wikitext(tostring(dmsLat)) :done() :wikitext(" ") :tag("span") :addClass("longitude") :wikitext(tostring(dmsLong)) :done() :done() :done() :tag("span") :addClass("geo-multi-punct") :wikitext("&#xfeff; / &#xfeff;") :done() :tag("span") :addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") :wikitext(args["name"] and "<span class=\"vcard\">" or "") :tag("span") :addClass("geo-dec") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :wikitext(decLat .. " " .. decLong) :done() :tag("span") :attr("style", "display:none") :tag("span") :addClass("geo") :wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) :done() :done() :wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") :done() :wikitext("]") :done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p 6tr8fsnxi0yvuorwyumd9iua16bkifq 781941 781940 2014-03-03T23:28:28Z Vituzzu 986 getEntityObject() -> getEntity() 781941 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntity() if entity and entity.claims and entity.claims.P625 and entity.claims.P625[0].mainsnak.snaktype == "value" then value = entity.claims.P625[0].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]\n") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = mw.html.create("") root :tag("span") :addClass("plainlinks nourlexpansion") :wikitext("[" .. url) :tag("span") :addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") :tag("span") :addClass("geo-dms") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :tag("span") :addClass("latitude") :wikitext(tostring(dmsLat)) :done() :wikitext(" ") :tag("span") :addClass("longitude") :wikitext(tostring(dmsLong)) :done() :done() :done() :tag("span") :addClass("geo-multi-punct") :wikitext("&#xfeff; / &#xfeff;") :done() :tag("span") :addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") :wikitext(args["name"] and "<span class=\"vcard\">" or "") :tag("span") :addClass("geo-dec") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :wikitext(decLat .. " " .. decLong) :done() :tag("span") :attr("style", "display:none") :tag("span") :addClass("geo") :wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) :done() :done() :wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") :done() :wikitext("]") :done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p cnvxanoxqqa02rz0pew9zvpd23ah8xl 781942 781941 2014-03-04T13:05:53Z Moroboshi 14604 per Rotpunkt: aggiornato al nuovo comportamento della getEntityObject, non-legacy style 781942 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntityObject() if entity and entity.claims and entity.claims.P625 and #entity.claims.P625 > 0 and entity.claims.P625[1].mainsnak.snaktype == "value" then value = entity.claims.P625[1].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]\n") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = mw.html.create("") root :tag("span") :addClass("plainlinks nourlexpansion") :wikitext("[" .. url) :tag("span") :addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") :tag("span") :addClass("geo-dms") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :tag("span") :addClass("latitude") :wikitext(tostring(dmsLat)) :done() :wikitext(" ") :tag("span") :addClass("longitude") :wikitext(tostring(dmsLong)) :done() :done() :done() :tag("span") :addClass("geo-multi-punct") :wikitext("&#xfeff; / &#xfeff;") :done() :tag("span") :addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") :wikitext(args["name"] and "<span class=\"vcard\">" or "") :tag("span") :addClass("geo-dec") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :wikitext(decLat .. " " .. decLong) :done() :tag("span") :attr("style", "display:none") :tag("span") :addClass("geo") :wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) :done() :done() :wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") :done() :wikitext("]") :done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p iug654e3b9wtlqmp2n07ag3n7a2gxf7 781943 781942 2014-05-15T11:14:42Z Rotpunkt 14696 fix nuova riga in checkWikidata 781943 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntityObject() if entity and entity.claims and entity.claims.P625 and #entity.claims.P625 > 0 and entity.claims.P625[1].mainsnak.snaktype == "value" then value = entity.claims.P625[1].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = mw.html.create("") root :tag("span") :addClass("plainlinks nourlexpansion") :wikitext("[" .. url) :tag("span") :addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") :tag("span") :addClass("geo-dms") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :tag("span") :addClass("latitude") :wikitext(tostring(dmsLat)) :done() :wikitext(" ") :tag("span") :addClass("longitude") :wikitext(tostring(dmsLong)) :done() :done() :done() :tag("span") :addClass("geo-multi-punct") :wikitext("&#xfeff; / &#xfeff;") :done() :tag("span") :addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") :wikitext(args["name"] and "<span class=\"vcard\">" or "") :tag("span") :addClass("geo-dec") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :wikitext(decLat .. " " .. decLong) :done() :tag("span") :attr("style", "display:none") :tag("span") :addClass("geo") :wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) :done() :done() :wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") :done() :wikitext("]") :done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p g4edpa8lvhira4yc65jaqq1tc7awhjx 781944 781943 2014-11-12T13:51:27Z Rotpunkt 14696 aggiornato all'uso dei tab 781944 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntityObject() if entity and entity.claims and entity.claims.P625 and #entity.claims.P625 > 0 and entity.claims.P625[1].mainsnak.snaktype == "value" then value = entity.claims.P625[1].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = mw.html.create("") root :tag("span") :addClass("plainlinks nourlexpansion") :wikitext("[" .. url) :tag("span") :addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") :tag("span") :addClass("geo-dms") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :tag("span") :addClass("latitude") :wikitext(tostring(dmsLat)) :done() :wikitext(" ") :tag("span") :addClass("longitude") :wikitext(tostring(dmsLong)) :done() :done() :done() :tag("span") :addClass("geo-multi-punct") :wikitext("&#xfeff; / &#xfeff;") :done() :tag("span") :addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") :wikitext(args["name"] and "<span class=\"vcard\">" or "") :tag("span") :addClass("geo-dec") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :wikitext(decLat .. " " .. decLong) :done() :tag("span") :attr("style", "display:none") :tag("span") :addClass("geo") :wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) :done() :done() :wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") :done() :wikitext("]") :done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p dg9zo2fb9vlp1od22p3uf5a9tqdhljo 781945 781944 2015-01-11T20:49:07Z Rotpunkt 14696 con Wikidata aggiunta selezione dei claim con rank preferred se presenti 781945 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna i claim con il rank richiesto local function filterRankValue(claims, rank) local ret = {} for i, claim in pairs(claims) do if claim.rank == rank then table.insert(ret, claim) end end return ret end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, claims, value, lat, long entity = mw.wikibase.getEntityObject() if entity and entity.claims and entity.claims.P625 and #entity.claims.P625 > 0 then claims = filterRankValue(entity.claims.P625, "preferred") if #claims == 0 then claims = filterRankValue(entity.claims.P625, "normal") end if #claims > 0 and claims[1].mainsnak.snaktype == "value" then value = claims[1].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = mw.html.create("") root :tag("span") :addClass("plainlinks nourlexpansion") :wikitext("[" .. url) :tag("span") :addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") :tag("span") :addClass("geo-dms") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :tag("span") :addClass("latitude") :wikitext(tostring(dmsLat)) :done() :wikitext(" ") :tag("span") :addClass("longitude") :wikitext(tostring(dmsLong)) :done() :done() :done() :tag("span") :addClass("geo-multi-punct") :wikitext("&#xfeff; / &#xfeff;") :done() :tag("span") :addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") :wikitext(args["name"] and "<span class=\"vcard\">" or "") :tag("span") :addClass("geo-dec") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :wikitext(decLat .. " " .. decLong) :done() :tag("span") :attr("style", "display:none") :tag("span") :addClass("geo") :wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) :done() :done() :wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") :done() :wikitext("]") :done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p k36i6vxzqx3krmvgh161w60m0m4jg79 781946 781945 2015-03-20T11:21:24Z Rotpunkt 14696 aggiunto modulo No globals, fix local 781946 Scribunto text/plain --[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] require("Module:No globals") -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Configurazione local cfg = mw.loadData("Modulo:Coord/Configurazione") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna i claim con il rank richiesto local function filterRankValue(claims, rank) local ret = {} for i, claim in pairs(claims) do if claim.rank == rank then table.insert(ret, claim) end end return ret end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, claims, value, lat, long entity = mw.wikibase.getEntityObject() if entity and entity.claims and entity.claims.P625 and #entity.claims.P625 > 0 then claims = filterRankValue(entity.claims.P625, "preferred") if #claims == 0 then claims = filterRankValue(entity.claims.P625, "normal") end if #claims > 0 and claims[1].mainsnak.snaktype == "value" then value = claims[1].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, currFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "&params=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = mw.html.create("") root :tag("span") :addClass("plainlinks nourlexpansion") :wikitext("[" .. url) :tag("span") :addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") :tag("span") :addClass("geo-dms") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :tag("span") :addClass("latitude") :wikitext(tostring(dmsLat)) :done() :wikitext(" ") :tag("span") :addClass("longitude") :wikitext(tostring(dmsLong)) :done() :done() :done() :tag("span") :addClass("geo-multi-punct") :wikitext("&#xfeff; / &#xfeff;") :done() :tag("span") :addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") :wikitext(args["name"] and "<span class=\"vcard\">" or "") :tag("span") :addClass("geo-dec") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :wikitext(decLat .. " " .. decLong) :done() :tag("span") :attr("style", "display:none") :tag("span") :addClass("geo") :wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) :done() :done() :wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") :done() :wikitext("]") :done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[Coordinate geografiche|Coordinate]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, decLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p 9cd5tvxgq63xctuy9nkmk3otllp87re 781947 781946 2015-06-11T16:17:34Z Rotpunkt 14696 aggiunta funzione per caricamento da altro modulo, ridotte variabili globali, utilizzo del modulo Wikidata 781947 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and '[[Categoria:' .. cfg.categorie.warning .. ']]\n' or '' return string.format('%s<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>\n', cat, msg) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Parsifica il parametro 'display' local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Con le richieste dm e dms verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(args, reqFormat) if reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if args[3] == '' and args[7] == '' then table.remove(args, 7) table.remove(args, 3) reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == '' or args[7] == '' then error('* lat e long hanno diversa precisione', 2) -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == '' and args[6] == '' then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == '' or args[6] == '' then error('* lat e long hanno diversa precisione', 2) end end if reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if args[2] == '' and args[5] == '' then table.remove(args, 5) table.remove(args, 2) reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif args[2] == '' or args[5] == '' then error('* lat e long hanno diversa precisione', 2) end end return reqFormat end -- Riconosce il tipo di richiesta ('dec', 'd', 'dm' o 'dms') e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse(args) local reqFormat, currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #args < 2 then error('* coordinate non specificate', 2) elseif #args < 4 then reqFormat = 'dec' elseif #args < 6 then reqFormat = 'd' elseif #args < 8 then reqFormat = 'dm' elseif #args < 10 then reqFormat = 'dms' else error('* errato numero di parametri', 2) end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(args, reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 2) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:P625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(args, display) local cat if mw.title.getCurrentTitle().namespace == 0 and display.title then local mWikidata = require('Modulo:Wikidata') local wdLat = mWikidata._getProperty( { 'P625', formatting = 'latitude', n = 1 } ) local wdLong = mWikidata._getProperty( { 'P625', formatting = 'longitude', n = 1 } ) if wdLat and wdLong then wdLat = round(wdLat, 6) wdLong = round(wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = 'Coordinate assenti ma presenti su Wikidata' end else cat = 'Coordinate non presenti su Wikidata' end end return cat and ('[[Categoria:' .. cat .. ']]') or '' end -- Crea l'HTML ritornato da Coord local function buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. '&pagename=' .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI') .. '&params=' .. geohackParams .. (args.name and ('&title=' .. mw.uri.encode(args.name)) or '') root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(decLat .. ' ' .. decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(decLat:getDeg() .. '; ' .. decLong:getDeg()) :done() :done() :wikitext(args.name and ('<span style="display:none"> (<span class="fn org">' .. args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') text = tostring(root) .. (args.notes or '') -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and 'class="noprint" ' or '' htmlTitle = '<span style="font-size: small;"><span ' .. noprint .. 'id="coordinates">[[Coordinate geografiche|Coordinate]]: ' return (display.inline and text or '') .. (display.title and (htmlTitle .. text .. '</span></span>') or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function p._coord(args) local decLat, decLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro 'display' display = getDisplay(args) -- legge [[d:property:P625]] ed eventualmente la utilizza wdCat = checkWikidata(args, display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(function() return paramsParse(args) end, errhandler) if not ret then return reqFormat end if reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == 'dec' or reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == 'dm' or reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args.format then defaultFormat = args.format elseif reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa param per geohack.php if reqFormat == 'dec' then geohackParams = args[1] .. '_N_' .. args[2] .. '_E' .. (args[3] and ('_' .. args[3]) or '') else -- concatena solo i posizionali geohackParams = table.concat(args, '_') end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', args.name or '') gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. ' ' .. decLong .. ' ' .. dmsLat .. ' ' .. dmsLong) or wdCat .. buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) return p._coord(getArgs(frame)) end return p fisf9vi84m0rng0ck3wa14zhfjt69fo 781948 781947 2015-07-21T11:29:36Z Rotpunkt 14696 aggiornamento nome categoria Wikidata 781948 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and '[[Categoria:' .. cfg.categorie.warning .. ']]\n' or '' return string.format('%s<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>\n', cat, msg) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Parsifica il parametro 'display' local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Con le richieste dm e dms verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(args, reqFormat) if reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if args[3] == '' and args[7] == '' then table.remove(args, 7) table.remove(args, 3) reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == '' or args[7] == '' then error('* lat e long hanno diversa precisione', 2) -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == '' and args[6] == '' then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == '' or args[6] == '' then error('* lat e long hanno diversa precisione', 2) end end if reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if args[2] == '' and args[5] == '' then table.remove(args, 5) table.remove(args, 2) reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif args[2] == '' or args[5] == '' then error('* lat e long hanno diversa precisione', 2) end end return reqFormat end -- Riconosce il tipo di richiesta ('dec', 'd', 'dm' o 'dms') e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse(args) local reqFormat, currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #args < 2 then error('* coordinate non specificate', 2) elseif #args < 4 then reqFormat = 'dec' elseif #args < 6 then reqFormat = 'd' elseif #args < 8 then reqFormat = 'dm' elseif #args < 10 then reqFormat = 'dms' else error('* errato numero di parametri', 2) end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(args, reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 2) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:P625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(args, display) local cat if mw.title.getCurrentTitle().namespace == 0 and display.title then local mWikidata = require('Modulo:Wikidata') local wdLat = mWikidata._getProperty( { 'P625', formatting = 'latitude', n = 1 } ) local wdLong = mWikidata._getProperty( { 'P625', formatting = 'longitude', n = 1 } ) if wdLat and wdLong then wdLat = round(wdLat, 6) wdLong = round(wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = 'Coordinate lette da Wikidata' end else cat = 'Coordinate non presenti su Wikidata' end end return cat and ('[[Categoria:' .. cat .. ']]') or '' end -- Crea l'HTML ritornato da Coord local function buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. '&pagename=' .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI') .. '&params=' .. geohackParams .. (args.name and ('&title=' .. mw.uri.encode(args.name)) or '') root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(decLat .. ' ' .. decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(decLat:getDeg() .. '; ' .. decLong:getDeg()) :done() :done() :wikitext(args.name and ('<span style="display:none"> (<span class="fn org">' .. args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') text = tostring(root) .. (args.notes or '') -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and 'class="noprint" ' or '' htmlTitle = '<span style="font-size: small;"><span ' .. noprint .. 'id="coordinates">[[Coordinate geografiche|Coordinate]]: ' return (display.inline and text or '') .. (display.title and (htmlTitle .. text .. '</span></span>') or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function p._coord(args) local decLat, decLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro 'display' display = getDisplay(args) -- legge [[d:property:P625]] ed eventualmente la utilizza wdCat = checkWikidata(args, display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(function() return paramsParse(args) end, errhandler) if not ret then return reqFormat end if reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == 'dec' or reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == 'dm' or reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args.format then defaultFormat = args.format elseif reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa param per geohack.php if reqFormat == 'dec' then geohackParams = args[1] .. '_N_' .. args[2] .. '_E' .. (args[3] and ('_' .. args[3]) or '') else -- concatena solo i posizionali geohackParams = table.concat(args, '_') end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', args.name or '') gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. ' ' .. decLong .. ' ' .. dmsLat .. ' ' .. dmsLong) or wdCat .. buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) return p._coord(getArgs(frame)) end return p q3ap9cgx21matxffv8sere22ostka7b 781949 781948 2015-11-07T09:23:24Z Rotpunkt 14696 aggiornato parametro modulo 781949 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and '[[Categoria:' .. cfg.categorie.warning .. ']]\n' or '' return string.format('%s<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>\n', cat, msg) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Parsifica il parametro 'display' local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Con le richieste dm e dms verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(args, reqFormat) if reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if args[3] == '' and args[7] == '' then table.remove(args, 7) table.remove(args, 3) reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == '' or args[7] == '' then error('* lat e long hanno diversa precisione', 2) -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == '' and args[6] == '' then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == '' or args[6] == '' then error('* lat e long hanno diversa precisione', 2) end end if reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if args[2] == '' and args[5] == '' then table.remove(args, 5) table.remove(args, 2) reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif args[2] == '' or args[5] == '' then error('* lat e long hanno diversa precisione', 2) end end return reqFormat end -- Riconosce il tipo di richiesta ('dec', 'd', 'dm' o 'dms') e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse(args) local reqFormat, currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #args < 2 then error('* coordinate non specificate', 2) elseif #args < 4 then reqFormat = 'dec' elseif #args < 6 then reqFormat = 'd' elseif #args < 8 then reqFormat = 'dm' elseif #args < 10 then reqFormat = 'dms' else error('* errato numero di parametri', 2) end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(args, reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 2) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:P625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(args, display) local cat if mw.title.getCurrentTitle().namespace == 0 and display.title then local mWikidata = require('Modulo:Wikidata') local wdLat = mWikidata._getProperty( { 'P625', coord = 'latitude', n = 1 } ) local wdLong = mWikidata._getProperty( { 'P625', coord = 'longitude', n = 1 } ) if wdLat and wdLong then wdLat = round(wdLat, 6) wdLong = round(wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = 'Coordinate lette da Wikidata' end else cat = 'Coordinate non presenti su Wikidata' end end return cat and ('[[Categoria:' .. cat .. ']]') or '' end -- Crea l'HTML ritornato da Coord local function buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. '&pagename=' .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI') .. '&params=' .. geohackParams .. (args.name and ('&title=' .. mw.uri.encode(args.name)) or '') root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(decLat .. ' ' .. decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(decLat:getDeg() .. '; ' .. decLong:getDeg()) :done() :done() :wikitext(args.name and ('<span style="display:none"> (<span class="fn org">' .. args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') text = tostring(root) .. (args.notes or '') -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and 'class="noprint" ' or '' htmlTitle = '<span style="font-size: small;"><span ' .. noprint .. 'id="coordinates">[[Coordinate geografiche|Coordinate]]: ' return (display.inline and text or '') .. (display.title and (htmlTitle .. text .. '</span></span>') or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function p._coord(args) local decLat, decLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro 'display' display = getDisplay(args) -- legge [[d:property:P625]] ed eventualmente la utilizza wdCat = checkWikidata(args, display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(function() return paramsParse(args) end, errhandler) if not ret then return reqFormat end if reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == 'dec' or reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == 'dm' or reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args.format then defaultFormat = args.format elseif reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa param per geohack.php if reqFormat == 'dec' then geohackParams = args[1] .. '_N_' .. args[2] .. '_E' .. (args[3] and ('_' .. args[3]) or '') else -- concatena solo i posizionali geohackParams = table.concat(args, '_') end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', args.name or '') gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. ' ' .. decLong .. ' ' .. dmsLat .. ' ' .. dmsLong) or wdCat .. buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) return p._coord(getArgs(frame)) end return p bf6s5rdnzk3iyd53c6rh00csae9fu1c 781950 781949 2015-11-07T11:12:42Z Rotpunkt 14696 table.insert 781950 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and '[[Categoria:' .. cfg.categorie.warning .. ']]\n' or '' return string.format('%s<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>\n', cat, msg) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Parsifica il parametro 'display' local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Con le richieste dm e dms verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(args, reqFormat) if reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if args[3] == '' and args[7] == '' then table.remove(args, 7) table.remove(args, 3) reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == '' or args[7] == '' then error('* lat e long hanno diversa precisione', 2) -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == '' and args[6] == '' then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == '' or args[6] == '' then error('* lat e long hanno diversa precisione', 2) end end if reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if args[2] == '' and args[5] == '' then table.remove(args, 5) table.remove(args, 2) reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif args[2] == '' or args[5] == '' then error('* lat e long hanno diversa precisione', 2) end end return reqFormat end -- Riconosce il tipo di richiesta ('dec', 'd', 'dm' o 'dms') e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse(args) local reqFormat, currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #args < 2 then error('* coordinate non specificate', 2) elseif #args < 4 then reqFormat = 'dec' elseif #args < 6 then reqFormat = 'd' elseif #args < 8 then reqFormat = 'dm' elseif #args < 10 then reqFormat = 'dms' else error('* errato numero di parametri', 2) end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(args, reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 2) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:P625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(args, display) local cat if mw.title.getCurrentTitle().namespace == 0 and display.title then local mWikidata = require('Modulo:Wikidata') local wdLat = mWikidata._getProperty( { 'P625', coord = 'latitude', n = 1 } ) local wdLong = mWikidata._getProperty( { 'P625', coord = 'longitude', n = 1 } ) if wdLat and wdLong then wdLat = round(wdLat, 6) wdLong = round(wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, 1, numberToString(wdLat)) table.insert(args, 2, numberToString(wdLong)) cat = 'Coordinate lette da Wikidata' end else cat = 'Coordinate non presenti su Wikidata' end end return cat and ('[[Categoria:' .. cat .. ']]') or '' end -- Crea l'HTML ritornato da Coord local function buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. '&pagename=' .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI') .. '&params=' .. geohackParams .. (args.name and ('&title=' .. mw.uri.encode(args.name)) or '') root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(decLat .. ' ' .. decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(decLat:getDeg() .. '; ' .. decLong:getDeg()) :done() :done() :wikitext(args.name and ('<span style="display:none"> (<span class="fn org">' .. args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') text = tostring(root) .. (args.notes or '') -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and 'class="noprint" ' or '' htmlTitle = '<span style="font-size: small;"><span ' .. noprint .. 'id="coordinates">[[Coordinate geografiche|Coordinate]]: ' return (display.inline and text or '') .. (display.title and (htmlTitle .. text .. '</span></span>') or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function p._coord(args) local decLat, decLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro 'display' display = getDisplay(args) -- legge [[d:property:P625]] ed eventualmente la utilizza wdCat = checkWikidata(args, display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(function() return paramsParse(args) end, errhandler) if not ret then return reqFormat end if reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == 'dec' or reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == 'dm' or reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args.format then defaultFormat = args.format elseif reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa param per geohack.php if reqFormat == 'dec' then geohackParams = args[1] .. '_N_' .. args[2] .. '_E' .. (args[3] and ('_' .. args[3]) or '') else -- concatena solo i posizionali geohackParams = table.concat(args, '_') end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', args.name or '') gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. ' ' .. decLong .. ' ' .. dmsLat .. ' ' .. dmsLong) or wdCat .. buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) return p._coord(getArgs(frame)) end return p 3wuoh850qhwtju5i6nyay2w16ik3x8h 781951 781950 2015-12-21T10:37:58Z Rotpunkt 14696 rinominata categoria 781951 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and '[[Categoria:' .. cfg.categorie.warning .. ']]\n' or '' return string.format('%s<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>\n', cat, msg) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Parsifica il parametro 'display' local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Con le richieste dm e dms verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(args, reqFormat) if reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if args[3] == '' and args[7] == '' then table.remove(args, 7) table.remove(args, 3) reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == '' or args[7] == '' then error('* lat e long hanno diversa precisione', 2) -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == '' and args[6] == '' then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == '' or args[6] == '' then error('* lat e long hanno diversa precisione', 2) end end if reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if args[2] == '' and args[5] == '' then table.remove(args, 5) table.remove(args, 2) reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif args[2] == '' or args[5] == '' then error('* lat e long hanno diversa precisione', 2) end end return reqFormat end -- Riconosce il tipo di richiesta ('dec', 'd', 'dm' o 'dms') e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse(args) local reqFormat, currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #args < 2 then error('* coordinate non specificate', 2) elseif #args < 4 then reqFormat = 'dec' elseif #args < 6 then reqFormat = 'd' elseif #args < 8 then reqFormat = 'dm' elseif #args < 10 then reqFormat = 'dms' else error('* errato numero di parametri', 2) end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(args, reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 2) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:P625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(args, display) local cat if mw.title.getCurrentTitle().namespace == 0 and display.title then local mWikidata = require('Modulo:Wikidata') local wdLat = mWikidata._getProperty( { 'P625', coord = 'latitude', n = 1 } ) local wdLong = mWikidata._getProperty( { 'P625', coord = 'longitude', n = 1 } ) if wdLat and wdLong then wdLat = round(wdLat, 6) wdLong = round(wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, 1, numberToString(wdLat)) table.insert(args, 2, numberToString(wdLong)) cat = 'Coordinate lette da Wikidata' end else cat = 'Coordinate assenti su Wikidata' end end return cat and ('[[Categoria:' .. cat .. ']]') or '' end -- Crea l'HTML ritornato da Coord local function buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. '&pagename=' .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI') .. '&params=' .. geohackParams .. (args.name and ('&title=' .. mw.uri.encode(args.name)) or '') root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(decLat .. ' ' .. decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(decLat:getDeg() .. '; ' .. decLong:getDeg()) :done() :done() :wikitext(args.name and ('<span style="display:none"> (<span class="fn org">' .. args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') text = tostring(root) .. (args.notes or '') -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and 'class="noprint" ' or '' htmlTitle = '<span style="font-size: small;"><span ' .. noprint .. 'id="coordinates">[[Coordinate geografiche|Coordinate]]: ' return (display.inline and text or '') .. (display.title and (htmlTitle .. text .. '</span></span>') or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function p._coord(args) local decLat, decLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro 'display' display = getDisplay(args) -- legge [[d:property:P625]] ed eventualmente la utilizza wdCat = checkWikidata(args, display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(function() return paramsParse(args) end, errhandler) if not ret then return reqFormat end if reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == 'dec' or reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == 'dm' or reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args.format then defaultFormat = args.format elseif reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa param per geohack.php if reqFormat == 'dec' then geohackParams = args[1] .. '_N_' .. args[2] .. '_E' .. (args[3] and ('_' .. args[3]) or '') else -- concatena solo i posizionali geohackParams = table.concat(args, '_') end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', args.name or '') gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. ' ' .. decLong .. ' ' .. dmsLat .. ' ' .. dmsLong) or wdCat .. buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) return p._coord(getArgs(frame)) end return p 2jywbfk5ecsrnnt1ornuxoqch7irxs0 781952 781951 2016-01-13T23:49:57Z Rotpunkt 14696 +controllo coordinate uguali 781952 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and '[[Categoria:' .. cfg.categorie.warning .. ']]\n' or '' return string.format('%s<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>\n', cat, msg) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Parsifica il parametro 'display' local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Con le richieste dm e dms verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(args, reqFormat) if reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if args[3] == '' and args[7] == '' then table.remove(args, 7) table.remove(args, 3) reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == '' or args[7] == '' then error('* lat e long hanno diversa precisione', 2) -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == '' and args[6] == '' then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == '' or args[6] == '' then error('* lat e long hanno diversa precisione', 2) end end if reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if args[2] == '' and args[5] == '' then table.remove(args, 5) table.remove(args, 2) reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif args[2] == '' or args[5] == '' then error('* lat e long hanno diversa precisione', 2) end end return reqFormat end -- Riconosce il tipo di richiesta ('dec', 'd', 'dm' o 'dms') e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse(args) local reqFormat, currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #args < 2 then error('* coordinate non specificate', 2) elseif #args < 4 then reqFormat = 'dec' elseif #args < 6 then reqFormat = 'd' elseif #args < 8 then reqFormat = 'dm' elseif #args < 10 then reqFormat = 'dms' else error('* errato numero di parametri', 2) end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(args, reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 2) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:P625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(args, display) local cat, retLat, retLong if mw.title.getCurrentTitle().namespace == 0 and display.title then local mWikidata = require('Modulo:Wikidata') local wdLat = mWikidata._getProperty( { 'P625', coord = 'latitude', n = 1 } ) local wdLong = mWikidata._getProperty( { 'P625', coord = 'longitude', n = 1 } ) if wdLat and wdLong then wdLat = round(wdLat, 6) wdLong = round(wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, 1, numberToString(wdLat)) table.insert(args, 2, numberToString(wdLong)) cat = 'Coordinate lette da Wikidata' else -- per poterle confrontare dopo la conversione retLat, retLong = wdLat, wdLong end else cat = 'Coordinate assenti su Wikidata' end end return cat and string.format('[[Categoria:%s]]', cat) or '', retLat, retLong end -- Crea l'HTML ritornato da Coord local function buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. '&pagename=' .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI') .. '&params=' .. geohackParams .. (args.name and ('&title=' .. mw.uri.encode(args.name)) or '') root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(decLat .. ' ' .. decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(decLat:getDeg() .. '; ' .. decLong:getDeg()) :done() :done() :wikitext(args.name and ('<span style="display:none"> (<span class="fn org">' .. args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') text = tostring(root) .. (args.notes or '') -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and 'class="noprint" ' or '' htmlTitle = '<span style="font-size: small;"><span ' .. noprint .. 'id="coordinates">[[Coordinate geografiche|Coordinate]]: ' return (display.inline and text or '') .. (display.title and (htmlTitle .. text .. '</span></span>') or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function p._coord(args) local decLat, decLong, dmsLat, dmsLong, wdLat, wdLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro 'display' display = getDisplay(args) -- legge [[d:property:P625]] ed eventualmente la utilizza wdCat, wdLat, wdLong = checkWikidata(args, display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(function() return paramsParse(args) end, errhandler) if not ret then return reqFormat end if reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == 'dec' or reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == 'dm' or reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args.catuguali and wdLat and wdLong and wdLat == round(decLat:getDeg(), 6) and wdLong == round(decLong:getDeg(), 6) then wdCat = wdCat .. '[[Categoria:Coordinate uguali a Wikidata]]' end if args.format then defaultFormat = args.format elseif reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa param per geohack.php if reqFormat == 'dec' then geohackParams = args[1] .. '_N_' .. args[2] .. '_E' .. (args[3] and ('_' .. args[3]) or '') else -- concatena solo i posizionali geohackParams = table.concat(args, '_') end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', args.name or '') gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. ' ' .. decLong .. ' ' .. dmsLat .. ' ' .. dmsLong) or wdCat .. buildHTML(args, decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) return p._coord(getArgs(frame)) end return p reshj5ykuda843zrqzsmatfwglq5d41 781953 781952 2016-03-31T12:34:05Z Rotpunkt 14696 +classe Coord, migliorate alcune funzioni 781953 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>%s', msg, cat) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Legge il parametro display local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- classe Coord ------------------------------------------------------------------------------- local Coord = {} function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- legge P625 ed eventualmente la utilizza if mw.title.getCurrentTitle().namespace == 0 and getDisplay(self.args).title then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:Coordinate uguali a Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdLat = mWikidata._getProperty( { 'P625', coord = 'latitude', n = 1 } ) self.wdLong = mWikidata._getProperty( { 'P625', coord = 'longitude', n = 1 } ) if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:Coordinate lette da Wikidata]]' end else self.wdCat = '[[Categoria:Coordinate assenti su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali currFormat = cfg.params[self.reqFormat] globe = self.args[#self.args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = self.reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]] function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Crea l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{Coord}} function p.coord(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 3fz33acz91zezbe1y2152uz3ydmq5n0 781954 781953 2016-03-31T12:45:56Z Rotpunkt 14696 per permettere la rinomina della funzione main 781954 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>%s', msg, cat) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Legge il parametro display local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- classe Coord ------------------------------------------------------------------------------- local Coord = {} function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- legge P625 ed eventualmente la utilizza if mw.title.getCurrentTitle().namespace == 0 and getDisplay(self.args).title then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:Coordinate uguali a Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdLat = mWikidata._getProperty( { 'P625', coord = 'latitude', n = 1 } ) self.wdLong = mWikidata._getProperty( { 'P625', coord = 'longitude', n = 1 } ) if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:Coordinate lette da Wikidata]]' end else self.wdCat = '[[Categoria:Coordinate assenti su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali currFormat = cfg.params[self.reqFormat] globe = self.args[#self.args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = self.reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]] function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Crea l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{Coord}} function p.coord(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end -- Entry-point per {{Coord}} function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 3xp44x3vuhzv9zk5dhlxoac6cmg9vu0 781955 781954 2016-03-31T12:51:03Z Rotpunkt 14696 aggiornato nome funzione 781955 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>%s', msg, cat) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Legge il parametro display local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- classe Coord ------------------------------------------------------------------------------- local Coord = {} function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- legge P625 ed eventualmente la utilizza if mw.title.getCurrentTitle().namespace == 0 and getDisplay(self.args).title then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:Coordinate uguali a Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdLat = mWikidata._getProperty( { 'P625', coord = 'latitude', n = 1 } ) self.wdLong = mWikidata._getProperty( { 'P625', coord = 'longitude', n = 1 } ) if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:Coordinate lette da Wikidata]]' end else self.wdCat = '[[Categoria:Coordinate assenti su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali currFormat = cfg.params[self.reqFormat] globe = self.args[#self.args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = self.reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]] function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Crea l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{Coord}} function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 0az9p3a4a5j2le7unwgvdun4er41a6b 781956 781955 2016-09-26T11:32:23Z Rotpunkt 14696 aggiunto parametro prop 781956 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>%s', msg, cat) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Legge il parametro display local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end return args end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- classe Coord ------------------------------------------------------------------------------- local Coord = {} function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- nel namespace principale e con display=title (o con il parametro "prop") -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if mw.title.getCurrentTitle().namespace == 0 and (getDisplay(self.args).title or self.args.prop) then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:Coordinate uguali a Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1 }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1 }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1 }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1 }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:Coordinate lette da Wikidata]]' end else self.wdCat = '[[Categoria:Coordinate assenti su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali currFormat = cfg.params[self.reqFormat] globe = self.args[#self.args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = self.reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]] function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Crea l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{Coord}} function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p rpwrqb1iq5hqyg5jzjpk367n3wgelz7 781957 781956 2016-12-29T13:14:20Z Rotpunkt 14696 +parametri latdec, longdec 781957 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>%s', msg, cat) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Legge il parametro display local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- classe Coord ------------------------------------------------------------------------------- local Coord = {} function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- nel namespace principale e con display=title (o con il parametro "prop") -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if mw.title.getCurrentTitle().namespace == 0 and (getDisplay(self.args).title or self.args.prop) then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:Coordinate uguali a Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1 }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1 }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1 }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1 }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:Coordinate lette da Wikidata]]' end else self.wdCat = '[[Categoria:Coordinate assenti su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali currFormat = cfg.params[self.reqFormat] globe = self.args[#self.args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = self.reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]] function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Crea l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{Coord}} function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 0jou7xsdzufdcf1gfzxz0mnkd9le8bi 781958 781957 2017-08-25T10:02:07Z Rotpunkt 14696 +coord2text 781958 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<span style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</span>%s', msg, cat) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Legge il parametro display local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- classe Coord ------------------------------------------------------------------------------- local Coord = {} function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- nel namespace principale e con display=title (o con il parametro "prop") -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if mw.title.getCurrentTitle().namespace == 0 and (getDisplay(self.args).title or self.args.prop) then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:Coordinate uguali a Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1 }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1 }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1 }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1 }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:Coordinate lette da Wikidata]]' end else self.wdCat = '[[Categoria:Coordinate assenti su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali currFormat = cfg.params[self.reqFormat] globe = self.args[#self.args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = self.reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]] function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Crea l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per il template {{Coord}} function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p gurvec16j14fv54yp7pv6vivs2c81r9 781959 781958 2017-12-01T17:30:34Z Sakretsu 24659 fix html 781959 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- Configurazione local cfg = mw.loadData('Modulo:Coord/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(t, ...) local args = {...} table.insert(t, '* ') for _, val in ipairs(args) do table.insert(t, val) end table.insert(t, '\n') end -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Legge il parametro display local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- classe Coord ------------------------------------------------------------------------------- local Coord = {} function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- nel namespace principale e con display=title (o con il parametro "prop") -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if mw.title.getCurrentTitle().namespace == 0 and (getDisplay(self.args).title or self.args.prop) then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:Coordinate uguali a Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1 }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1 }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1 }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1 }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:Coordinate lette da Wikidata]]' end else self.wdCat = '[[Categoria:Coordinate assenti su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local currFormat, globe, earth, prefix, num, str local param = {} local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali currFormat = cfg.params[self.reqFormat] globe = self.args[#self.args]:match('globe:(%w+)') earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = self.reqFormat .. ' format: ' .. param.name -- valida un parametro di tipo numero if param.type == 'number' then num = tonumber(v) if num then if earth and num < param.min then dumpError(errorTable, prefix, ' < ', param.min) elseif earth and math.floor(num) > param.max then dumpError(errorTable, prefix, ' > ', param.max) end else dumpError(errorTable, prefix, ' non è un numero') end -- valida un parametro di tipo stringa elseif param.type == 'string' then if v ~= param.min and v ~= param.max then dumpError(errorTable, prefix, ' diverso da ', param.min, ' e da ', param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]] function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Crea l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per il template {{Coord}} function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 1675893f8to1fnaqbs3ddncmn5w8pvz 781960 781959 2018-02-14T18:33:01Z Rotpunkt 14696 aggiornato stile documentazione a quello usato in Mediawiki per Lua, semplificazioni in checkRequestFormat 781960 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- nel namespace principale e con display=title (o con il parametro "prop") -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if mw.title.getCurrentTitle().namespace == 0 and (getDisplay(self.args).title or self.args.prop) then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:Coordinate uguali a Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1 }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1 }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1 }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1 }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:Coordinate lette da Wikidata]]' end else self.wdCat = '[[Categoria:Coordinate assenti su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') local earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if earth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif earth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. -- -- @return {string} function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per il template {{Coord}} function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 50d30fdgf2gmc7fp99y4ytb1r084fht 781961 781960 2018-02-14T18:34:42Z Rotpunkt 14696 riga vuota 781961 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- nel namespace principale e con display=title (o con il parametro "prop") -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if mw.title.getCurrentTitle().namespace == 0 and (getDisplay(self.args).title or self.args.prop) then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:Coordinate uguali a Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1 }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1 }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1 }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1 }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:Coordinate lette da Wikidata]]' end else self.wdCat = '[[Categoria:Coordinate assenti su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') local earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if earth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif earth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. -- -- @return {string} function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per il template {{Coord}} function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p rx8urnfhgctb8h4lwywpa81j7an5kwo 781962 781961 2018-03-02T08:25:51Z Rotpunkt 14696 aggiornati nomi categorie Wikidata 781962 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local self = { args = args } setmetatable(self, { __index = Coord }) -- nel namespace principale e con display=title (o con il parametro "prop") -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if mw.title.getCurrentTitle().namespace == 0 and (getDisplay(self.args).title or self.args.prop) then self:_checkWikidata() end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1 }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1 }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1 }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1 }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') local earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if earth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif earth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. -- -- @return {string} function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Per l'utilizzo da un altro modulo function p._main(args) local coord = Coord:new(args) return args.display == 'debug' and coord:getDebugCoords() or coord:getHTML() end -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per il template {{Coord}} function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 6uhim32bbjmxvwlxcm902dgbzvbbhen 781963 781962 2018-08-06T07:25:01Z Rotpunkt 14696 aggiunto il parametro from per leggere le coordinate da un elemento Wikidata arbitrario, solo con display=inline 781963 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.args.from }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.args.from }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.args.from }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.args.from }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') local earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if earth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif earth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. -- -- @return {string} function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per l'utilizzo da un altro modulo. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p b4ozyaftdyh5uownpj447hew94z762q 781964 781963 2019-08-25T12:24:37Z Laurentius 692 uso di TemplateStyles (scorporo i CSS da Common.css e Mobile.css) 781964 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.args.from }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.args.from }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.args.from }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.args.from }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') local earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if earth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif earth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. -- -- @return {string} function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<span style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></span>', display.inline and 'class="noprint"' or '', html) return mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Modulo:Coord/styles.css'}) .. (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per l'utilizzo da un altro modulo. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 6a52pcf2t4q5t7cd3ci9zhid7i2v0x7 781965 781964 2021-10-22T21:07:16Z Sakretsu 24659 applico [[Speciale:Permalink/123595443#Il_template_coord_non_permette_la_visualizzazione_del_popup_di_anteprima|fix]] di Titore per le anteprime di MediaWiki 781965 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('Modulo:No globals') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.args.from }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.args.from }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.args.from }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.args.from }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') local earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if earth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif earth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. -- -- @return {string} function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<div style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></div>', display.inline and 'class="noprint"' or '', html) return mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Modulo:Coord/styles.css'}) .. (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per l'utilizzo da un altro modulo. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p fb1e0wwhm5qcne5ik0636w80rthtrbn 781966 781965 2022-10-22T19:24:47Z Sakretsu 24659 modulo no globals obsoleto 781966 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('strict') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.args.from }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.args.from }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.args.from }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.args.from }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') local earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if earth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif earth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. -- -- @return {string} function Coord:getHTML() local defaultFormat, geohackParams, display, root, html, url, htmlTitle -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end -- legge il parametro display display = getDisplay(self.args) if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end -- crea la stringa per il parametro params di geohack.php if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end root = mw.html.create('') root :tag('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url) :tag('span') :addClass(defaultFormat == 'dec' and 'geo-nondefault' or 'geo-default') :tag('span') :addClass('geo-dms') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext(' ') :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :done() :done() :tag('span') :addClass('geo-multi-punct') :wikitext('&#xfeff; / &#xfeff;') :done() :tag('span') :addClass(defaultFormat == 'dec' and 'geo-default' or 'geo-nondefault') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :addClass('geo-dec') :attr('title', 'Mappe, foto aeree e altri dati per questa posizione') :wikitext(self.decLat .. ' ' .. self.decLong) :done() :tag('span') :attr('style', 'display:none') :tag('span') :addClass('geo') :wikitext(self.decLat:getDeg() .. '; ' .. self.decLong:getDeg()) :done() :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() :wikitext(']') :done() html = tostring(root) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo htmlTitle = string.format('<div style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></div>', display.inline and 'class="noprint"' or '', html) return mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Modulo:Coord/styles.css'}) .. (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per l'utilizzo da un altro modulo. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p rh9iml8zyx9sldsnbd40pgx488y06k5 781967 781966 2024-05-26T16:36:36Z Daimona Eaytoy 24232 Passaggio a maplink di Kartographer come da [[Wikipedia:Bar/Discussioni/Link coordinate con Kartographer, edizione 2024|discussione]], vedi sandbox per commenti dettagliati. 781967 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('strict') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getZoom( extraparams ) local scale = extraparams:match( '%f[%w]scale: ?(%d+)' ) if scale then return math.floor(math.log10( 5 / tonumber( scale ) ) * 3 + 25) end local extraType = extraparams:match( '%f[%w]type: ?(%w+)' ) if extraType then local zoomType = { country = 5, state = 6, adm1st = 7, adm2nd = 8, city = 9, isle = 10, mountain = 10, waterbody = 10, airport = 12, landmark = 13, } return zoomType[ extraType ] end return 13 end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdEntityId = self.args.from or mw.wikibase.getEntityIdForCurrentPage(); if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.wdEntityId }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.wdEntityId }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') local earth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if earth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif earth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. -- -- @return {string} function Coord:getHTML() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end -- legge il parametro display local display = getDisplay(self.args) local defaultFormat if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end local linkText; if defaultFormat == 'dec' then linkText = self.decLat .. ' ' .. self.decLong else linkText = tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) end local jsonParams = { type = 'Feature', geometry = { type ='Point', coordinates = { round( self.decLong:getDeg(), 6 ), -- max precision in GeoJSON format round( self.decLat:getDeg(), 6 ) } }, properties = { ['marker-color'] = "228b22", } } if self.wdEntityId then -- geoshape da Wikidata jsonParams = { jsonParams, { type = 'ExternalData', service = 'geoshape', ids = self.wdEntityId, properties = { ['fill-opacity'] = 0.2 } } } end local mapLink = mw.getCurrentFrame():extensionTag{ name = 'maplink', content = mw.text.jsonEncode( jsonParams ), args = { text = linkText, zoom = getZoom( self.args[#self.args] or '' ) or default_zoom, latitude = self.decLat:getDeg(), longitude = self.decLong:getDeg(), } } -- XXX microformat geo: serve o no? Come verificare se così è corretto? local geo = mw.html.create('') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :attr('style', 'display:none') :addClass('geo') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext( ', ' ) :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() local html = mapLink .. tostring(geo) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo local htmlTitle = string.format('<div style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></div>', display.inline and 'class="noprint"' or '', html) return mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Modulo:Coord/styles.css'}) .. (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per l'utilizzo da un altro modulo. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 959lpfmnpt0y7i2x0ca6ne4aqya5dp7 781968 781967 2024-05-26T20:24:16Z Daimona Eaytoy 24232 Ripristino link a geohack quando le coordinate non sono terrestri 781968 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('strict') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getZoom( extraparams ) local scale = extraparams:match( '%f[%w]scale: ?(%d+)' ) if scale then return math.floor(math.log10( 5 / tonumber( scale ) ) * 3 + 25) end local extraType = extraparams:match( '%f[%w]type: ?(%w+)' ) if extraType then local zoomType = { country = 5, state = 6, adm1st = 7, adm2nd = 8, city = 9, isle = 10, mountain = 10, waterbody = 10, airport = 12, landmark = 13, } return zoomType[ extraType ] end return 13 end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdEntityId = self.args.from or mw.wikibase.getEntityIdForCurrentPage(); if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.wdEntityId }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.wdEntityId }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') self.isEarth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if self.isEarth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif self.isEarth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML di un elemento <maplink> di Kartographer per le coordinate -- -- @return {string} function Coord:_buildMaplinkHTML() local defaultFormat if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end local linkText; if defaultFormat == 'dec' then linkText = self.decLat .. ' ' .. self.decLong else linkText = tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) end local jsonParams = { type = 'Feature', geometry = { type ='Point', coordinates = { round( self.decLong:getDeg(), 6 ), -- max precision in GeoJSON format round( self.decLat:getDeg(), 6 ) } }, properties = { ['marker-color'] = "228b22", } } if self.wdEntityId then -- geoshape da Wikidata jsonParams = { jsonParams, { type = 'ExternalData', service = 'geoshape', ids = self.wdEntityId, properties = { ['fill-opacity'] = 0.2 } } } end return mw.getCurrentFrame():extensionTag{ name = 'maplink', content = mw.text.jsonEncode( jsonParams ), args = { text = linkText, zoom = getZoom( self.args[#self.args] or '' ), latitude = self.decLat:getDeg(), longitude = self.decLong:getDeg(), } } end -- Restituisce l'HTML di un link a geohack con le coordinate (usato solo quando -- non è possibile usare maplink). -- -- @return {string} function Coord:_buildGeohackLink() -- crea la stringa per il parametro params di geohack.php local geohackParams if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri local url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end local linkNode = mw.html.create('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url .. ' ' .. tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) .. ']') :done() return tostring(linkNode) end -- Restituisce l'HTML per il microformat Geo. -- FIXME Serve ancora nel 2024? La documentazione in proposito è scarsissima, e tutti -- i link a strumenti che lo usano non vanno più. Inoltre, qui usiamo un elemento nascosto; -- va bene lo stesso? Come verificarlo? Le specifiche non ne parlano. -- -- @return {string} function Coord:_buildGeoMarkup() return mw.html.create('') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :attr('style', 'display:none') :addClass('geo') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext( ', ' ) :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() end -- Restituisce l'HTML contenente le coordinate con link che utilizza <maplink> (Kartographer) -- se possibile, e geohack altrimenti. -- -- @return {string} function Coord:getHTML() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end local display = getDisplay(self.args) local coordLink if self.isEarth then -- Usa maplink se possibile. A maggio 2024 supporta solo coordinate terrestri, -- vedi T151138. coordLink = self:_buildMaplinkHTML() else coordLink = self:_buildGeohackLink() end local geo = self:_buildGeoMarkup(); local html = coordLink .. tostring(geo) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo local htmlTitle = string.format('<div style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></div>', display.inline and 'class="noprint"' or '', html) return mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Modulo:Coord/styles.css'}) .. (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per l'utilizzo da un altro modulo. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 2tcd42hyegsqcqixnzdwnptldnbts3z 781969 781968 2024-05-26T22:56:58Z Daimona Eaytoy 24232 Riposiziono coordinate come indicatore, necessario per [[phab:T281974]] 781969 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('strict') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getZoom( extraparams ) local scale = extraparams:match( '%f[%w]scale: ?(%d+)' ) if scale then return math.floor(math.log10( 5 / tonumber( scale ) ) * 3 + 25) end local extraType = extraparams:match( '%f[%w]type: ?(%w+)' ) if extraType then local zoomType = { country = 5, state = 6, adm1st = 7, adm2nd = 8, city = 9, isle = 10, mountain = 10, waterbody = 10, airport = 12, landmark = 13, } return zoomType[ extraType ] end return 13 end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdEntityId = self.args.from or mw.wikibase.getEntityIdForCurrentPage(); if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.wdEntityId }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.wdEntityId }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') self.isEarth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if self.isEarth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif self.isEarth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML di un elemento <maplink> di Kartographer per le coordinate -- -- @return {string} function Coord:_buildMaplinkHTML() local defaultFormat if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end local linkText; if defaultFormat == 'dec' then linkText = self.decLat .. ' ' .. self.decLong else linkText = tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) end local jsonParams = { type = 'Feature', geometry = { type ='Point', coordinates = { round( self.decLong:getDeg(), 6 ), -- max precision in GeoJSON format round( self.decLat:getDeg(), 6 ) } }, properties = { ['marker-color'] = "228b22", } } if self.wdEntityId then -- geoshape da Wikidata jsonParams = { jsonParams, { type = 'ExternalData', service = 'geoshape', ids = self.wdEntityId, properties = { ['fill-opacity'] = 0.2 } } } end return mw.getCurrentFrame():extensionTag{ name = 'maplink', content = mw.text.jsonEncode( jsonParams ), args = { text = linkText, zoom = getZoom( self.args[#self.args] or '' ), latitude = self.decLat:getDeg(), longitude = self.decLong:getDeg(), } } end -- Restituisce l'HTML di un link a geohack con le coordinate (usato solo quando -- non è possibile usare maplink). -- -- @return {string} function Coord:_buildGeohackLink() -- crea la stringa per il parametro params di geohack.php local geohackParams if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri local url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end local linkNode = mw.html.create('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url .. ' ' .. tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) .. ']') :done() return tostring(linkNode) end -- Restituisce l'HTML per il microformat Geo. -- FIXME Serve ancora nel 2024? La documentazione in proposito è scarsissima, e tutti -- i link a strumenti che lo usano non vanno più. Inoltre, qui usiamo un elemento nascosto; -- va bene lo stesso? Come verificarlo? Le specifiche non ne parlano. -- -- @return {string} function Coord:_buildGeoMarkup() return mw.html.create('') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :attr('style', 'display:none') :addClass('geo') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext( ', ' ) :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() end -- Restituisce l'HTML contenente le coordinate con link che utilizza <maplink> (Kartographer) -- se possibile, e geohack altrimenti. -- -- @return {string} function Coord:getHTML() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end local display = getDisplay(self.args) local coordLink if self.isEarth then -- Usa maplink se possibile. A maggio 2024 supporta solo coordinate terrestri, -- vedi T151138. coordLink = self:_buildMaplinkHTML() else coordLink = self:_buildGeohackLink() end local geo = self:_buildGeoMarkup(); local html = coordLink .. tostring(geo) .. (self.args.notes or '') -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo local htmlTitleInner = string.format( '<div style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></div>', display.inline and 'class="noprint"' or '', html ) local frame = mw.getCurrentFrame() local htmlTitle = frame:extensionTag( 'indicator', htmlTitleInner, { name = 'coordinates' } ) return frame:extensionTag('templatestyles', '', {src = 'Modulo:Coord/styles.css'}) .. (display.inline and html or '') .. (display.title and htmlTitle or '') .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per l'utilizzo da un altro modulo. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p s4qmxu8x6q6w9nsv03hypzcwru39jw0 781970 781969 2024-09-03T16:46:17Z Daimona Eaytoy 24232 non generare indicatore quando non va mostrato, fix per [[Special:Permalink/140491317#Anomalia_coordinate]] 781970 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('strict') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getZoom( extraparams ) local scale = extraparams:match( '%f[%w]scale: ?(%d+)' ) if scale then return math.floor(math.log10( 5 / tonumber( scale ) ) * 3 + 25) end local extraType = extraparams:match( '%f[%w]type: ?(%w+)' ) if extraType then local zoomType = { country = 5, state = 6, adm1st = 7, adm2nd = 8, city = 9, isle = 10, mountain = 10, waterbody = 10, airport = 12, landmark = 13, } return zoomType[ extraType ] end return 13 end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdEntityId = self.args.from or mw.wikibase.getEntityIdForCurrentPage(); if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.wdEntityId }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.wdEntityId }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') self.isEarth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if self.isEarth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif self.isEarth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML di un elemento <maplink> di Kartographer per le coordinate -- -- @return {string} function Coord:_buildMaplinkHTML() local defaultFormat if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end local linkText; if defaultFormat == 'dec' then linkText = self.decLat .. ' ' .. self.decLong else linkText = tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) end local jsonParams = { type = 'Feature', geometry = { type ='Point', coordinates = { round( self.decLong:getDeg(), 6 ), -- max precision in GeoJSON format round( self.decLat:getDeg(), 6 ) } }, properties = { ['marker-color'] = "228b22", } } if self.wdEntityId then -- geoshape da Wikidata jsonParams = { jsonParams, { type = 'ExternalData', service = 'geoshape', ids = self.wdEntityId, properties = { ['fill-opacity'] = 0.2 } } } end return mw.getCurrentFrame():extensionTag{ name = 'maplink', content = mw.text.jsonEncode( jsonParams ), args = { text = linkText, zoom = getZoom( self.args[#self.args] or '' ), latitude = self.decLat:getDeg(), longitude = self.decLong:getDeg(), } } end -- Restituisce l'HTML di un link a geohack con le coordinate (usato solo quando -- non è possibile usare maplink). -- -- @return {string} function Coord:_buildGeohackLink() -- crea la stringa per il parametro params di geohack.php local geohackParams if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri local url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end local linkNode = mw.html.create('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url .. ' ' .. tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) .. ']') :done() return tostring(linkNode) end -- Restituisce l'HTML per il microformat Geo. -- FIXME Serve ancora nel 2024? La documentazione in proposito è scarsissima, e tutti -- i link a strumenti che lo usano non vanno più. Inoltre, qui usiamo un elemento nascosto; -- va bene lo stesso? Come verificarlo? Le specifiche non ne parlano. -- -- @return {string} function Coord:_buildGeoMarkup() return mw.html.create('') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :attr('style', 'display:none') :addClass('geo') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext( ', ' ) :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() end -- Restituisce l'HTML contenente le coordinate con link che utilizza <maplink> (Kartographer) -- se possibile, e geohack altrimenti. -- -- @return {string} function Coord:getHTML() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end local display = getDisplay(self.args) local coordLink if self.isEarth then -- Usa maplink se possibile. A maggio 2024 supporta solo coordinate terrestri, -- vedi T151138. coordLink = self:_buildMaplinkHTML() else coordLink = self:_buildGeohackLink() end local geo = self:_buildGeoMarkup(); local html = coordLink .. tostring(geo) .. (self.args.notes or '') local frame = mw.getCurrentFrame() local ret = frame:extensionTag('templatestyles', '', {src = 'Modulo:Coord/styles.css'}) .. (display.inline and html or ''); if display.title then -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo local htmlTitle = string.format( '<div style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></div>', display.inline and 'class="noprint"' or '', html ) ret = ret .. frame:extensionTag( 'indicator', htmlTitle, { name = 'coordinates' } ) end return ret .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per l'utilizzo da un altro modulo. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p catw8mrejddfub8lws40dlp65kkyto2 781971 781970 2026-05-13T09:08:56Z GiovanniPen 22308 91 rivisioni mpurtati di [[:it:Modulo:Coord]] 781970 Scribunto text/plain --[[ * Modulo che implementa il template Coord. ]] require('strict') local mWikidata = require('Modulo:Wikidata') local cfg = mw.loadData('Modulo:Coord/Configurazione') local errorCategory = '[[Categoria:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Il template {{Coord}} ha riscontrato degli errori ' .. '([[Template:Coord|istruzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce il numero arrotondato al numero di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getZoom( extraparams ) local scale = extraparams:match( '%f[%w]scale: ?(%d+)' ) if scale then return math.floor(math.log10( 5 / tonumber( scale ) ) * 3 + 25) end local extraType = extraparams:match( '%f[%w]type: ?(%w+)' ) if extraType then local zoomType = { country = 5, state = 6, adm1st = 7, adm2nd = 8, city = 9, isle = 10, mountain = 10, waterbody = 10, airport = 12, landmark = 13, } return zoomType[ extraType ] end return 13 end -- Legge i parametri passati al modulo. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del modulo. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Categoria:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdEntityId = self.args.from or mw.wikibase.getEntityIdForCurrentPage(); if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.wdEntityId }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.wdEntityId }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Categoria:P625 letta da Wikidata]]' end else self.wdCat = '[[Categoria:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato numero di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') self.isEarth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo numero if parType == 'number' then local num = tonumber(v) if num then if self.isEarth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif self.isEarth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un numero', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML di un elemento <maplink> di Kartographer per le coordinate -- -- @return {string} function Coord:_buildMaplinkHTML() local defaultFormat if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end local linkText; if defaultFormat == 'dec' then linkText = self.decLat .. ' ' .. self.decLong else linkText = tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) end local jsonParams = { type = 'Feature', geometry = { type ='Point', coordinates = { round( self.decLong:getDeg(), 6 ), -- max precision in GeoJSON format round( self.decLat:getDeg(), 6 ) } }, properties = { ['marker-color'] = "228b22", } } if self.wdEntityId then -- geoshape da Wikidata jsonParams = { jsonParams, { type = 'ExternalData', service = 'geoshape', ids = self.wdEntityId, properties = { ['fill-opacity'] = 0.2 } } } end return mw.getCurrentFrame():extensionTag{ name = 'maplink', content = mw.text.jsonEncode( jsonParams ), args = { text = linkText, zoom = getZoom( self.args[#self.args] or '' ), latitude = self.decLat:getDeg(), longitude = self.decLong:getDeg(), } } end -- Restituisce l'HTML di un link a geohack con le coordinate (usato solo quando -- non è possibile usare maplink). -- -- @return {string} function Coord:_buildGeohackLink() -- crea la stringa per il parametro params di geohack.php local geohackParams if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri local url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end local linkNode = mw.html.create('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url .. ' ' .. tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) .. ']') :done() return tostring(linkNode) end -- Restituisce l'HTML per il microformat Geo. -- FIXME Serve ancora nel 2024? La documentazione in proposito è scarsissima, e tutti -- i link a strumenti che lo usano non vanno più. Inoltre, qui usiamo un elemento nascosto; -- va bene lo stesso? Come verificarlo? Le specifiche non ne parlano. -- -- @return {string} function Coord:_buildGeoMarkup() return mw.html.create('') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :attr('style', 'display:none') :addClass('geo') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext( ', ' ) :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() end -- Restituisce l'HTML contenente le coordinate con link che utilizza <maplink> (Kartographer) -- se possibile, e geohack altrimenti. -- -- @return {string} function Coord:getHTML() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end local display = getDisplay(self.args) local coordLink if self.isEarth then -- Usa maplink se possibile. A maggio 2024 supporta solo coordinate terrestri, -- vedi T151138. coordLink = self:_buildMaplinkHTML() else coordLink = self:_buildGeohackLink() end local geo = self:_buildGeoMarkup(); local html = coordLink .. tostring(geo) .. (self.args.notes or '') local frame = mw.getCurrentFrame() local ret = frame:extensionTag('templatestyles', '', {src = 'Modulo:Coord/styles.css'}) .. (display.inline and html or ''); if display.title then -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo local htmlTitle = string.format( '<div style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></div>', display.inline and 'class="noprint"' or '', html ) ret = ret .. frame:extensionTag( 'indicator', htmlTitle, { name = 'coordinates' } ) end return ret .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzione per l'utilizzo da un altro modulo. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p catw8mrejddfub8lws40dlp65kkyto2 781993 781971 2026-05-13T09:46:05Z GiovanniPen 22308 prima traduzione 781993 Scribunto text/plain --[[ * Mòdulu ca 'mplementa lu template Coord. ]] require('strict') local mWikidata = require('Mòdulu:Wikidata') local cfg = mw.loadData('Mòdulu:Coord/Configurazione') local errorCategory = '[[Catigurìa:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Lu template {{Coord}} havi riscontrato degli errura ' .. '([[Template:Coord|struzzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce lu nùmmuru arrotondato al nùmmuru di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + nùmmuru" quannu lu nùmmuru è di una sola cifra, altrimenti lo stesso nùmmuru. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un nùmmuru in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getZoom( extraparams ) local scale = extraparams:match( '%f[%w]scale: ?(%d+)' ) if scale then return math.floor(math.log10( 5 / tonumber( scale ) ) * 3 + 25) end local extraType = extraparams:match( '%f[%w]type: ?(%w+)' ) if extraType then local zoomType = { country = 5, state = 6, adm1st = 7, adm2nd = 8, city = 9, isle = 10, mountain = 10, waterbody = 10, airport = 12, landmark = 13, } return zoomType[ extraType ] end return 13 end -- Legge i parametri passati al mòdulu. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del mòdulu. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end -- se presente args.catuguali e non è stato usato Wikidata verifica se uguali if args.catuguali and self.wdLat and self.wdLong and self.wdCat == nil and self.wdLat == round(decLat:getDeg(), 6) and self.wdLong == round(decLong:getDeg(), 6) then self.wdCat = '[[Catigurìa:P625 uguale su Wikidata]]' end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdEntityId = self.args.from or mw.wikibase.getEntityIdForCurrentPage(); if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.wdEntityId }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.wdEntityId }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Catigurìa:P625 letta da Wikidata]]' end else self.wdCat = '[[Catigurìa:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato nùmmuru di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') self.isEarth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo nùmmuru if parType == 'number' then local num = tonumber(v) if num then if self.isEarth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif self.isEarth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un nùmmuru', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML di un elemento <maplink> di Kartographer per le coordinate -- -- @return {string} function Coord:_buildMaplinkHTML() local defaultFormat if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end local linkText; if defaultFormat == 'dec' then linkText = self.decLat .. ' ' .. self.decLong else linkText = tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) end local jsonParams = { type = 'Feature', geometry = { type ='Point', coordinates = { round( self.decLong:getDeg(), 6 ), -- max precision in GeoJSON format round( self.decLat:getDeg(), 6 ) } }, properties = { ['marker-color'] = "228b22", } } if self.wdEntityId then -- geoshape da Wikidata jsonParams = { jsonParams, { type = 'ExternalData', service = 'geoshape', ids = self.wdEntityId, properties = { ['fill-opacity'] = 0.2 } } } end return mw.getCurrentFrame():extensionTag{ name = 'maplink', content = mw.text.jsonEncode( jsonParams ), args = { text = linkText, zoom = getZoom( self.args[#self.args] or '' ), latitude = self.decLat:getDeg(), longitude = self.decLong:getDeg(), } } end -- Restituisce l'HTML di un link a geohack con le coordinate (usato solo quando non è possibile usare maplink). -- -- @return {string} function Coord:_buildGeohackLink() -- crea la stringa per il parametro params di geohack.php local geohackParams if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri local url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end local linkNode = mw.html.create('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url .. ' ' .. tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) .. ']') :done() return tostring(linkNode) end -- Restituisce l'HTML per il microformat Geo. -- FIXME Serve ancora nel 2024? La documentazione in proposito è scarsissima, e tutti -- i link a strumenti che lo usano non vanno più. Inoltre, qui usiamo un elemento nascosto; -- va bene lo stesso? Come verificarlo? Le specifiche non ne parlano. -- -- @return {string} function Coord:_buildGeoMarkup() return mw.html.create('') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :attr('style', 'display:none') :addClass('geo') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext( ', ' ) :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() end -- Restituisce l'HTML contenente le coordinate con link che utilizza <maplink> (Kartographer) -- se possibile, e geohack altrimenti. -- -- @return {string} function Coord:getHTML() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end local display = getDisplay(self.args) local coordLink if self.isEarth then -- Usa maplink se possibile. A maggio 2024 supporta solo coordinate terrestri, -- vedi T151138. coordLink = self:_buildMaplinkHTML() else coordLink = self:_buildGeohackLink() end local geo = self:_buildGeoMarkup(); local html = coordLink .. tostring(geo) .. (self.args.notes or '') local frame = mw.getCurrentFrame() local ret = frame:extensionTag('templatestyles', '', {src = 'Mòdulu:Coord/styles.css'}) .. (display.inline and html or ''); if display.title then -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo local htmlTitle = string.format( '<div style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></div>', display.inline and 'class="noprint"' or '', html ) ret = ret .. frame:extensionTag( 'indicator', htmlTitle, { name = 'coordinates' } ) end return ret .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzioni ppi l'utilizzo da n'autru mòdulu. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p 2zgoxmoymte9j5zvnxysyvo2e38funl 781994 781993 2026-05-13T10:09:16Z GiovanniPen 22308 Rimozione controllo "P625 uguale su Wikidata" per alleggerire il modulo 781994 Scribunto text/plain --[[ * Mòdulu ca 'mplementa lu template Coord. ]] require('strict') local mWikidata = require('Mòdulu:Wikidata') local cfg = mw.loadData('Mòdulu:Coord/Configurazione') local errorCategory = '[[Catigurìa:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Lu template {{Coord}} havi riscontrato degli errura ' .. '([[Template:Coord|struzzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce lu nùmmuru arrotondato al nùmmuru di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + nùmmuru" quannu lu nùmmuru è di una sola cifra, altrimenti lo stesso nùmmuru. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un nùmmuru in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getZoom( extraparams ) local scale = extraparams:match( '%f[%w]scale: ?(%d+)' ) if scale then return math.floor(math.log10( 5 / tonumber( scale ) ) * 3 + 25) end local extraType = extraparams:match( '%f[%w]type: ?(%w+)' ) if extraType then local zoomType = { country = 5, state = 6, adm1st = 7, adm2nd = 8, city = 9, isle = 10, mountain = 10, waterbody = 10, airport = 12, landmark = 13, } return zoomType[ extraType ] end return 13 end -- Legge i parametri passati al mòdulu. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del mòdulu. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdEntityId = self.args.from or mw.wikibase.getEntityIdForCurrentPage(); if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.wdEntityId }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.wdEntityId }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Catigurìa:P625 letta da Wikidata]]' end else self.wdCat = '[[Catigurìa:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* coordinate non specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato nùmmuru di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') self.isEarth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo nùmmuru if parType == 'number' then local num = tonumber(v) if num then if self.isEarth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif self.isEarth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un nùmmuru', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML di un elemento <maplink> di Kartographer per le coordinate -- -- @return {string} function Coord:_buildMaplinkHTML() local defaultFormat if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end local linkText; if defaultFormat == 'dec' then linkText = self.decLat .. ' ' .. self.decLong else linkText = tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) end local jsonParams = { type = 'Feature', geometry = { type ='Point', coordinates = { round( self.decLong:getDeg(), 6 ), -- max precision in GeoJSON format round( self.decLat:getDeg(), 6 ) } }, properties = { ['marker-color'] = "228b22", } } if self.wdEntityId then -- geoshape da Wikidata jsonParams = { jsonParams, { type = 'ExternalData', service = 'geoshape', ids = self.wdEntityId, properties = { ['fill-opacity'] = 0.2 } } } end return mw.getCurrentFrame():extensionTag{ name = 'maplink', content = mw.text.jsonEncode( jsonParams ), args = { text = linkText, zoom = getZoom( self.args[#self.args] or '' ), latitude = self.decLat:getDeg(), longitude = self.decLong:getDeg(), } } end -- Restituisce l'HTML di un link a geohack con le coordinate (usato solo quando non è possibile usare maplink). -- -- @return {string} function Coord:_buildGeohackLink() -- crea la stringa per il parametro params di geohack.php local geohackParams if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri local url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end local linkNode = mw.html.create('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url .. ' ' .. tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) .. ']') :done() return tostring(linkNode) end -- Restituisce l'HTML per il microformat Geo. -- FIXME Serve ancora nel 2024? La documentazione in proposito è scarsissima, e tutti -- i link a strumenti che lo usano non vanno più. Inoltre, qui usiamo un elemento nascosto; -- va bene lo stesso? Come verificarlo? Le specifiche non ne parlano. -- -- @return {string} function Coord:_buildGeoMarkup() return mw.html.create('') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :attr('style', 'display:none') :addClass('geo') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext( ', ' ) :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() end -- Restituisce l'HTML contenente le coordinate con link che utilizza <maplink> (Kartographer) -- se possibile, e geohack altrimenti. -- -- @return {string} function Coord:getHTML() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end local display = getDisplay(self.args) local coordLink if self.isEarth then -- Usa maplink se possibile. A maggio 2024 supporta solo coordinate terrestri, -- vedi T151138. coordLink = self:_buildMaplinkHTML() else coordLink = self:_buildGeohackLink() end local geo = self:_buildGeoMarkup(); local html = coordLink .. tostring(geo) .. (self.args.notes or '') local frame = mw.getCurrentFrame() local ret = frame:extensionTag('templatestyles', '', {src = 'Mòdulu:Coord/styles.css'}) .. (display.inline and html or ''); if display.title then -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo local htmlTitle = string.format( '<div style="font-size: small"><span %s id="coordinates">[[Coordinate geografiche|Coordinate]]: %s</span></div>', display.inline and 'class="noprint"' or '', html ) ret = ret .. frame:extensionTag( 'indicator', htmlTitle, { name = 'coordinates' } ) end return ret .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzioni ppi l'utilizzo da n'autru mòdulu. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p hk2ul1hkong8bpv7km5buc8cuy58we4 782028 781994 2026-05-13T10:28:15Z GiovanniPen 22308 inizio traduzione 782028 Scribunto text/plain --[[ * Mòdulu ca 'mplementa lu template Coord. ]] require('strict') local mWikidata = require('Mòdulu:Wikidata') local cfg = mw.loadData('Mòdulu:Coord/Configurazione') local errorCategory = '[[Catigurìa:Errori di compilazione del template Coord]]' -- ============================================================================= -- Funzioni di utilità -- ============================================================================= -- Error handler per xpcall, formatta l'errore. -- -- @param {string} msg -- @return {string} local function errhandler(msg) local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' return string.format('<div style="color:red">Lu template {{Coord}} havi riscontrato degli errura ' .. '([[Template:Coord|struzzioni]]):\n%s</div>%s', msg, cat) end -- Restituisce lu nùmmuru arrotondato al nùmmuru di cifre decimali richiesto. -- http://lua-users.org/wiki/SimpleRound -- -- @param {number} num -- @param {number} idp -- @return {number} local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Restituisce la stringa "0 + nùmmuru" quannu lu nùmmuru è di una sola cifra, altrimenti lo stesso nùmmuru. -- -- @param {number} num -- @return {string} local function padleft0(num) return (num < 10 and '0' or '') .. num end -- Converte un nùmmuru in stringa senza usare la notazione scientifica, esempio tostring(0.00001). -- -- @param {number} num -- @return {string} local function numberToString(num) -- la parentesi () extra serve per non restituire anche il gsub.count return (string.format('%f', num):gsub('%.?0+$', '')) end -- Parsifica il parametro display e restituisce una table con chiavi inline, title e debug. -- -- @param {table} args -- @return {table} local function getDisplay(args) return { inline = not args.display or args.display == 'inline' or args.display == 'inline,title', title = args.display == 'title' or args.display == 'inline,title', debug = args.display == 'debug' } end local function getZoom( extraparams ) local scale = extraparams:match( '%f[%w]scale: ?(%d+)' ) if scale then return math.floor(math.log10( 5 / tonumber( scale ) ) * 3 + 25) end local extraType = extraparams:match( '%f[%w]type: ?(%w+)' ) if extraType then local zoomType = { country = 5, state = 6, adm1st = 7, adm2nd = 8, city = 9, isle = 10, mountain = 10, waterbody = 10, airport = 12, landmark = 13, } return zoomType[ extraType ] end return 13 end -- Legge i parametri passati al mòdulu. -- -- @param {table} frame -- @return {table} local function getArgs(frame) local args = {} -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= '' or tonumber(k) then args[k] = string.gsub(v, '^%s*(.-)%s*$', '%1') end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == '' then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == '' do table.remove(args, 1) end -- se l'utente non ha fornito lat e long con i posizionali ma con latdec e longdec if (#args == 0 or (#args == 1 and not tonumber(args[1]))) and tonumber(args.latdec) and tonumber(args.longdec) then table.insert(args, 1, numberToString(args.latdec)) table.insert(args, 2, numberToString(args.longdec)) end return args end -- ============================================================================= -- Classe DecCoord -- ============================================================================= -- La classe DecCoord rappresenta una coordinata (latitudine o longitudine) in gradi decimali. local DecCoord = {} local DmsCoord = {} -- dichiarata qui per le conversioni -- Costruttore della classe DecCoord. -- -- @param {string} deg - i gradi decimali, positivi o negativi, se negativi viene -- cambiato il segno e la direzione cardinale eventualmente invertita -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DecCoord function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == 'N' and 'S' or (card == 'E' and 'W' or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DecCoord:__tostring() return numberToString(self.deg) .. '°' .. self.card end -- Restituisce i gradi con segno. -- -- @return {string} function DecCoord:getDeg() local deg = self.deg * ((self.card == 'N' or self.card =='E') and 1 or -1) return numberToString(deg) end -- Restituisce un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi. -- -- @return {table} un nuovo oggetto DmsCoord function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- ============================================================================= -- Classe DmsCoord -- ============================================================================= -- La classe DmsCoord rappresenta una coordinata (latitudine o longitudine) in gradi/minuti/secondi. -- Costruttore della classe DmsCoord. -- -- @param {string} deg - i gradi -- @param {string} min - i minuti, può essere nil -- @param {string} sec - i secondi, può essere nil -- @param {string} card - la direzione cardinale (N|S|E|W) -- @return {table} un nuovo oggetto DmsCoord function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento. -- -- @return {string} function DmsCoord:__tostring() return self.deg .. '°' .. (self.min and (padleft0(self.min) .. '′') or '') .. (self.sec and (padleft0(self.sec) .. '″') or '') .. self.card end -- Restituisce un nuovo oggetto DecCoord, convertendo in gradi decimali. -- -- @return {table} un nuovo oggetto DecCoord function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end -- ============================================================================= -- Classe Coord -- ============================================================================= -- La classe Coord è la classe principale del mòdulu. -- Al suo interno ha un riferimento alla latitudine e longitudine in ogni formato. local Coord = {} -- Costruttore della classe Coord. -- -- @param {table} args -- @return {table} un nuovo oggetto Coord function Coord:new(args) local decLat, decLong, dmsLat, dmsLong local display = getDisplay(args) local self = { args = args } setmetatable(self, { __index = Coord }) if args.from and display.title then error('il parametro "from" è valido solo con display=inline', 3) end -- con display=title o con i parametri "prop" o "from" -- legge le coordinate da P625 per utilizzarle o per confrontarle con quelle inserite if getDisplay(self.args).title or self.args.prop or args.from then self:_checkWikidata() -- con "from", senza coordinate utente e su Wikidata non esegue i controlli successivi if self.args.from and #self.args < 2 and not tonumber(args[1]) then return self end end -- identifica il tipo di chiamata self:_checkRequestFormat() -- in base al tipo di chiamata crea gli oggetti DecCoord o DmsCoord if self.reqFormat == 'dec' then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], 'N') decLong = DecCoord:new(args[2], 'E') elseif self.reqFormat == 'd' then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif self.reqFormat == 'dm' then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif self.reqFormat == 'dms' then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- effettua le conversioni dec <=> dms if self.reqFormat == 'dec' or self.reqFormat == 'd' then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif self.reqFormat == 'dm' or self.reqFormat == 'dms' then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end self.decLat = decLat self.decLong = decLong self.dmsLat = dmsLat self.dmsLong = dmsLong return self end -- Legge la P625 e la utilizza come latitudine e longitudine se non fornite dall'utente. function Coord:_checkWikidata() self.wdEntityId = self.args.from or mw.wikibase.getEntityIdForCurrentPage(); if self.args.prop then self.wdLat = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'latitude', n = 1, nq = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getQualifier({ self.args.prop, 'P625', coord = 'longitude', n = 1, nq = 1, from = self.wdEntityId }) else self.wdLat = mWikidata._getProperty({ 'P625', coord = 'latitude', n = 1, from = self.wdEntityId }) self.wdLong = mWikidata._getProperty({ 'P625', coord = 'longitude', n = 1, from = self.wdEntityId }) end if self.wdLat and self.wdLong then self.wdLat = round(self.wdLat, 6) self.wdLong = round(self.wdLong, 6) -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #self.args == 0 or (#self.args == 1 and not tonumber(self.args[1])) then table.insert(self.args, 1, numberToString(self.wdLat)) table.insert(self.args, 2, numberToString(self.wdLong)) self.wdCat = '[[Catigurìa:P625 letta da Wikidata]]' end else self.wdCat = '[[Catigurìa:P625 assente su Wikidata]]' end end -- Riconosce il tipo di richiesta: dec, d, dm o dms. function Coord:_checkRequestFormat() local errorTable = {} -- riconoscimento tipo di richiesta if #self.args < 2 then error('* cuurdinati nun specificate', 4) elseif #self.args < 4 then self.reqFormat = 'dec' elseif #self.args < 6 then self.reqFormat = 'd' elseif #self.args < 8 then self.reqFormat = 'dm' elseif #self.args < 10 then self.reqFormat = 'dms' else error('* errato nùmmuru di parametri', 4) end -- con le richieste dm e dms verifica se ci sono parametri lasciati vuoti in modo valido. if self.reqFormat == 'dms' then -- {{coord|1|2||N|5|6||E}} valido if self.args[3] == '' and self.args[7] == '' then table.remove(self.args, 7) table.remove(self.args, 3) self.reqFormat = 'dm' -- {{coord|1|2|3|N|5|6||E}} non valido elseif self.args[3] == '' or self.args[7] == '' then error('* lat e long hanno diversa precisione', 4) -- {{coord|1||3|N|5||7|E}} valido elseif self.args[2] == '' and self.args[6] == '' then self.args[2], self.args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif self.args[2] == '' or self.args[6] == '' then error('* lat e long hanno diversa precisione', 4) end end if self.reqFormat == 'dm' then -- {{coord|1||N|4||E}} valido if self.args[2] == '' and self.args[5] == '' then table.remove(self.args, 5) table.remove(self.args, 2) self.reqFormat = 'd' -- {{coord|1|2|N|4||E}} non valido elseif self.args[2] == '' or self.args[5] == '' then error('* lat e long hanno diversa precisione', 4) end end -- validazione parametri posizionali local currFormat = cfg.params[self.reqFormat] local globe = self.args[#self.args]:match('globe:(%w+)') self.isEarth = not globe or globe == 'earth' for k, v in ipairs(self.args) do if currFormat[k] then local err local parType = currFormat[k][1] local parName = currFormat[k][2] local parMin = currFormat[k][3] local parMax = currFormat[k][4] -- valida un parametro di tipo nùmmuru if parType == 'number' then local num = tonumber(v) if num then if self.isEarth and num < parMin then err = string.format('* %s format: %s < %s', self.reqFormat, parName, parMin) elseif self.isEarth and math.floor(num) > parMax then err = string.format('* %s format: %s > %s', self.reqFormat, parName, parMax) end else err = string.format('* %s format: %s non è un nùmmuru', self.reqFormat, parName) end -- valida un parametro di tipo stringa elseif parType == 'string' then if v ~= parMin and v ~= parMax then err = string.format('* %s format: %s diverso da %s e da %s', self.reqFormat, parName, parMin, parMax) end end if err then table.insert(errorTable, err) end end end if #errorTable > 0 then error(table.concat(errorTable, '\n'), 4) end end -- Utilizza l'estensione [[mw:Extension:GeoData]]. -- -- @param {table} display -- @return {string} function Coord:_setGeoData(display) local gdStr = string.format('{{#coordinates:%s|%s|name=%s}}', table.concat(self.args, '|'), (display.title and mw.title.getCurrentTitle().namespace == 0) and 'primary' or '', self.args.name or '') return mw.getCurrentFrame():preprocess(gdStr) end -- Funzione di debug, restituisce latitudine e longitudine in entrambi i formati. -- -- @return {string} function Coord:getDebugCoords() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' end return self.decLat .. ' ' .. self.decLong .. ' ' .. self.dmsLat .. ' ' .. self.dmsLong end -- Restituisce l'HTML di un elemento <maplink> di Kartographer per le coordinate -- -- @return {string} function Coord:_buildMaplinkHTML() local defaultFormat if self.args.format then defaultFormat = self.args.format elseif self.reqFormat == 'dec' then defaultFormat = 'dec' else defaultFormat = 'dms' end local linkText; if defaultFormat == 'dec' then linkText = self.decLat .. ' ' .. self.decLong else linkText = tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) end local jsonParams = { type = 'Feature', geometry = { type ='Point', coordinates = { round( self.decLong:getDeg(), 6 ), -- max precision in GeoJSON format round( self.decLat:getDeg(), 6 ) } }, properties = { ['marker-color'] = "228b22", } } if self.wdEntityId then -- geoshape da Wikidata jsonParams = { jsonParams, { type = 'ExternalData', service = 'geoshape', ids = self.wdEntityId, properties = { ['fill-opacity'] = 0.2 } } } end return mw.getCurrentFrame():extensionTag{ name = 'maplink', content = mw.text.jsonEncode( jsonParams ), args = { text = linkText, zoom = getZoom( self.args[#self.args] or '' ), latitude = self.decLat:getDeg(), longitude = self.decLong:getDeg(), } } end -- Restituisce l'HTML di un link a geohack con le coordinate (usato solo quando non è possibile usare maplink). -- -- @return {string} function Coord:_buildGeohackLink() -- crea la stringa per il parametro params di geohack.php local geohackParams if self.reqFormat == 'dec' then geohackParams = string.format('%s_N_%s_E', self.args[1], self.args[2]) if self.args[3] then geohackParams = geohackParams .. '_' .. self.args[3] end else -- concatena solo i posizionali geohackParams = table.concat(self.args, '_') end -- geohack url e parametri local url = string.format('%s&pagename=%s&params=%s', cfg.geohackUrl, mw.uri.encode(mw.title.getCurrentTitle().prefixedText, 'WIKI'), geohackParams) if self.args.name then url = url .. '&title=' .. mw.uri.encode(self.args.name) end local linkNode = mw.html.create('span') :addClass('plainlinks nourlexpansion') :wikitext('[' .. url .. ' ' .. tostring(self.dmsLat) .. ' ' .. tostring(self.dmsLong) .. ']') :done() return tostring(linkNode) end -- Restituisce l'HTML per il microformat Geo. -- FIXME Serve ancora nel 2024? La documentazione in proposito è scarsissima, e tutti -- i link a strumenti che lo usano non vanno più. Inoltre, qui usiamo un elemento nascosto; -- va bene lo stesso? Come verificarlo? Le specifiche non ne parlano. -- -- @return {string} function Coord:_buildGeoMarkup() return mw.html.create('') :wikitext(self.args.name and '<span class="vcard">' or '') :tag('span') :attr('style', 'display:none') :addClass('geo') :tag('span') :addClass('latitude') :wikitext(tostring(self.dmsLat)) :done() :wikitext( ', ' ) :tag('span') :addClass('longitude') :wikitext(tostring(self.dmsLong)) :done() :wikitext(self.args.name and ('<span style="display:none"> (<span class="fn org">' .. self.args.name .. '</span>)</span></span>') or '') :done() end -- Restituisce l'HTML contenente le coordinate con link che utilizza <maplink> (Kartographer) -- se possibile, e geohack altrimenti. -- -- @return {string} function Coord:getHTML() -- con args.from restitusce una stringa vuota se non c'è nessun dato if self.args.from and #self.args < 2 and not tonumber(self.args[1]) then return '' elseif self.args.display == 'debug' then return self:getDebugCoords() end local display = getDisplay(self.args) local coordLink if self.isEarth then -- Usa maplink se possibile. A maggio 2024 supporta solo coordinate terrestri, -- vedi T151138. coordLink = self:_buildMaplinkHTML() else coordLink = self:_buildGeohackLink() end local geo = self:_buildGeoMarkup(); local html = coordLink .. tostring(geo) .. (self.args.notes or '') local frame = mw.getCurrentFrame() local ret = frame:extensionTag('templatestyles', '', {src = 'Mòdulu:Coord/styles.css'}) .. (display.inline and html or ''); if display.title then -- formatta il risultato a seconda di args.display (nil, 'inline', 'title', 'inline,title') -- se inline e title, in stampa visualizza solo il primo local htmlTitle = string.format( '<div style="font-size: small"><span %s id="coordinates">[[Cuurdinati giugràfichi|Cuurdinati]]: %s</span></div>', display.inline and 'class="noprint"' or '', html ) ret = ret .. frame:extensionTag( 'indicator', htmlTitle, { name = 'coordinates' } ) end return ret .. self:_setGeoData(display) .. (mw.title.getCurrentTitle().namespace == 0 and self.wdCat or '') end -- ============================================================================= -- Funzioni esportate -- ============================================================================= local p = {} -- Funzione importata da https://en.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=789126031 -- per estrarre lat, long, type, scale, dim, region, globe, source, dal link a geohack.php generato da coord. function p.coord2text(frame) if frame.args[1] == '' or frame.args[2] == '' or not frame.args[2] then return nil end frame.args[2] = mw.text.trim(frame.args[2]) if frame.args[2] == 'lat' or frame.args[2] == 'long' then local result, negative = mw.text.split((mw.ustring.match(frame.args[1],'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') if frame.args[2] == 'lat' then result, negative = result[1], 'S' else result, negative = result[2], 'W' end result = mw.text.split(result, '°') if result[2] == negative then result[1] = '-'..result[1] end return result[1] else return mw.ustring.match(frame.args[1], 'params=.-_'..frame.args[2]..':(.-)[ _]') end end -- Funzione per eventuale template {{dms2dec}}. function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Funzione per eventuale template {{dec2dms}}. function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Funzioni ppi l'utilizzo da n'autru mòdulu. function p._main(args) return Coord:new(args):getHTML() end -- Funzione per il template {{Coord}}. function p.main(frame) return select(2, xpcall(function() return p._main(getArgs(frame)) end, errhandler)) end return p geworj105z0v5uvucygxvdua3hh6pii Mòdulu:Coord/man 828 67415 781978 2013-10-20T15:12:57Z Rotpunkt 14696 Nuova pagina 781978 wikitext text/x-wiki {{Wikibozza}} {{Man modulo}} Modulo Lua che implementa le funzionalità del [[Template:Coord]]. <includeonly>[[Categoria:Moduli]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> p9hyuw6eci6wrnvwo2487x793eanahd 781979 781978 2013-11-02T08:45:07Z Rotpunkt 14696 +configurazione 781979 wikitext text/x-wiki {{Wikibozza}} {{Man modulo}} Modulo Lua che implementa le funzionalità del [[Template:Coord]]. Ha una sottopagina di configurazione: [[Modulo:Coord/Configurazione]]. <includeonly>[[Categoria:Moduli]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> f46w7u3d484w19vikqxxt3bwa6d6yi5 781980 781979 2013-11-18T19:01:11Z Bultro 2731 781980 wikitext text/x-wiki {{Man modulo}} Modulo Lua che implementa le funzionalità del [[Template:Coord]]. Ha una sottopagina di configurazione: [[Modulo:Coord/Configurazione]]. <includeonly>[[Categoria:Moduli]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> jlvar3bithd97uzd83iwq8gvc4nf5c7 781981 781980 2014-01-13T22:27:15Z Bultro 2731 cat 781981 wikitext text/x-wiki {{Man modulo}} Modulo Lua che implementa le funzionalità del [[Template:Coord]]. Ha una sottopagina di configurazione: [[Modulo:Coord/Configurazione]]. <includeonly>[[Categoria:Moduli]] [[Categoria:Template Coord]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> ijkhaizat290jp7fbrb9rwae0olc2ds 781982 781981 2014-12-15T16:18:09Z Rotpunkt 14696 +template protetta 781982 wikitext text/x-wiki {{Man modulo}} Modulo Lua che implementa le funzionalità del [[Template:Coord]]. Ha una sottopagina di configurazione: [[Modulo:Coord/Configurazione]]. <includeonly>{{Protetta}}[[Categoria:Moduli]] [[Categoria:Template Coord]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> gzfn9te0l8zzh3ddjarb615nvd7i7rz 781983 781982 2015-06-11T20:17:29Z Rotpunkt 14696 utilizzo da un altro modulo 781983 wikitext text/x-wiki {{Man modulo}} Modulo Lua che implementa le funzionalità del [[Template:Coord]]. Ha una sottopagina di configurazione: [[Modulo:Coord/Configurazione]]. == Utilizzo da un altro modulo == Il modulo può essere usato anche da un altro modulo tramite "require". È sufficiente inserire nel modulo: <syntaxhighlight lang="lua">local mCoord = require('Modulo:Coord')</syntaxhighlight> La funzione esportata è ''_coord'', con gli stessi parametri del template. ;Esempio <syntaxhighlight lang="lua"> local mCoord = require('Modulo:Coord') local p = {} function p.main(frame) local sydney, wd sydney = mCoord._coord( { '-33.86', '151.211111', format = 'dms' } ) wd = mCoord._coord( { display = 'inline,title', format = 'dec' } ) return string.format('Le coordinate dms di Sydney sono: %s. ' .. 'Le coordinate dec dell\'elemento Wikidata collegato: %s.', sydney, wd) end return p </syntaxhighlight> <includeonly>{{Protetta}}[[Categoria:Moduli]] [[Categoria:Template Coord]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> ewv25wkebx7ojpyryqiydq6ushzj0hi 781984 781983 2016-03-31T12:56:19Z Rotpunkt 14696 aggiornato nome funzione 781984 wikitext text/x-wiki {{Man modulo}} Modulo Lua che implementa le funzionalità del [[Template:Coord]]. Ha una sottopagina di configurazione: [[Modulo:Coord/Configurazione]]. == Utilizzo da un altro modulo == Il modulo può essere usato anche da un altro modulo tramite "require". È sufficiente inserire nel modulo: <syntaxhighlight lang="lua">local mCoord = require('Modulo:Coord')</syntaxhighlight> La funzione esportata è ''_main'', con gli stessi parametri del template. ;Esempio <syntaxhighlight lang="lua"> local mCoord = require('Modulo:Coord') local p = {} function p.main(frame) local sydney, wd sydney = mCoord._main( { '-33.86', '151.211111', format = 'dms' } ) wd = mCoord._main( { display = 'inline,title', format = 'dec' } ) return string.format('Le coordinate dms di Sydney sono: %s. ' .. 'Le coordinate dec dell\'elemento Wikidata collegato: %s.', sydney, wd) end return p </syntaxhighlight> <includeonly>{{Protetta}}[[Categoria:Moduli]] [[Categoria:Template Coord]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> pgkxegeppn1qnumxepahkhk4jpfdvjf 781985 781984 2020-05-27T20:09:19Z Sakretsu 24659 +sottopagina 781985 wikitext text/x-wiki {{Man modulo}} Modulo Lua che implementa le funzionalità del [[Template:Coord]]. Ha una sottopagina di configurazione [[Modulo:Coord/Configurazione]] e una sottopagina CSS [[Modulo:Coord/styles.css]]. == Utilizzo da un altro modulo == Il modulo può essere usato anche da un altro modulo tramite "require". È sufficiente inserire nel modulo: <syntaxhighlight lang="lua">local mCoord = require('Modulo:Coord')</syntaxhighlight> La funzione esportata è ''_main'', con gli stessi parametri del template. ;Esempio <syntaxhighlight lang="lua"> local mCoord = require('Modulo:Coord') local p = {} function p.main(frame) local sydney, wd sydney = mCoord._main( { '-33.86', '151.211111', format = 'dms' } ) wd = mCoord._main( { display = 'inline,title', format = 'dec' } ) return string.format('Le coordinate dms di Sydney sono: %s. ' .. 'Le coordinate dec dell\'elemento Wikidata collegato: %s.', sydney, wd) end return p </syntaxhighlight> <includeonly>{{Protetta}}[[Categoria:Moduli]] [[Categoria:Template Coord]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> 9pn8jsho3odrus03mvgnf2ruiku587k 781986 781985 2026-05-13T09:08:58Z GiovanniPen 22308 8 rivisioni mpurtati di [[:it:Modulo:Coord/man]] 781985 wikitext text/x-wiki {{Man modulo}} Modulo Lua che implementa le funzionalità del [[Template:Coord]]. Ha una sottopagina di configurazione [[Modulo:Coord/Configurazione]] e una sottopagina CSS [[Modulo:Coord/styles.css]]. == Utilizzo da un altro modulo == Il modulo può essere usato anche da un altro modulo tramite "require". È sufficiente inserire nel modulo: <syntaxhighlight lang="lua">local mCoord = require('Modulo:Coord')</syntaxhighlight> La funzione esportata è ''_main'', con gli stessi parametri del template. ;Esempio <syntaxhighlight lang="lua"> local mCoord = require('Modulo:Coord') local p = {} function p.main(frame) local sydney, wd sydney = mCoord._main( { '-33.86', '151.211111', format = 'dms' } ) wd = mCoord._main( { display = 'inline,title', format = 'dec' } ) return string.format('Le coordinate dms di Sydney sono: %s. ' .. 'Le coordinate dec dell\'elemento Wikidata collegato: %s.', sydney, wd) end return p </syntaxhighlight> <includeonly>{{Protetta}}[[Categoria:Moduli]] [[Categoria:Template Coord]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> 9pn8jsho3odrus03mvgnf2ruiku587k Mòdulu:Coordinates 828 67416 781996 2026-05-13T10:13:34Z GiovanniPen 22308 redirect 781996 Scribunto text/plain return require('Mòdulu:Coord') oymr9tt493j2txxprv1sr8x485vxcwk 781997 781996 2026-05-13T10:15:00Z GiovanniPen 22308 fix redirect 781997 Scribunto text/plain return require [[Mòdulu:Coord]] e81czjg26tn6t9v8ef2yne4k7cjdllj Mòdulu:Coord/Config 828 67417 781998 2026-05-13T10:17:48Z GiovanniPen 22308 redirect 781998 Scribunto text/plain return require [[Mòdulu:Coord/Config]] fv6i9l2eir11ckm523w7022x00n69ck 781999 2013-10-20T15:15:29Z Rotpunkt 14696 Nuova pagina 781999 Scribunto text/plain local coord_config = {} -- Nomi categorie di servizio coord_config.categorie = { -- inserita quando ci sono errori nei parametri ["warning"] = "Errori di compilazione del template Coord" } -- Modalità di immmissione dei parametri posizionali ("dec", "d", "dm" o "dms") -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, coord_config.params = { ["dec"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "longd", -180, 180 }, }, ["d"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "string", "latc", "N", "S" }, [3] = { "number", "longd", -180, 180 }, [4] = { "string", "longc", "E", "W" }, }, ["dm"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "latm", 0, 60 }, [3] = { "string", "latc", "N", "S" }, [4] = { "number", "longd", -180, 180 }, [5] = { "number", "longm", 0, 60 }, [6] = { "string", "longc", "E", "W" }, }, ["dms"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "latm", 0, 60 }, [3] = { "number", "lats", 0, 60 }, [4] = { "string", "latc", "N", "S" }, [5] = { "number", "longd", -180, 180 }, [6] = { "number", "longm", 0, 60 }, [7] = { "number", "longs", 0, 60 }, [8] = { "string", "longc", "E", "W" }, } } return coord_config sedilslmed71fhg7u627wfqdkd2v56s 782000 781999 2013-10-21T20:43:06Z Rotpunkt 14696 fix gradi rispetto a quelli del template, fix minuti/secondi 782000 Scribunto text/plain local coord_config = {} -- Nomi categorie di servizio coord_config.categorie = { -- inserita quando ci sono errori nei parametri ["warning"] = "Errori di compilazione del template Coord" } -- Modalità di immmissione dei parametri posizionali ("dec", "d", "dm" o "dms") -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, coord_config.params = { ["dec"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "longd", -180, 180 }, }, ["d"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "string", "latc", "N", "S" }, [3] = { "number", "longd", 0, 180 }, [4] = { "string", "longc", "E", "W" }, }, ["dm"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "string", "latc", "N", "S" }, [4] = { "number", "longd", 0, 180 }, [5] = { "number", "longm", 0, 59 }, [6] = { "string", "longc", "E", "W" }, }, ["dms"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "number", "lats", 0, 59 }, [4] = { "string", "latc", "N", "S" }, [5] = { "number", "longd", 0, 180 }, [6] = { "number", "longm", 0, 59 }, [7] = { "number", "longs", 0, 59 }, [8] = { "string", "longc", "E", "W" }, } } return coord_config pm9x3gqkgn45oehxty9om6wt8bnztlm 782001 782000 2013-10-22T11:41:36Z Rotpunkt 14696 +geohackUrl 782001 Scribunto text/plain local coord_config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri "pagename", "params" e "title" coord_config.geohackUrl = "http://tools.wmflabs.org/geohack/geohack.php?language=it" -- Nomi categorie di servizio coord_config.categorie = { -- inserita quando ci sono errori nei parametri ["warning"] = "Errori di compilazione del template Coord" } -- Modalità di immmissione dei parametri posizionali ("dec", "d", "dm" o "dms") -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, coord_config.params = { ["dec"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "longd", -180, 180 }, }, ["d"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "string", "latc", "N", "S" }, [3] = { "number", "longd", 0, 180 }, [4] = { "string", "longc", "E", "W" }, }, ["dm"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "string", "latc", "N", "S" }, [4] = { "number", "longd", 0, 180 }, [5] = { "number", "longm", 0, 59 }, [6] = { "string", "longc", "E", "W" }, }, ["dms"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "number", "lats", 0, 59 }, [4] = { "string", "latc", "N", "S" }, [5] = { "number", "longd", 0, 180 }, [6] = { "number", "longm", 0, 59 }, [7] = { "number", "longs", 0, 59 }, [8] = { "string", "longc", "E", "W" }, } } return coord_config nx4weuriqygmhjgfpum6n2vos5tjvrk 782002 782001 2013-10-22T12:02:39Z Rotpunkt 14696 +esempi 782002 Scribunto text/plain local coord_config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri "pagename", "params" e "title" coord_config.geohackUrl = "http://tools.wmflabs.org/geohack/geohack.php?language=it" -- Nomi categorie di servizio coord_config.categorie = { -- inserita quando ci sono errori nei parametri ["warning"] = "Errori di compilazione del template Coord" } -- Modalità di immmissione dei parametri posizionali ("dec", "d", "dm" o "dms") -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, coord_config.params = { -- {{coord|10|20}} ["dec"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "longd", -180, 180 }, }, -- {{coord|10|N|20|E}} ["d"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "string", "latc", "N", "S" }, [3] = { "number", "longd", 0, 180 }, [4] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|N|20|30|E}} ["dm"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "string", "latc", "N", "S" }, [4] = { "number", "longd", 0, 180 }, [5] = { "number", "longm", 0, 59 }, [6] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|30|N|20|30|40|E}} ["dms"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "number", "lats", 0, 59 }, [4] = { "string", "latc", "N", "S" }, [5] = { "number", "longd", 0, 180 }, [6] = { "number", "longm", 0, 59 }, [7] = { "number", "longs", 0, 59 }, [8] = { "string", "longc", "E", "W" }, } } return coord_config 9m81cs3y17195esoyrvlp0xb6mqp8wf 782003 782002 2013-10-22T12:07:16Z Rotpunkt 14696 +commento 782003 Scribunto text/plain local coord_config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri "pagename", "params" e "title" coord_config.geohackUrl = "http://tools.wmflabs.org/geohack/geohack.php?language=it" -- Nomi categorie di servizio coord_config.categorie = { -- inserita quando ci sono errori nei parametri ["warning"] = "Errori di compilazione del template Coord" } -- Tipo/valore accettato per i parametri posizionali, -- per ciascuno dei quattro schemi di input dei dati ("dec", "d", "dm" o "dms") -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, coord_config.params = { -- {{coord|10|20}} ["dec"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "longd", -180, 180 }, }, -- {{coord|10|N|20|E}} ["d"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "string", "latc", "N", "S" }, [3] = { "number", "longd", 0, 180 }, [4] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|N|20|30|E}} ["dm"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "string", "latc", "N", "S" }, [4] = { "number", "longd", 0, 180 }, [5] = { "number", "longm", 0, 59 }, [6] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|30|N|20|30|40|E}} ["dms"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "number", "lats", 0, 59 }, [4] = { "string", "latc", "N", "S" }, [5] = { "number", "longd", 0, 180 }, [6] = { "number", "longm", 0, 59 }, [7] = { "number", "longs", 0, 59 }, [8] = { "string", "longc", "E", "W" }, } } return coord_config skzt1p2t0icggaps2hxxrwbf99myvqj 782004 782003 2013-11-10T17:26:07Z Rotpunkt 14696 rinominata config 782004 Scribunto text/plain local config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri "pagename", "params" e "title" config.geohackUrl = "http://tools.wmflabs.org/geohack/geohack.php?language=it" -- Nomi categorie di servizio config.categorie = { -- inserita quando ci sono errori nei parametri ["warning"] = "Errori di compilazione del template Coord" } -- Tipo/valore accettato per i parametri posizionali, -- per ciascuno dei quattro schemi di input dei dati ("dec", "d", "dm" o "dms") -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, config.params = { -- {{coord|10|20}} ["dec"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "longd", -180, 180 }, }, -- {{coord|10|N|20|E}} ["d"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "string", "latc", "N", "S" }, [3] = { "number", "longd", 0, 180 }, [4] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|N|20|30|E}} ["dm"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "string", "latc", "N", "S" }, [4] = { "number", "longd", 0, 180 }, [5] = { "number", "longm", 0, 59 }, [6] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|30|N|20|30|40|E}} ["dms"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "number", "lats", 0, 59 }, [4] = { "string", "latc", "N", "S" }, [5] = { "number", "longd", 0, 180 }, [6] = { "number", "longm", 0, 59 }, [7] = { "number", "longs", 0, 59 }, [8] = { "string", "longc", "E", "W" }, } } return config o637jcycjqzxnlgby2iffqqpy5lde8m 782005 782004 2013-12-22T12:01:03Z Bultro 2731 Ha protetto "[[Modulo:Coord/Configurazione]]": Template o modulo usato in maniera estensiva ([Modifica=Consentito solo agli amministratori] (infinito) [Spostamento=Consentito solo agli amministratori] (infinito)) 782004 Scribunto text/plain local config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri "pagename", "params" e "title" config.geohackUrl = "http://tools.wmflabs.org/geohack/geohack.php?language=it" -- Nomi categorie di servizio config.categorie = { -- inserita quando ci sono errori nei parametri ["warning"] = "Errori di compilazione del template Coord" } -- Tipo/valore accettato per i parametri posizionali, -- per ciascuno dei quattro schemi di input dei dati ("dec", "d", "dm" o "dms") -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, config.params = { -- {{coord|10|20}} ["dec"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "longd", -180, 180 }, }, -- {{coord|10|N|20|E}} ["d"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "string", "latc", "N", "S" }, [3] = { "number", "longd", 0, 180 }, [4] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|N|20|30|E}} ["dm"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "string", "latc", "N", "S" }, [4] = { "number", "longd", 0, 180 }, [5] = { "number", "longm", 0, 59 }, [6] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|30|N|20|30|40|E}} ["dms"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "number", "lats", 0, 59 }, [4] = { "string", "latc", "N", "S" }, [5] = { "number", "longd", 0, 180 }, [6] = { "number", "longm", 0, 59 }, [7] = { "number", "longs", 0, 59 }, [8] = { "string", "longc", "E", "W" }, } } return config o637jcycjqzxnlgby2iffqqpy5lde8m 782006 782005 2014-11-12T13:57:12Z Rotpunkt 14696 aggiornato all'uso dei tab 782006 Scribunto text/plain local config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri "pagename", "params" e "title" config.geohackUrl = "http://tools.wmflabs.org/geohack/geohack.php?language=it" -- Nomi categorie di servizio config.categorie = { -- inserita quando ci sono errori nei parametri ["warning"] = "Errori di compilazione del template Coord" } -- Tipo/valore accettato per i parametri posizionali, -- per ciascuno dei quattro schemi di input dei dati ("dec", "d", "dm" o "dms") -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, config.params = { -- {{coord|10|20}} ["dec"] = { [1] = { "number", "latd", -90, 90 }, [2] = { "number", "longd", -180, 180 }, }, -- {{coord|10|N|20|E}} ["d"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "string", "latc", "N", "S" }, [3] = { "number", "longd", 0, 180 }, [4] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|N|20|30|E}} ["dm"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "string", "latc", "N", "S" }, [4] = { "number", "longd", 0, 180 }, [5] = { "number", "longm", 0, 59 }, [6] = { "string", "longc", "E", "W" }, }, -- {{coord|10|20|30|N|20|30|40|E}} ["dms"] = { [1] = { "number", "latd", 0, 90 }, [2] = { "number", "latm", 0, 59 }, [3] = { "number", "lats", 0, 59 }, [4] = { "string", "latc", "N", "S" }, [5] = { "number", "longd", 0, 180 }, [6] = { "number", "longm", 0, 59 }, [7] = { "number", "longs", 0, 59 }, [8] = { "string", "longc", "E", "W" }, } } return config 2mb8h8itk2njyk8f3bkduoqcknnnopz 782007 782006 2015-06-12T05:03:14Z Rotpunkt 14696 virgolette 782007 Scribunto text/plain local config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri pagename, params e title config.geohackUrl = 'http://tools.wmflabs.org/geohack/geohack.php?language=it' -- Nomi categorie di servizio config.categorie = { -- inserita quando ci sono errori nei parametri warning = 'Errori di compilazione del template Coord' } -- Tipo/valore accettato per i parametri posizionali, -- per ciascuno dei quattro schemi di input dei dati (dec, d, dm o dms) -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, config.params = { -- {{coord|10|20}} dec = { [1] = { 'number', 'latd', -90, 90 }, [2] = { 'number', 'longd', -180, 180 }, }, -- {{coord|10|N|20|E}} d = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'string', 'latc', 'N', 'S' }, [3] = { 'number', 'longd', 0, 180 }, [4] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|N|20|30|E}} dm = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'string', 'latc', 'N', 'S' }, [4] = { 'number', 'longd', 0, 180 }, [5] = { 'number', 'longm', 0, 59 }, [6] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|30|N|20|30|40|E}} dms = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'number', 'lats', 0, 59 }, [4] = { 'string', 'latc', 'N', 'S' }, [5] = { 'number', 'longd', 0, 180 }, [6] = { 'number', 'longm', 0, 59 }, [7] = { 'number', 'longs', 0, 59 }, [8] = { 'string', 'longc', 'E', 'W' }, } } return config t4g6ro65s8v69l3dy1jmrg7f8f3c3xz 782008 782007 2016-03-31T12:52:43Z Rotpunkt 14696 aggiornato modulo 782008 Scribunto text/plain local config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri pagename, params e title config.geohackUrl = 'http://tools.wmflabs.org/geohack/geohack.php?language=it' -- Tipo/valore accettato per i parametri posizionali, -- per ciascuno dei quattro schemi di input dei dati (dec, d, dm o dms) -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, config.params = { -- {{coord|10|20}} dec = { [1] = { 'number', 'latd', -90, 90 }, [2] = { 'number', 'longd', -180, 180 }, }, -- {{coord|10|N|20|E}} d = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'string', 'latc', 'N', 'S' }, [3] = { 'number', 'longd', 0, 180 }, [4] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|N|20|30|E}} dm = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'string', 'latc', 'N', 'S' }, [4] = { 'number', 'longd', 0, 180 }, [5] = { 'number', 'longm', 0, 59 }, [6] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|30|N|20|30|40|E}} dms = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'number', 'lats', 0, 59 }, [4] = { 'string', 'latc', 'N', 'S' }, [5] = { 'number', 'longd', 0, 180 }, [6] = { 'number', 'longm', 0, 59 }, [7] = { 'number', 'longs', 0, 59 }, [8] = { 'string', 'longc', 'E', 'W' }, } } return config 5uw8w3kr07ms0wld6leuslvtkbmh4y5 782009 782008 2018-07-18T20:12:25Z Rotpunkt 14696 aggiornato geohackUrl a https 782009 Scribunto text/plain local config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri pagename, params e title config.geohackUrl = 'https://tools.wmflabs.org/geohack/geohack.php?language=it' -- Tipo/valore accettato per i parametri posizionali, -- per ciascuno dei quattro schemi di input dei dati (dec, d, dm o dms) -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, config.params = { -- {{coord|10|20}} dec = { [1] = { 'number', 'latd', -90, 90 }, [2] = { 'number', 'longd', -180, 180 }, }, -- {{coord|10|N|20|E}} d = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'string', 'latc', 'N', 'S' }, [3] = { 'number', 'longd', 0, 180 }, [4] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|N|20|30|E}} dm = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'string', 'latc', 'N', 'S' }, [4] = { 'number', 'longd', 0, 180 }, [5] = { 'number', 'longm', 0, 59 }, [6] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|30|N|20|30|40|E}} dms = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'number', 'lats', 0, 59 }, [4] = { 'string', 'latc', 'N', 'S' }, [5] = { 'number', 'longd', 0, 180 }, [6] = { 'number', 'longm', 0, 59 }, [7] = { 'number', 'longs', 0, 59 }, [8] = { 'string', 'longc', 'E', 'W' }, } } return config e9ujjtp05nb3tq628s5xdac9eamuoja 782010 781998 2026-05-13T10:18:32Z GiovanniPen 22308 11 rivisioni mpurtati di [[:it:Modulo:Coord/Configurazione]] 781998 Scribunto text/plain return require [[Mòdulu:Coord/Config]] fv6i9l2eir11ckm523w7022x00n69ck 782014 782010 2026-05-13T10:19:16Z GiovanniPen 22308 preparo per spostamento 782014 Scribunto text/plain local config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri pagename, params e title config.geohackUrl = 'https://tools.wmflabs.org/geohack/geohack.php?language=it' -- Tipo/valore accettato per i parametri posizionali, -- per ciascuno dei quattro schemi di input dei dati (dec, d, dm o dms) -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, config.params = { -- {{coord|10|20}} dec = { [1] = { 'number', 'latd', -90, 90 }, [2] = { 'number', 'longd', -180, 180 }, }, -- {{coord|10|N|20|E}} d = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'string', 'latc', 'N', 'S' }, [3] = { 'number', 'longd', 0, 180 }, [4] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|N|20|30|E}} dm = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'string', 'latc', 'N', 'S' }, [4] = { 'number', 'longd', 0, 180 }, [5] = { 'number', 'longm', 0, 59 }, [6] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|30|N|20|30|40|E}} dms = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'number', 'lats', 0, 59 }, [4] = { 'string', 'latc', 'N', 'S' }, [5] = { 'number', 'longd', 0, 180 }, [6] = { 'number', 'longm', 0, 59 }, [7] = { 'number', 'longs', 0, 59 }, [8] = { 'string', 'longc', 'E', 'W' }, } } return config e9ujjtp05nb3tq628s5xdac9eamuoja 782015 782014 2026-05-13T10:19:34Z GiovanniPen 22308 GiovanniPen spustau la pàggina [[Mòdulu:Coord/Configurazione]] nni [[Mòdulu:Coord/Config]] 782014 Scribunto text/plain local config = {} -- URL base di GeoHack, a cui vengono aggiunti i parametri pagename, params e title config.geohackUrl = 'https://tools.wmflabs.org/geohack/geohack.php?language=it' -- Tipo/valore accettato per i parametri posizionali, -- per ciascuno dei quattro schemi di input dei dati (dec, d, dm o dms) -- { "tipo (number o string)", "nome nel messaggio d'errore", min/max (numeri) o valori accettati (stringhe) }, config.params = { -- {{coord|10|20}} dec = { [1] = { 'number', 'latd', -90, 90 }, [2] = { 'number', 'longd', -180, 180 }, }, -- {{coord|10|N|20|E}} d = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'string', 'latc', 'N', 'S' }, [3] = { 'number', 'longd', 0, 180 }, [4] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|N|20|30|E}} dm = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'string', 'latc', 'N', 'S' }, [4] = { 'number', 'longd', 0, 180 }, [5] = { 'number', 'longm', 0, 59 }, [6] = { 'string', 'longc', 'E', 'W' }, }, -- {{coord|10|20|30|N|20|30|40|E}} dms = { [1] = { 'number', 'latd', 0, 90 }, [2] = { 'number', 'latm', 0, 59 }, [3] = { 'number', 'lats', 0, 59 }, [4] = { 'string', 'latc', 'N', 'S' }, [5] = { 'number', 'longd', 0, 180 }, [6] = { 'number', 'longm', 0, 59 }, [7] = { 'number', 'longs', 0, 59 }, [8] = { 'string', 'longc', 'E', 'W' }, } } return config e9ujjtp05nb3tq628s5xdac9eamuoja Mòdulu:Coord/Config/man 828 67418 782011 2013-10-20T15:16:19Z Rotpunkt 14696 Nuova pagina 782011 wikitext text/x-wiki {{Man modulo}} Modulo Lua di supporto a [[Modulo:Coord]]. Contiene la configurazione principale del modulo. <includeonly>[[Categoria:Moduli]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> ergi354c5tt7eybre8qoabymuqj51co 782012 782011 2014-12-15T16:18:29Z Rotpunkt 14696 +template protetta 782012 wikitext text/x-wiki {{Man modulo}} Modulo Lua di supporto a [[Modulo:Coord]]. Contiene la configurazione principale del modulo. <includeonly>{{Protetta}}[[Categoria:Moduli]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> hqa7hjeil93l8nidprusxah86e0z4dt 782013 782012 2026-05-13T10:18:33Z GiovanniPen 22308 2 rivisioni mpurtati di [[:it:Modulo:Coord/Configurazione/man]] 782012 wikitext text/x-wiki {{Man modulo}} Modulo Lua di supporto a [[Modulo:Coord]]. Contiene la configurazione principale del modulo. <includeonly>{{Protetta}}[[Categoria:Moduli]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> hqa7hjeil93l8nidprusxah86e0z4dt 782017 782013 2026-05-13T10:19:34Z GiovanniPen 22308 GiovanniPen spustau la pàggina [[Mòdulu:Coord/Configurazione/man]] nni [[Mòdulu:Coord/Config/man]] 782012 wikitext text/x-wiki {{Man modulo}} Modulo Lua di supporto a [[Modulo:Coord]]. Contiene la configurazione principale del modulo. <includeonly>{{Protetta}}[[Categoria:Moduli]]</includeonly> <noinclude>[[Categoria:Manuali dei moduli]]</noinclude> hqa7hjeil93l8nidprusxah86e0z4dt 782019 782017 2026-05-13T10:21:16Z GiovanniPen 22308 inizio traduzione 782019 wikitext text/x-wiki {{Man mòdulu}} Mòdulu Lua di supporto a [[Mòdulu:Coord]]. Contiene la configurazione principale del mòdulu. <includeonly>{{Prutetta}}[[Catigurìa:Moduli]]</includeonly> <noinclude>[[Catigurìa:Manuali dei moduli]]</noinclude> ikja4z0wr9cf7iaxlq84sbqd6cohssj Mòdulu:Coord/Configurazione 828 67419 782016 2026-05-13T10:19:34Z GiovanniPen 22308 GiovanniPen spustau la pàggina [[Mòdulu:Coord/Configurazione]] nni [[Mòdulu:Coord/Config]] 782016 Scribunto text/plain return require [[Mòdulu:Coord/Config]] fv6i9l2eir11ckm523w7022x00n69ck Mòdulu:Coord/Configurazione/man 828 67420 782018 2026-05-13T10:19:34Z GiovanniPen 22308 GiovanniPen spustau la pàggina [[Mòdulu:Coord/Configurazione/man]] nni [[Mòdulu:Coord/Config/man]] 782018 wikitext text/x-wiki #RINVIA [[Mòdulu:Coord/Config/man]] odvr0pkzpto4rwrtx1fj8pen9xhv68r Mòdulu:Coord/styles.css 828 67421 782020 2019-08-25T12:15:58Z Laurentius 692 scorporo da MediaWiki:Common.css e MediaWiki:Mobile.css 782020 sanitized-css text/css /* Classi utilizzate per mostrare le coordinate geografiche ([[Modulo:Coord]], [[Template:Coord]] e altri template basati su questi). Le classi "geo", "longitude" e "latitude" non sono solo stili, ma vengono riconosciute da [[Geo (microformat)]], non eliminare o rinominare. Vedere [[Template:Coord#Personalizzare_la_visualizzazione]] per visualizzare sempre in formato decimale o sessagesimale. */ .geo-default, .geo-dms, .geo-dec { display: inline; } .geo-nondefault, .geo-multi-punct { display: none; } .latitude, .longitude { white-space: nowrap; } .geo { } nzie93i1xxbrecc8skzhvm639hht98y 782021 782020 2019-08-25T12:25:47Z Laurentius 692 Protetto "[[Modulo:Coord/styles.css]]": Template o modulo usato in maniera estensiva: come il modulo e i template che lo richiamano ([Modifica=Consentito solo agli amministratori] (infinito) [Spostamento=Consentito solo agli amministratori] (infinito)) 782020 sanitized-css text/css /* Classi utilizzate per mostrare le coordinate geografiche ([[Modulo:Coord]], [[Template:Coord]] e altri template basati su questi). Le classi "geo", "longitude" e "latitude" non sono solo stili, ma vengono riconosciute da [[Geo (microformat)]], non eliminare o rinominare. Vedere [[Template:Coord#Personalizzare_la_visualizzazione]] per visualizzare sempre in formato decimale o sessagesimale. */ .geo-default, .geo-dms, .geo-dec { display: inline; } .geo-nondefault, .geo-multi-punct { display: none; } .latitude, .longitude { white-space: nowrap; } .geo { } nzie93i1xxbrecc8skzhvm639hht98y 782022 782021 2020-05-27T20:32:24Z Sakretsu 24659 sposto da [[MediaWiki:Vector.css]] 782022 sanitized-css text/css /* Classi utilizzate per mostrare le coordinate geografiche ([[Modulo:Coord]], [[Template:Coord]] e altri template basati su questi). Le classi "geo", "longitude" e "latitude" non sono solo stili, ma vengono riconosciute da [[Geo (microformat)]], non eliminare o rinominare. Vedere [[Template:Coord#Personalizzare_la_visualizzazione]] per visualizzare sempre in formato decimale o sessagesimale. */ .geo-default, .geo-dms, .geo-dec { display: inline; } .geo-nondefault, .geo-multi-punct { display: none; } .latitude, .longitude { white-space: nowrap; } .geo { } body.skin-vector #coordinates { font-size: 85%; line-height: 1.5em; position: absolute; right: 0; top: 0; white-space: nowrap; } cgu5pg3548i7n8h1bxzqzsc4q2j5vfr 782023 782022 2021-03-21T22:30:41Z Sakretsu 24659 +Protetta 782023 sanitized-css text/css /* {{Protetta}} */ /* Classi utilizzate per mostrare le coordinate geografiche ([[Modulo:Coord]], [[Template:Coord]] e altri template basati su questi). Le classi "geo", "longitude" e "latitude" non sono solo stili, ma vengono riconosciute da [[Geo (microformat)]], non eliminare o rinominare. Vedere [[Template:Coord#Personalizzare_la_visualizzazione]] per visualizzare sempre in formato decimale o sessagesimale. */ .geo-default, .geo-dms, .geo-dec { display: inline; } .geo-nondefault, .geo-multi-punct { display: none; } .latitude, .longitude { white-space: nowrap; } .geo { } body.skin-vector #coordinates { font-size: 85%; line-height: 1.5em; position: absolute; right: 0; top: 0; white-space: nowrap; } 2hse4jn6xb02shh5dmcdb5n643fm1aw 782024 782023 2024-05-26T17:04:11Z Daimona Eaytoy 24232 Personalizzazione non più disponibile con kartographer. Potrà essere reimplementata con un accessorio, se ce ne fosse bisogno. Il microformat geo è nascosto e non gli servono stili (non è chiaro se da nascosto funzioni, ma la documentazione è a dir poco carente) 782024 sanitized-css text/css /* {{Protetta}} */ /* Classi utilizzate per mostrare le coordinate geografiche ([[Modulo:Coord]], [[Template:Coord]] e altri template basati su questi). */ body.skin-vector #coordinates { font-size: 85%; line-height: 1.5em; position: absolute; right: 0; top: 0; white-space: nowrap; } gzkdy3mczu2wuvlcde9ka5hqgup14z9 782025 782024 2024-05-26T22:57:21Z Daimona Eaytoy 24232 posizionamento assoluto non più necessario 782025 sanitized-css text/css /* {{Protetta}} */ /* Classi utilizzate per mostrare le coordinate geografiche ([[Modulo:Coord]], [[Template:Coord]] e altri template basati su questi). */ body.skin-vector #coordinates { font-size: 85%; line-height: 1.5em; white-space: nowrap; } 5jjvfysbbho2i2ukyu0xew842z9p3uy 782026 782025 2026-05-13T10:22:35Z GiovanniPen 22308 6 rivisioni mpurtati di [[:it:Modulo:Coord/styles.css]] 782025 sanitized-css text/css /* {{Protetta}} */ /* Classi utilizzate per mostrare le coordinate geografiche ([[Modulo:Coord]], [[Template:Coord]] e altri template basati su questi). */ body.skin-vector #coordinates { font-size: 85%; line-height: 1.5em; white-space: nowrap; } 5jjvfysbbho2i2ukyu0xew842z9p3uy