Wikipedia gvwiki https://gv.wikipedia.org/wiki/Ard-ghuillag MediaWiki 1.47.0-wmf.5 first-letter Meanyn Er lheh Resooney Ymmydeyr Resooney ymmydeyr Wikipedia Resooney Wikipedia Coadan Resooney coadan MediaWiki Resooney MediaWiki Clowan Resooney clowan Cooney Resooney cooney Ronney Resooney ronney TimedText TimedText talk Module Module talk Event Event talk Ronney:Ruggyryn 'sy vlein 1770 14 3379 382098 348057 2026-06-05T00:09:53Z MacTire02 219 clowan noa 382098 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1756 14 3623 382106 348068 2026-06-05T00:17:11Z MacTire02 219 clowan noa 382106 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1813 14 3627 382165 347856 2026-06-05T01:12:11Z MacTire02 219 clowan noa 382165 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1811 14 3638 382163 347863 2026-06-05T01:11:37Z MacTire02 219 clowan noa 382163 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1856 14 3839 382200 347922 2026-06-05T01:25:53Z MacTire02 219 clowan noa 382200 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1819 14 3845 382171 347846 2026-06-05T01:18:53Z MacTire02 219 clowan noa 382171 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1735 14 3854 382117 348089 2026-06-05T00:25:52Z MacTire02 219 clowan noa 382117 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1954 14 3856 382296 347715 2026-06-05T01:56:09Z MacTire02 219 clowan noa 382296 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1918 14 3857 382260 347783 2026-06-05T01:47:33Z MacTire02 219 clowan noa 382260 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1951 14 3858 382293 347720 2026-06-05T01:54:58Z MacTire02 219 clowan noa 382293 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1926 14 3861 382268 347767 2026-06-05T01:49:00Z MacTire02 219 clowan noa 382268 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1961 14 3862 382303 347708 2026-06-05T01:59:12Z MacTire02 219 clowan noa 382303 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1956 14 3863 382298 347713 2026-06-05T01:57:23Z MacTire02 219 clowan noa 382298 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1946 14 3864 382288 381299 2026-06-05T01:53:54Z MacTire02 219 clowan noa 382288 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1953 14 3866 382295 347717 2026-06-05T01:56:00Z MacTire02 219 clowan noa 382295 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1945 14 3867 382287 381293 2026-06-05T01:53:46Z MacTire02 219 clowan noa 382287 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1983 14 3881 382325 381033 2026-06-05T02:05:47Z MacTire02 219 clowan noa 382325 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1987 14 3886 382329 381029 2026-06-05T02:06:35Z MacTire02 219 clowan noa 382329 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1732 14 3888 382119 348093 2026-06-05T00:26:17Z MacTire02 219 clowan noa 382119 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1988 14 3893 382330 381028 2026-06-05T02:06:44Z MacTire02 219 clowan noa 382330 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1936 14 3896 382278 347751 2026-06-05T01:52:01Z MacTire02 219 clowan noa 382278 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1974 14 3899 382316 347694 2026-06-05T02:02:46Z MacTire02 219 clowan noa 382316 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1812 14 3905 382164 347860 2026-06-05T01:11:52Z MacTire02 219 clowan noa 382164 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1818 14 3910 382170 347844 2026-06-05T01:16:41Z MacTire02 219 clowan noa 382170 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1903 14 3914 382245 381077 2026-06-05T01:43:09Z MacTire02 219 clowan noa 382245 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1952 14 3919 382294 347718 2026-06-05T01:55:43Z MacTire02 219 clowan noa 382294 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1935 14 3924 382277 347750 2026-06-05T01:51:05Z MacTire02 219 clowan noa 382277 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1932 14 3932 382274 347742 2026-06-05T01:50:40Z MacTire02 219 clowan noa 382274 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1882 14 3934 382226 347992 2026-06-05T01:33:15Z MacTire02 219 clowan noa 382226 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1960 14 3938 382302 347709 2026-06-05T01:58:51Z MacTire02 219 clowan noa 382302 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1970 14 3940 382312 347698 2026-06-05T02:01:45Z MacTire02 219 clowan noa 382312 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1958 14 3942 382300 347711 2026-06-05T01:58:27Z MacTire02 219 clowan noa 382300 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1949 14 3944 382291 381289 2026-06-05T01:54:37Z MacTire02 219 clowan noa 382291 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1943 14 3946 382285 381298 2026-06-05T01:53:19Z MacTire02 219 clowan noa 382285 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1942 14 3950 382284 347732 2026-06-05T01:53:06Z MacTire02 219 clowan noa 382284 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1934 14 3952 382276 347747 2026-06-05T01:50:56Z MacTire02 219 clowan noa 382276 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1940 14 4130 382282 381306 2026-06-05T01:52:44Z MacTire02 219 clowan noa 382282 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1937 14 4141 382279 347752 2026-06-05T01:52:10Z MacTire02 219 clowan noa 382279 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1892 14 4173 382234 380930 2026-06-05T01:35:26Z MacTire02 219 clowan noa 382234 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1881 14 4185 382225 347996 2026-06-05T01:33:05Z MacTire02 219 clowan noa 382225 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1963 14 4265 382305 347706 2026-06-05T01:59:34Z MacTire02 219 clowan noa 382305 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1980 14 4284 382322 381037 2026-06-05T02:05:19Z MacTire02 219 clowan noa 382322 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1962 14 4296 382304 347707 2026-06-05T01:59:25Z MacTire02 219 clowan noa 382304 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1981 14 4304 382323 381035 2026-06-05T02:05:31Z MacTire02 219 clowan noa 382323 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1990 14 4337 382332 380970 2026-06-05T02:07:05Z MacTire02 219 clowan noa 382332 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1978 14 4357 382320 347688 2026-06-05T02:04:17Z MacTire02 219 clowan noa 382320 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1955 14 4360 382297 347714 2026-06-05T01:56:47Z MacTire02 219 clowan noa 382297 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1982 14 4369 382324 381034 2026-06-05T02:05:39Z MacTire02 219 clowan noa 382324 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1979 14 4374 382321 347687 2026-06-05T02:04:27Z MacTire02 219 clowan noa 382321 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1965 14 4382 382307 347704 2026-06-05T02:01:06Z MacTire02 219 clowan noa 382307 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1911 14 4419 382253 347796 2026-06-05T01:44:51Z MacTire02 219 clowan noa 382253 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1757 14 4451 382105 348067 2026-06-05T00:11:28Z MacTire02 219 clowan noa 382105 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1758 14 4462 382104 348077 2026-06-05T00:11:15Z MacTire02 219 clowan noa 382104 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1751 14 4472 382109 348073 2026-06-05T00:17:47Z MacTire02 219 clowan noa 382109 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1815 14 4477 382167 347851 2026-06-05T01:16:04Z MacTire02 219 clowan noa 382167 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1790 14 4483 382146 348036 2026-06-05T01:01:59Z MacTire02 219 clowan noa 382146 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1865 14 4490 382208 347942 2026-06-05T01:27:43Z MacTire02 219 clowan noa 382208 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1928 14 4566 382270 347762 2026-06-05T01:49:21Z MacTire02 219 clowan noa 382270 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1833 14 4577 382182 347886 2026-06-05T01:22:53Z MacTire02 219 clowan noa 382182 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1841 14 4581 382188 347910 2026-06-05T01:23:49Z MacTire02 219 clowan noa 382188 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1840 14 4593 382187 347911 2026-06-05T01:23:40Z MacTire02 219 clowan noa 382187 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1948 14 4608 382290 380793 2026-06-05T01:54:29Z MacTire02 219 clowan noa 382290 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1938 14 4726 382280 347754 2026-06-05T01:52:24Z MacTire02 219 clowan noa 382280 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Harral Godwinson 0 4739 382350 348284 2026-06-05T02:14:43Z MacTire02 219 kishtey fys elley 382350 wikitext text/x-wiki {{WD Kishtey Fys Dooinney}} Va '''Harral Godwinson''' ny yn '''Ree Harral II''' ([[Shenn Vaarle]]: ''Harold Gōdwines sunu''; m. 1022 &ndash; 14 Jerrey Fouyir 1066) ny Ree [[Sostyn|Hostyn]] er feiy traa giare eddyr baase [[Edard Feyshtyney]] as ruegys ny [[Ny Normanee|Normanagh]] as goaill magh pooar da [[Illiam I Hostyn]]. Hooar eh baase ayns [[Cah Hastings]] 'sy vlein 1066. {{gurneil eaghtyrys}} {{DEFAULTSORT:Harold Godwinson}} [[Ronney:Ruggyryn ayns ny 1020yn]] [[Ronney:Baaseyn 'sy vlein 1066]] [[Ronney:Blein ruggyree gyn fys]] [[Ronney:Monarkyn Sostynagh]] [[Ronney:Monarkyn Anglo-Loghlynagh]] [[Ronney:Anglo-Hostnee]] [[Ronney:Feallee chaggee Anglo-Hostnagh]] [[Ronney:Anglo-Hostnee va marrooit ayns caggey]] [[Ronney:Eearlaghyn Anglia Hiar]] [[Ronney:Eearlaghyn Herefordshire]] [[Ronney:Eearlaghyn Wessex]] [[Ronney:Sostynee jeh sluight Danvargagh]] [[Ronney:Catolee Raueagh Hostynagh]] [[Ronney:Reeraghtys Godwin]] [[Ronney:Monarkyn va marrooit ayns caggey]] [[Ronney:Monarkyn Hostyn roish 1066]] [[Ronney:Barriaght Normanagh er Sostyn]] [[Ronney:Feallee ass Bosham]] {{bun}} eljmt231ca2dcsqrnre9540reuz0fd0 Ronney:Ruggyryn 'sy vlein 1723 14 4751 382122 348100 2026-06-05T00:26:51Z MacTire02 219 clowan noa 382122 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Illiam II y Ghermaan 0 4756 382352 346498 2026-06-05T03:05:10Z MacTire02 219 ++ 382352 wikitext text/x-wiki {{WD Kishtey Fys Dooinney}} Va '''Illiam II''' (27 Jerrey Geuree 1859 &ndash; 4 Boaldyn 1941) n'Impir jerrinagh ny [[Yn Ghermaan|Germaan]] as Ree yn [[Yn Phroosh|Proosh]]. V'eh y fer stiuree veih 15 Mean Souree 1888 derrey 9 Mee Houney 1918. Véh ruggit ayns [[Berleen]] 'sy Phroosh as hooar eh baase ayns [[Doorn]] 'syn [[Yn Ollan|Ollan]]. ==Kianglaghyn magh== {{commons category|Wilhelm II of Germany|Illiam II y Ghermaan}} * [https://archive.org/details/germanemperorass00gausuoft ''The German Emperor as shown in his public utterances''] * {{Citation | url = https://books.google.com/books?id=ywZoAAAAMAAJ | title = My Memoirs: 1878–1918 | first = William II | last = Hohenzollern | place = Lunnin| publisher = Cassell & Co | year = 1922 | ref = none}}, Google Books. * [https://archive.org/details/germanemperorssp00willuoft ''The German emperor's speeches: being a selection from the speeches, edicts, letters, and telegrams of the Emperor William II''] * {{Gutenberg author|id=42274}} * {{Internet Archive author |search=("William II, German Emperor" OR "Wilhelm II")}}, 'sy Ghermaanisjh er y chooid smoo * {{Cite EB1911|wstitle= William II. of Germany |volume= 28 | pages = 667–669 |short= 1}} * {{Cite EB1922 |wstitle= William II. of Hohenzollern |volume= 32 |last= Saunders |first= George |author-link= George Saunders|short= 1}} * [http://www.europeanfilmgateway.eu/node/33/efg1914%20wilhelm/multilingual:1/showOnly:video Docamadyn fillym shenndeeagh bentyn rish Illiam II veih traa yn Chied Chaggey Dowanagh] ec [[European Film Gateway]] * {{PM20|FID=pe/023777}} * [http://www.oldmagazinearticles.com/article-summary/summary_and_review_of_MY_MEMOIR_by_Kaiser_Wilhelm The 1922 book review of ''My Memoir'' veih ''The Spectator''] * {{NPG name|name=Wilhelm II, Emperor of Germany and King of Prussia}} * {{IMDb name|0435118|Kaiser Wilhelm II}} {{S-start}} {{S-hou|[[Reeraghtys Hohenzollern]]|27 Jerrey Geuree|1859|4 Mean Souree|1941}} {{S-break}} {{S-reg}} {{S-break}} {{S-bef|before=[[Ferdorraghey III, Impir y Ghermaan|Ferdorraghey III]]}} {{S-ttl|title=[[Impir y Ghermaan]]<br>[[Ree yn Phroosh]]|years=15 Mean Souree 1888 – 9 Mee Houney 1918}} {{S-vac|reason=[[Bun-chaghlaa yn Ghermaan|scryssey magh y vonarkaght]]}} {{S-break}} {{S-off}} {{S-break}} {{S-bef|before=[[Ferdorraghey III, Impir y Ghermaan|Ferdorraghey III]]|as=[[Impir y Ghermaan]]<br>as [[Ree yn Phroosh]]}} {{S-ttl|title=Kione steat y Ghermaan<br>Kione steat y Phroosh|as=[[Rolley monarkyn y Ghermaan|Impir y Ghermaan]]|years=15 Mean Souree 1888 – 9 Mee Houney 1918}} {{S-aft|after=[[Friedrich Ebert]]|as=[[Eaghtyrane y Ghermaan (1919–1945)|Eaghtyrane y Ghermaan]]<br>as [[Ard-vinishter y Phroosh]]}} {{S-break}} {{S-pre}} {{S-break}} {{S-new|loss|reason=[[Pobblaght Weimar|Pobblaght fogrit magh]]}} {{S-tul|title=[[Impir y Ghermaan]]<br>[[Ree yn Phroosh]]|years=9 Mee Houney 1918 – 4 Mean Souree 1941|reason=[[Bun-chaghlaa yn Ghermaan]]}} {{S-aft|after=[[Illiam y Phroosh]]}} {{S-end}} {{Reireyderyn eiraghtagh jerrinagh ayns Impiraght y Ghermaan}} {{Monarkyn y Ghermaan}} {{Reireyderyn y Phroosh}} {{King-steat y Ghermaan}} {{Pretenders to the German and Prussian thrones since 1918}} {{Fowderyn y Chrosh Vooar}} {{Prinseyn Prooshagh}} {{gurneil eaghtyrys}} {{DEFAULTSORT:Illiam 02}} [[Ronney:Illiam II y Ghermaan| ]] [[Ronney:Ruggyryn 'sy vlein 1859]] [[Ronney:Baaseyn 'sy vlein 1941]] [[Ronney:Monarkyn y 19oo eash]] [[Ronney:King steat y Ghermaan 'sy 20oo eash]] [[Ronney:Monarkyn y 20oo eash 'syn Oarpey]] [[Ronney:Reeghyn y Phroosh 'sy 19oo eash]] [[Ronney:Smooinaght noi-Hostynagh 'syn Oarpey]] [[Ronney:Cremeyderyn y Vasoonys]] [[Ronney:Noi-Ewnaghys 'sy Ghermaan]] [[Ronney:Paitçhyn lesh Ferdorraghey III, Impir y Ghermaan]] [[Ronney:Prinseyn crooinagh y Phroosh]] [[Ronney:Monarkyn goit veih'n troyn]] [[Ronney:Reeoilid 'syn eebyrt]] [[Ronney:Noi-chummynee Ghermaanagh]] [[Ronney:Sheiltynee cho-chialg Ghermaanagh]] [[Ronney:Impiryn y Ghermaan]] [[Ronney:Germaanee eebrit]] [[Ronney:Eebyrtee Ghermaanagh 'sy Çheer Injil]] [[Ronney:Lutheree Ghermaanagh]] [[Ronney:Ashoonaghteyryn Germaanagh]] [[Ronney:Germaanee jeh sluight Sostynagh]] [[Ronney:Politickeyryn Germaanagh as anlheiltyssyn oc]] [[Ronney:Shellooderyn as sheelreyderyn cabbil roie Germaanagh]] [[Ronney:Reeoilid as ooashlid Ghermaanagh as anlheiltyssyn oc]] [[Ronney:Jantee chynney-ghunverys ny Herero as ny Nama]] [[Ronney:Reeraghtys Hohenzollern]] [[Ronney:Reeghyn y Phroosh]] [[Ronney:Monarchs who abdicated]] [[Ronney:Reeoilid ass Berleen]] [[Ronney:Feallee ass Berleen]] [[Ronney:Feallee ass Doorn]] [[Ronney:Feallee chaill nyn geimyn onnoroil]] [[Ronney:Aggyrtee]] [[Ronney:Mec lesh impiryn]] [[Ronney:Ard-chaptanyn y Spaainey]] <!-- Onnoryn --> [[Ronney:Fowderyn Chrosh Vooar y Chrosh Yiarn]] [[Ronney:Fowderyn Pour le Mérite (keim chaggee)]] [[Ronney:Croshyn Mooarey Oardyr Caggee Max Joseph]] [[Ronney:Fowderyn y Chrosh Hanseatagh (Bremen)]] [[Ronney:Fowderyn y Chrosh Hanseatagh (Hamburg)]] [[Ronney:Fowderyn y Chrosh Hanseatagh (Lübeck)]] [[Ronney:Croshyn Mooarey Oardyr Noo Steaon yn Ungaar]] [[Ronney:Croshyn Mooarey Oardyr Caggee Maria Theresa]] [[Ronney:Fowderyn Oardyr y Dunnalys, 1d cheim]] [[Ronney:Fowderyn Chrosh Onnor Oardyr y Dannebrog]] [[Ronney:Reejereeyn Chrosh Vooar Oardyr ny Nooghyn Mwirrish as Lazarus]] [[Ronney:Reejereeyn Chrosh Vooar Oardyr Caggee Savoie]] [[Ronney:Fowderyn Oardyr Leoin y Çheer Injil]] [[Ronney:Reejereeyn Chrosh Vooar Oardyr Caggee Illiam]] [[Ronney:Croshyn Mooarey Oardyr Reeraghtys Oranje]] [[Ronney:Reejereeyn Oardyr y Leoin Norlynnagh]] [[Ronney:Croshyn Mooarey Oardyr Chreest (y Phortiugal)|2]] [[Ronney:Croshyn Mooarey Oardyr Aviz|2]] [[Ronney:Fowderyn Oardyr yn Urley Bane (y Roosh)]] [[Ronney:Fowderyn Oardyr Noo Anna, 1d cheim]] [[Ronney:Fowderyn Oardyr Noo Stanislaus (y Roosh), 1d cheim]] [[Ronney:Reejereeyn Loamrey Airhey yn Spaainey]] [[Ronney:Anneyderyn Chrosh Vooar Oardyr Vasa]] [[Ronney:Reejereeyn Chrosh Vooar Onnoroil Oardyr Reeoil Victoria mooghit]] [[Ronney:Sur-reejereeyn Cooidjaghtagh y Chribbyl]] [[Ronney:Reejereeyn Cairys Oardyr Eoin]] [[Ronney:Croshyn Mooarey Oardyr Chrosh y Teyrsnys]] [[Ronney:Toshee pholitickagh 'sy Chied Chaggey Dowanagh]] [[Ronney:Feallee ayns Geyre-ghaue Yerrey Souree]] 8hk3k9vlmcjkil6sqwyr4tejsa2bdma Ronney:Ruggyryn 'sy vlein 1930 14 4780 382272 347736 2026-06-05T01:50:17Z MacTire02 219 clowan noa 382272 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1822 14 4784 382173 347867 2026-06-05T01:20:52Z MacTire02 219 clowan noa 382173 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1884 14 4786 382228 347987 2026-06-05T01:33:40Z MacTire02 219 clowan noa 382228 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1986 14 4892 382328 381030 2026-06-05T02:06:23Z MacTire02 219 clowan noa 382328 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1984 14 4913 382326 381032 2026-06-05T02:06:00Z MacTire02 219 clowan noa 382326 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1989 14 4925 382331 381008 2026-06-05T02:06:54Z MacTire02 219 clowan noa 382331 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1859 14 4943 382203 347914 2026-06-05T01:26:29Z MacTire02 219 clowan noa 382203 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1910 14 5075 382252 381415 2026-06-05T01:44:41Z MacTire02 219 clowan noa 382252 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1870 14 5206 382213 381525 2026-06-05T01:30:15Z MacTire02 219 clowan noa 382213 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1799 14 5224 382152 348026 2026-06-05T01:05:43Z MacTire02 219 clowan noa 382152 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1890 14 5233 382232 380932 2026-06-05T01:35:09Z MacTire02 219 clowan noa 382232 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1885 14 5316 382229 347984 2026-06-05T01:33:53Z MacTire02 219 clowan noa 382229 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1964 14 5349 382306 380794 2026-06-05T02:00:59Z MacTire02 219 clowan noa 382306 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1971 14 5407 382313 347697 2026-06-05T02:01:53Z MacTire02 219 clowan noa 382313 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1975 14 5413 382317 347693 2026-06-05T02:02:57Z MacTire02 219 clowan noa 382317 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1985 14 5419 382327 381031 2026-06-05T02:06:09Z MacTire02 219 clowan noa 382327 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1991 14 5454 382333 380533 2026-06-05T02:07:14Z MacTire02 219 clowan noa 382333 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1973 14 5658 382315 347695 2026-06-05T02:02:36Z MacTire02 219 clowan noa 382315 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1855 14 5968 382199 347924 2026-06-05T01:25:45Z MacTire02 219 clowan noa 382199 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1972 14 6287 382314 347696 2026-06-05T02:02:04Z MacTire02 219 clowan noa 382314 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1810 14 6451 382162 347845 2026-06-05T01:10:50Z MacTire02 219 clowan noa 382162 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1824 14 6455 382175 347872 2026-06-05T01:21:16Z MacTire02 219 clowan noa 382175 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1852 14 6558 382196 347931 2026-06-05T01:25:19Z MacTire02 219 clowan noa 382196 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1925 14 6563 382267 347768 2026-06-05T01:48:52Z MacTire02 219 clowan noa 382267 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1874 14 6567 382218 381529 2026-06-05T01:31:21Z MacTire02 219 clowan noa 382218 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1879 14 6574 382223 347954 2026-06-05T01:32:38Z MacTire02 219 clowan noa 382223 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1857 14 6608 382201 347919 2026-06-05T01:26:01Z MacTire02 219 clowan noa 382201 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1883 14 6609 382227 347989 2026-06-05T01:33:26Z MacTire02 219 clowan noa 382227 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1887 14 6612 382230 347983 2026-06-05T01:34:19Z MacTire02 219 clowan noa 382230 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1868 14 6617 382211 347936 2026-06-05T01:29:48Z MacTire02 219 clowan noa 382211 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1743 14 6693 382113 348084 2026-06-05T00:21:12Z MacTire02 219 clowan noa 382113 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1767 14 6711 382100 348059 2026-06-05T00:10:17Z MacTire02 219 clowan noa 382100 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1782 14 6716 382143 348041 2026-06-05T01:01:35Z MacTire02 219 clowan noa 382143 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1773 14 6718 382097 348054 2026-06-05T00:09:41Z MacTire02 219 clowan noa 382097 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1795 14 6738 382150 348031 2026-06-05T01:05:25Z MacTire02 219 clowan noa 382150 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1784 14 6746 382144 348044 2026-06-05T01:01:43Z MacTire02 219 clowan noa 382144 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1800 14 6753 382153 347823 2026-06-05T01:05:52Z MacTire02 219 clowan noa 382153 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1804 14 6767 382156 380951 2026-06-05T01:06:24Z MacTire02 219 clowan noa 382156 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1791 14 6775 382147 348034 2026-06-05T01:02:07Z MacTire02 219 clowan noa 382147 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1809 14 6777 382161 380955 2026-06-05T01:10:41Z MacTire02 219 clowan noa 382161 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1808 14 6781 382160 347837 2026-06-05T01:10:31Z MacTire02 219 clowan noa 382160 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1831 14 6788 382180 347892 2026-06-05T01:22:27Z MacTire02 219 clowan noa 382180 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1829 14 6790 382178 347876 2026-06-05T01:21:59Z MacTire02 219 clowan noa 382178 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1837 14 6792 382185 347882 2026-06-05T01:23:21Z MacTire02 219 clowan noa 382185 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1843 14 6812 382190 347905 2026-06-05T01:24:09Z MacTire02 219 clowan noa 382190 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1858 14 6815 382202 347915 2026-06-05T01:26:10Z MacTire02 219 clowan noa 382202 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1872 14 6851 382215 347973 2026-06-05T01:30:37Z MacTire02 219 clowan noa 382215 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1917 14 6888 382259 380617 2026-06-05T01:47:13Z MacTire02 219 clowan noa 382259 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1908 14 6892 382250 381064 2026-06-05T01:44:22Z MacTire02 219 clowan noa 382250 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1913 14 6897 382255 347794 2026-06-05T01:45:10Z MacTire02 219 clowan noa 382255 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1924 14 6905 382266 347771 2026-06-05T01:48:43Z MacTire02 219 clowan noa 382266 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1877 14 7204 382221 347958 2026-06-05T01:31:58Z MacTire02 219 clowan noa 382221 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1896 14 7387 382238 380918 2026-06-05T01:41:24Z MacTire02 219 clowan noa 382238 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1820 14 7433 382172 347865 2026-06-05T01:19:18Z MacTire02 219 clowan noa 382172 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1894 14 8012 382236 380924 2026-06-05T01:41:01Z MacTire02 219 clowan noa 382236 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1912 14 8182 382254 380597 2026-06-05T01:45:01Z MacTire02 219 clowan noa 382254 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1916 14 8186 382258 347787 2026-06-05T01:47:03Z MacTire02 219 clowan noa 382258 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1860 14 8190 382204 347952 2026-06-05T01:26:52Z MacTire02 219 clowan noa 382204 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1905 14 8198 382247 347810 2026-06-05T01:43:33Z MacTire02 219 clowan noa 382247 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1923 14 8200 382265 347774 2026-06-05T01:48:34Z MacTire02 219 clowan noa 382265 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1944 14 8236 382286 347730 2026-06-05T01:53:30Z MacTire02 219 clowan noa 382286 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1947 14 8257 382289 381291 2026-06-05T01:54:17Z MacTire02 219 clowan noa 382289 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1899 14 8260 382241 380902 2026-06-05T01:42:14Z MacTire02 219 clowan noa 382241 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1863 14 13006 382206 347947 2026-06-05T01:27:14Z MacTire02 219 clowan noa 382206 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1832 14 13043 382181 347888 2026-06-05T01:22:39Z MacTire02 219 clowan noa 382181 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1853 14 13145 382197 347927 2026-06-05T01:25:28Z MacTire02 219 clowan noa 382197 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1889 14 13299 382231 347980 2026-06-05T01:34:31Z MacTire02 219 clowan noa 382231 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1907 14 13960 382249 381070 2026-06-05T01:44:12Z MacTire02 219 clowan noa 382249 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1775 14 14402 382095 348050 2026-06-05T00:08:14Z MacTire02 219 clowan noa 382095 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1915 14 14607 382257 347791 2026-06-05T01:45:28Z MacTire02 219 clowan noa 382257 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1933 14 14619 382275 347744 2026-06-05T01:50:48Z MacTire02 219 clowan noa 382275 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1848 14 14620 382194 347899 2026-06-05T01:24:58Z MacTire02 219 clowan noa 382194 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1891 14 15054 382233 380898 2026-06-05T01:35:17Z MacTire02 219 clowan noa 382233 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1920 14 15078 382262 347778 2026-06-05T01:48:08Z MacTire02 219 clowan noa 382262 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1807 14 15254 382159 380945 2026-06-05T01:10:22Z MacTire02 219 clowan noa 382159 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1898 14 15317 382240 380906 2026-06-05T01:41:58Z MacTire02 219 clowan noa 382240 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1750 14 15389 382110 348075 2026-06-05T00:18:11Z MacTire02 219 clowan noa 382110 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a John Joseph Kneen 0 15444 382217 346138 2026-06-05T01:31:09Z MacTire02 219 -parameadar 382217 wikitext text/x-wiki {{WD Kishtey Fys Dooinney | ennym = John Joseph Kneen | boayl_ruggyr = [[Doolish]], [[Mannin]] | boayl_baaish = Doolish, Mannin | date_baaish = {{date baaish as eash|df=y|1938|11|21|1873|9|12}} | ashoonaght = [[Manninee|Manninagh]] }} She [[çhengoaylleeaght|çhengoayllee]] [[Manninee|Manninagh]] va '''John Joseph Kneen''' (12 Mean Fouyir 1873 &ndash; 21 Sauin 1938<ref name="manxnotebook">{{cite web | title = Brief Biography of John Joseph Kneen 1873-1938 | url = http://www.isle-of-man.com/manxnotebook/people/antiqarn/jjkneen.htm | publisher = Manx Notebook | accessdate = 15 Averil 2011 | language = Baarle }}</ref>). Ta enney mooar er son yn obbyr va jeant echey er son y [[Gaelg|Ghaelg]] ayns [[Mannin]], goaill stiagh studeyryssyn er sliennooyn, enmyn, boayl-enmyn Manninagh as grammeydys y Ghaelg. She eshyn ren çhyndaa [[Arrane Ashoonagh dy Vannin]] 'sy vlein 1907.<ref name="manxnotebook"/><ref>{{cite web | title = Manx National Anthem (Arrane Ashoonagh dy Vannin) | url = http://www.manxheritagemusic.org/Pdf/ManxNatAnth.pdf | format = pdf | publisher = Manx Heritage Music | accessdate = 15 Averil 2011 | language = Baarle }}</ref> Va'n arrane shen screeuit 'sy Vaarle as va'n chiaull cummit ec [[William Henry Gill]]. ==Seihll as coorse beaghee== Rug Kneen er Straid Hanover, [[Doolish]], er 12 Mean Fouyir 1873. She mac lesh yn 'er post John Kneen as e ven heshee Hannah Crebbin v'eh. V'eh ynsit ayns Scoill Shorys Noo fo stiurey yn 'er ynsee Mnr. Nichols. Tra v'eh ayn, daase anaase mooar echey 'sy Ghaelg. Va anaase mooar ec e phaarantyn, as lesh cooney voue, hooar eh cooid vooar d'oayllys tradishoonagh assdaue. Ren eh poosey daa cheayrt. Phoos eh rish Margaret Ann Tasker er 24 Mean Souree 1902.<ref name="IoMNHAS">{{cite journal | journal = Proceedings of the Isle of Man Natural History and Antiquarian Society | title = J. J. Kneen, M.A. | date = 1939 | accessdate = 16 Averil 2011 | language = Baarle | location = Doolish | pages = dg. 322 | publisher = Manx Notebook}}</ref><ref>{{cite web | url = http://www.iomfhs.im/lawsons/marriages/kn-01.html | title = Index of Marriages / Kneale - Knox | accessdate = 16 Averil 2011 | language = Baarle | publisher = The Isle of Man Family History Society | archivedate = 2016-03-05 | archiveurl = https://web.archive.org/web/20160305014538/http://www.iomfhs.im/lawsons/marriages/kn-01.html }}</ref> Phoos eh da'n nah cheayrt rish Alice Bridson er 6 Jerrey Souree 1930, as va daa vac, James as Harold, as un inneen, Winifred, oc. Hoshee eh screeu 'sy phabyr naight ''[[Isle of Man Examiner]]'' cha leah as 1895, tra nagh row eh agh 22 vleeaney d'eash. 'Sy vlein 1897 ren Loayreyder y Chiare as Feed, [[Arthur William Moore|A. W. Moore]], goaill tastey er ny cohoyrtyssyn echey 'sy phabyr, as va shiartanse dy whaaltyssyn jeant eddyr yn daa jeu. Daa vlein ny lurg ren ad cur er bun [[yn Çheshaght Ghailckagh]] (YCG). Haink er dy ve ny eaghtyrane er y çheshaght shen, chammah as eaghtyrane er yn Isle of Man History and Antiquarian Society.<ref name="IoMNHAS"/> Chur yn obbyr echey lesh YCG cree mooar ayn ayns freiltys y çhengey as ayns studeyrys er [[beeal-arrish]] as [[Shennaghys Vannin|shennaghys]] yn çheer echey. Ren eh screeu ram lioareenyn as ren eh cummey lesoonyn da scoillaryn y çhengey. Va ram daanyn as hymnyn çhyndaait echey. Va paart mooar echey ayns cur magh lhieggan noa as lhiassit jeh Fockleyr Chregeen, as beggan ny lurg ren eh cur magh fockleyr echey hene, ''Manx-English Pronouncing Dictionary''. 'Sy vlein 1910 ren eh cur magh yn obbyr share echey - ''A Grammar of the Manx Language''. Ren eh cur er tashtey yn laue-screeuyn ayns Lioarlann Thie Tashtee Vannin 'sy vlein 1927 er-yn-oyr nagh row mie dy liooar argid echey son yn obbyr y chlou. Va'n laue-screeuyn currit gys tastey ny Treishteilee 'sy lioarlann. V'eh er credjal ec ny Treishteilee shen dy row scansh vooar ec yn laue-screeuyn as hie ad gys Tinvaal son argid y gheddyn dy chur magh eh. Hug Tinvaal £250 dauesyn er e hon shen as hie yn lioar er ny chur magh 'sy vlein 1930. Car lhing y [[Yn Chied Chaggey Dowanagh|chaggey]] hoshee eh screeu noteyn mychione boayl-enmyn yn Ellan, as obbyr A. W. Moore myr bun da. Va'n clane obbyr creaghnit echey 'sy vlein 1923, as ren eh cur yn stoo roish y Çheshaght Ghailckagh. Ren y çheshaght scarrey yn obbyr ayns shey ayrnyn - fer da dagh sheadin - as hie ad er nyn glou ayns ym-lioaryn er lheh eddyr ny bleeantyn 1925 as 1928. Va ny shirveishyn echey lesh lettyraght Vannin currit er enney liorish [[Ollooscoill Lerphoyll]] 'sy vlein 1929 tra va Mainshtyr ny h-Ellynyn (M.A.) bronnit er. 'Sy vlein 1930 va'n obbyr echey er blaystyn [[Ny Loghlynee|Loghlynagh]] ayns kynney, shennaghys, as çhengey Vannin currit er enney ec y reiltys Norlynnagh trooid cleayney yn Olloo [[Carl Marstrander]] ass [[Ollooscoill Oslo]] as hug ad £200. Va'n argid shen jeerit da freayltys ny ronsaghtyn echey as son recortys cruinn jeh fockley magh ynnydagh jeh ny boayl-enmyn y gheddyn roish baase yn Ghaelg vio. Reesht er moylley yn Olloo Marstrander, va [[Oardyr Auley Noo|Reejerys jeh Oardyr Auley Noo]] bronnit er liorish [[Haakon VII Norlynn|Haakon VII]], Ree Norlynn. ==Obbraghyn== * ''Arrane Ashoonagh dy Vannin'' (1907; çhyndaa) * ''The Place Names of the Isle of Man, with their Origin and History'' (1926) * ''A Grammar of the Manx Language'' (1931) * ''Mona's Herald' English-Manx Pronouncing Dictionary'' (1938) ==Imraaghyn== ===Symnaghyn=== {{rolleyimraaghyn}} ===Farraneyn=== * {{MNB1885}} {{Gurneil eaghtyrys}} {{DEFAULTSORT:Kneen, John Joseph}} [[Ronney:Ruggyryn 'sy vlein 1873]] [[Ronney:Baaseyn 'sy vlein 1938]] [[Ronney:Cummeyderyn Manninagh]] [[Ronney:Çhengoaylleeyn Manninagh]] [[Ronney:Screeudeyryn firryn Manninagh]] [[Ronney:Fockleyreyderyn Manninagh]] [[Ronney:Dramadeyryn as screeudeyryn cloie Manninagh]] [[Ronney:Feallee ass Doolish]] pp9rrw34snbptyci4pzj54mehynwiov Ronney:Ruggyryn 'sy vlein 1873 14 15451 382216 381514 2026-06-05T01:30:47Z MacTire02 219 clowan noa 382216 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1992 14 17111 382334 380986 2026-06-05T02:07:23Z MacTire02 219 clowan noa 382334 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1906 14 17164 382248 347807 2026-06-05T01:43:58Z MacTire02 219 clowan noa 382248 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1969 14 17510 382311 380760 2026-06-05T02:01:36Z MacTire02 219 clowan noa 382311 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1959 14 17624 382301 347710 2026-06-05T01:58:36Z MacTire02 219 clowan noa 382301 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1701 14 18583 382140 348123 2026-06-05T00:54:49Z MacTire02 219 clowan noa 382140 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1921 14 18612 382263 347777 2026-06-05T01:48:18Z MacTire02 219 clowan noa 382263 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1838 14 18647 382186 347879 2026-06-05T01:23:31Z MacTire02 219 clowan noa 382186 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1922 14 19107 382264 347775 2026-06-05T01:48:26Z MacTire02 219 clowan noa 382264 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1929 14 19108 382271 347757 2026-06-05T01:49:35Z MacTire02 219 clowan noa 382271 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1999 14 19109 382341 380990 2026-06-05T02:08:24Z MacTire02 219 clowan noa 382341 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1919 14 19110 382261 381413 2026-06-05T01:47:46Z MacTire02 219 clowan noa 382261 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1864 14 19765 382207 347945 2026-06-05T01:27:30Z MacTire02 219 clowan noa 382207 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1939 14 20672 382281 380778 2026-06-05T01:52:34Z MacTire02 219 clowan noa 382281 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1996 14 20875 382338 381001 2026-06-05T02:08:00Z MacTire02 219 clowan noa 382338 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1927 14 20878 382269 347765 2026-06-05T01:49:10Z MacTire02 219 clowan noa 382269 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1995 14 20972 382337 380974 2026-06-05T02:07:52Z MacTire02 219 clowan noa 382337 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1993 14 20973 382335 380982 2026-06-05T02:07:33Z MacTire02 219 clowan noa 382335 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1994 14 20974 382336 380978 2026-06-05T02:07:43Z MacTire02 219 clowan noa 382336 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1997 14 20975 382339 380997 2026-06-05T02:08:09Z MacTire02 219 clowan noa 382339 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1998 14 20976 382340 347663 2026-06-05T02:08:16Z MacTire02 219 clowan noa 382340 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 2001 14 20977 382343 380637 2026-06-05T02:08:41Z MacTire02 219 clowan noa 382343 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1803 14 20999 382155 380949 2026-06-05T01:06:14Z MacTire02 219 clowan noa 382155 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1842 14 21025 382189 347907 2026-06-05T01:23:59Z MacTire02 219 clowan noa 382189 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1909 14 21035 382251 380911 2026-06-05T01:44:32Z MacTire02 219 clowan noa 382251 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 2004 14 21066 382346 380540 2026-06-05T02:09:06Z MacTire02 219 clowan noa 382346 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1823 14 21070 382174 347870 2026-06-05T01:21:02Z MacTire02 219 clowan noa 382174 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1867 14 21078 382210 347939 2026-06-05T01:29:39Z MacTire02 219 clowan noa 382210 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1844 14 21083 382191 347902 2026-06-05T01:24:21Z MacTire02 219 clowan noa 382191 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1707 14 21109 382138 348118 2026-06-05T00:53:03Z MacTire02 219 clowan noa 382138 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1941 14 21122 382283 381302 2026-06-05T01:52:57Z MacTire02 219 clowan noa 382283 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1967 14 21123 382309 381045 2026-06-05T02:01:21Z MacTire02 219 clowan noa 382309 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1977 14 21191 382319 347691 2026-06-05T02:04:06Z MacTire02 219 clowan noa 382319 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1966 14 21192 382308 347703 2026-06-05T02:01:13Z MacTire02 219 clowan noa 382308 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1950 14 21193 382292 347723 2026-06-05T01:54:48Z MacTire02 219 clowan noa 382292 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1904 14 21194 382246 381074 2026-06-05T01:43:22Z MacTire02 219 clowan noa 382246 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1902 14 21195 382244 381081 2026-06-05T01:42:47Z MacTire02 219 clowan noa 382244 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1900 14 21196 382242 381065 2026-06-05T01:42:27Z MacTire02 219 clowan noa 382242 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1878 14 21197 382222 381509 2026-06-05T01:32:26Z MacTire02 219 clowan noa 382222 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1862 14 21198 382205 347951 2026-06-05T01:27:02Z MacTire02 219 clowan noa 382205 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1854 14 21199 382198 347926 2026-06-05T01:25:36Z MacTire02 219 clowan noa 382198 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1816 14 21200 382168 347850 2026-06-05T01:16:13Z MacTire02 219 clowan noa 382168 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1780 14 21201 382142 348039 2026-06-05T01:01:27Z MacTire02 219 clowan noa 382142 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1774 14 21202 382096 348052 2026-06-05T00:08:28Z MacTire02 219 clowan noa 382096 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1749 14 21203 382111 348078 2026-06-05T00:20:55Z MacTire02 219 clowan noa 382111 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 2000 14 21976 382342 380635 2026-06-05T02:08:32Z MacTire02 219 clowan noa 382342 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1814 14 22185 382166 347853 2026-06-05T01:12:20Z MacTire02 219 clowan noa 382166 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1901 14 22233 382243 381085 2026-06-05T01:42:36Z MacTire02 219 clowan noa 382243 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1968 14 22426 382310 347700 2026-06-05T02:01:28Z MacTire02 219 clowan noa 382310 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1976 14 22943 382318 347692 2026-06-05T02:03:09Z MacTire02 219 clowan noa 382318 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 2003 14 23303 382345 380592 2026-06-05T02:08:57Z MacTire02 219 clowan noa 382345 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1957 14 23311 382299 347712 2026-06-05T01:58:20Z MacTire02 219 clowan noa 382299 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 2002 14 23982 382344 380600 2026-06-05T02:08:48Z MacTire02 219 clowan noa 382344 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1931 14 24395 382273 347741 2026-06-05T01:50:32Z MacTire02 219 clowan noa 382273 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1805 14 24736 382157 380959 2026-06-05T01:06:34Z MacTire02 219 clowan noa 382157 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 2006 14 26109 382348 380602 2026-06-05T02:09:29Z MacTire02 219 clowan noa 382348 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1734 14 26130 382118 348092 2026-06-05T00:26:06Z MacTire02 219 clowan noa 382118 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1826 14 26137 382177 347875 2026-06-05T01:21:44Z MacTire02 219 clowan noa 382177 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1851 14 26267 382195 347934 2026-06-05T01:25:09Z MacTire02 219 clowan noa 382195 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Module:Citation/CS1/Whitelist 828 26976 382127 317171 2026-06-05T00:39:53Z MacTire02 219 ++ 382127 Scribunto text/plain --[[--------------------------< S U P P O R T E D P A R A M E T E R S >-------------------------------------- Because a steady-state signal conveys no useful information, whitelist.basic_arguments[] list items can have three values: true - these parameters are valid and supported parameters false - these parameters are deprecated but still supported tracked - these parameters are valid and supported parameters tracked in an eponymous properties category nil - these parameters are no longer supported. remove entirely ]] local basic_arguments_t = { ['accessdate'] = true, ['access-date'] = true, ['agency'] = true, ['archivedate'] = true, ['archive-date'] = true, ['archive-format'] = true, ['archiveurl'] = true, ['archive-url'] = true, ['article'] = true, ['article-format'] = true, ['article-number'] = true, -- {{cite journal}}, {{cite conference}}; {{citation}} when |journal= has a value ['article-url'] = true, ['article-url-access'] = true, ['arxiv'] = true, -- cite arxiv; here because allowed in cite ... as identifier ['asin'] = true, ['ASIN'] = true, ['asin-tld'] = true, ['at'] = true, ['author'] = true, ['author-first'] = true, ['author-given'] = true, ['author-last'] = true, ['author-surname'] = true, ['authorlink'] = true, ['author-link'] = true, ['author-mask'] = true, ['bibcode'] = true, ['bibcode-access'] = true, ['biorxiv'] = true, -- cite biorxiv; here because allowed in cite ... as identifier ['chapter'] = true, ['chapter-format'] = true, ['chapter-url'] = true, ['chapter-url-access'] = true, ['citeseerx'] = true, -- cite citeseerx; here because allowed in cite ... as identifier ['collaboration'] = true, ['contribution'] = true, ['contribution-format'] = true, ['contribution-url'] = true, ['contribution-url-access'] = true, ['contributor'] = true, ['contributor-first'] = true, ['contributor-given'] = true, ['contributor-last'] = true, ['contributor-surname'] = true, ['contributor-link'] = true, ['contributor-mask'] = true, ['date'] = true, ['department'] = true, ['df'] = true, ['dictionary'] = true, ['display-authors'] = true, ['display-contributors'] = true, ['display-editors'] = true, ['display-interviewers'] = true, ['display-subjects'] = true, ['display-translators'] = true, ['doi'] = true, ['DOI'] = true, ['doi-access'] = true, ['doi-broken-date'] = true, ['edition'] = true, ['editor'] = true, ['editor-first'] = true, ['editor-given'] = true, ['editor-last'] = true, ['editor-surname'] = true, ['editor-link'] = true, ['editor-mask'] = true, ['eissn'] = true, ['EISSN'] = true, ['encyclopaedia'] = true, ['encyclopedia'] = true, ['entry'] = true, ['entry-format'] = true, ['entry-url'] = true, ['entry-url-access'] = true, ['eprint'] = true, -- cite arxiv; here because allowed in cite ... as identifier ['first'] = true, ['format'] = true, ['given'] = true, ['hdl'] = true, ['HDL'] = true, ['hdl-access'] = true, ['host'] = true, -- unique to certain templates? ['id'] = true, ['ID'] = true, ['institution'] = true, -- constrain to cite thesis? ['interviewer'] = true, ['interviewer-first'] = true, ['interviewer-given'] = true, ['interviewer-last'] = true, ['interviewer-surname'] = true, ['interviewer-link'] = true, ['interviewer-mask'] = true, ['isbn'] = true, ['ISBN'] = true, ['ismn'] = true, ['ISMN'] = true, ['issn'] = true, ['ISSN'] = true, ['issue'] = true, ['jfm'] = true, ['JFM'] = true, ['journal'] = true, ['jstor'] = true, ['JSTOR'] = true, ['jstor-access'] = true, ['lang'] = true, ['language'] = true, ['last'] = true, ['lccn'] = true, ['LCCN'] = true, ['location'] = true, ['magazine'] = true, ['medium'] = true, ['medrxiv'] = true, -- cite medrxiv; here because allowed in cite ... as identifier ['minutes'] = true, -- constrain to cite AV media and podcast? ['mode'] = true, ['mr'] = true, ['MR'] = true, ['name-list-style'] = true, ['newspaper'] = true, ['no-pp'] = true, ['no-tracking'] = true, ['number'] = true, ['oclc'] = true, ['OCLC'] = true, ['ol'] = true, ['OL'] = true, ['ol-access'] = true, ['orig-date'] = true, ['origyear'] = true, ['orig-year'] = true, ['osti'] = true, ['OSTI'] = true, ['osti-access'] = true, ['others'] = true, ['p'] = true, ['page'] = true, ['pages'] = true, ['periodical'] = true, ['place'] = true, ['pmc'] = true, ['PMC'] = true, ['pmc-embargo-date'] = true, ['pmid'] = true, ['PMID'] = true, ['postscript'] = true, ['pp'] = true, ['publication-date'] = true, ['publication-place'] = true, ['publisher'] = true, ['quotation'] = true, ['quote'] = true, ['quote-page'] = true, ['quote-pages'] = true, ['ref'] = true, ['rfc'] = true, ['RFC'] = true, ['sbn'] = true, ['SBN'] = true, ['scale'] = true, ['script-article'] = true, ['script-chapter'] = true, ['script-contribution'] = true, ['script-encyclopaedia'] = true, ['script-encyclopedia'] = true, ['script-entry'] = true, ['script-journal'] = true, ['script-magazine'] = true, ['script-newspaper'] = true, ['script-periodical'] = true, ['script-quote'] = true, ['script-section'] = true, ['script-title'] = true, ['script-website'] = true, ['script-work'] = true, ['section'] = true, ['section-format'] = true, ['section-url'] = true, ['section-url-access'] = true, ['series'] = true, ['ssrn'] = true, -- cite ssrn; these three here because allowed in cite ... as identifier ['SSRN'] = true, ['ssrn-access'] = true, ['subject'] = true, ['subject-first'] = true, ['subject-given'] = true, ['subject-last'] = true, ['subject-link'] = true, ['subject-mask'] = true, ['subject-surname'] = true, ['surname'] = true, ['s2cid'] = true, ['S2CID'] = true, ['s2cid-access'] = true, ['template-doc-demo'] = true, ['time'] = true, -- constrain to cite av media and podcast? ['time-caption'] = true, -- constrain to cite av media and podcast? ['title'] = true, ['title-link'] = true, ['title-note'] = true, ['translator'] = true, ['translator-first'] = true, ['translator-given'] = true, ['translator-last'] = true, ['translator-surname'] = true, ['translator-link'] = true, ['translator-mask'] = true, ['trans-article'] = true, ['trans-chapter'] = true, ['trans-contribution'] = true, ['trans-encyclopaedia'] = true, ['trans-encyclopedia'] = true, ['trans-entry'] = true, ['trans-journal'] = true, ['trans-magazine'] = true, ['trans-newspaper'] = true, ['trans-periodical'] = true, ['trans-quote'] = true, ['trans-section'] = true, ['trans-title'] = true, ['trans-website'] = true, ['trans-work'] = true, ['type'] = true, ['url'] = true, ['URL'] = true, ['url-access'] = true, ['url-status'] = true, ['vauthors'] = true, ['veditors'] = true, ['version'] = true, ['via'] = true, ['volume'] = true, ['website'] = true, ['work'] = true, ['year'] = true, ['zbl'] = true, ['ZBL'] = true, } local numbered_arguments_t = { ['author#'] = true, ['author-first#'] = true, ['author#-first'] = true, ['author-given#'] = true, ['author#-given'] = true, ['author-last#'] = true, ['author#-last'] = true, ['author-surname#'] = true, ['author#-surname'] = true, ['author-link#'] = true, ['author#-link'] = true, ['authorlink#'] = true, ['author#link'] = true, ['author-mask#'] = true, ['author#-mask'] = true, ['contributor#'] = true, ['contributor-first#'] = true, ['contributor#-first'] = true, ['contributor-given#'] = true, ['contributor#-given'] = true, ['contributor-last#'] = true, ['contributor#-last'] = true, ['contributor-surname#'] = true, ['contributor#-surname'] = true, ['contributor-link#'] = true, ['contributor#-link'] = true, ['contributor-mask#'] = true, ['contributor#-mask'] = true, ['editor#'] = true, ['editor-first#'] = true, ['editor#-first'] = true, ['editor-given#'] = true, ['editor#-given'] = true, ['editor-last#'] = true, ['editor#-last'] = true, ['editor-surname#'] = true, ['editor#-surname'] = true, ['editor-link#'] = true, ['editor#-link'] = true, ['editor-mask#'] = true, ['editor#-mask'] = true, ['first#'] = true, ['given#'] = true, ['host#'] = true, ['interviewer#'] = true, ['interviewer-first#'] = true, ['interviewer#-first'] = true, ['interviewer-given#'] = true, ['interviewer#-given'] = true, ['interviewer-last#'] = true, ['interviewer#-last'] = true, ['interviewer-surname#'] = true, ['interviewer#-surname'] = true, ['interviewer-link#'] = true, ['interviewer#-link'] = true, ['interviewer-mask#'] = true, ['interviewer#-mask'] = true, ['last#'] = true, ['subject#'] = true, ['subject-first#'] = true, ['subject#-first'] = true, ['subject-given#'] = true, ['subject#-given'] = true, ['subject-last#'] = true, ['subject#-last'] = true, ['subject-link#'] = true, ['subject#-link'] = true, ['subject-mask#'] = true, ['subject#-mask'] = true, ['subject-surname#'] = true, ['subject#-surname'] = true, ['surname#'] = true, ['translator#'] = true, ['translator-first#'] = true, ['translator#-first'] = true, ['translator-given#'] = true, ['translator#-given'] = true, ['translator-last#'] = true, ['translator#-last'] = true, ['translator-surname#'] = true, ['translator#-surname'] = true, ['translator-link#'] = true, ['translator#-link'] = true, ['translator-mask#'] = true, ['translator#-mask'] = true, } --[[--------------------------< P R E P R I N T S U P P O R T E D P A R A M E T E R S >-------------------- Cite arXiv, cite biorxiv, cite citeseerx, cite medrxiv, and cite ssrn are preprint templates that use the limited set of parameters defined in the limited_basic_arguments and limited_numbered_arguments tables. Those lists are supplemented with a template-specific list of parameters that are required by the particular template and may be exclusive to one of the preprint templates. Some of these parameters may also be available to the general cs1|2 templates. Same conventions for true/false/tracked/nil as above. ]] local preprint_arguments_t = { arxiv = { ['arxiv'] = true, -- cite arxiv and arxiv identifiers ['class'] = true, ['eprint'] = true, -- cite arxiv and arxiv identifiers }, biorxiv = { ['biorxiv'] = true, }, citeseerx = { ['citeseerx'] = true, }, medrxiv = { ['medrxiv'] = true, }, ssrn = { ['ssrn'] = true, ['SSRN'] = true, ['ssrn-access'] = true, }, } --[[--------------------------< L I M I T E D S U P P O R T E D P A R A M E T E R S >---------------------- cite arxiv, cite biorxiv, cite citeseerx, cite medrxiv, and cite ssrn templates are preprint templates so are allowed only a limited subset of parameters allowed to all other cs1|2 templates. The limited subset is defined here. This list of parameters also used by {{cite document}} Same conventions for true/false/tracked/nil as above. ]] local limited_basic_arguments_t = { ['at'] = true, ['author'] = true, ['author-first'] = true, ['author-given'] = true, ['author-last'] = true, ['author-surname'] = true, ['author-link'] = true, ['authorlink'] = true, ['author-mask'] = true, ['collaboration'] = true, ['date'] = true, ['df'] = true, ['display-authors'] = true, ['first'] = true, ['given'] = true, ['language'] = true, ['last'] = true, ['mode'] = true, ['name-list-style'] = true, ['no-tracking'] = true, ['p'] = true, ['page'] = true, ['pages'] = true, ['postscript'] = true, ['pp'] = true, ['quotation'] = true, ['quote'] = true, ['ref'] = true, ['surname'] = true, ['template-doc-demo'] = true, ['title'] = true, ['trans-title'] = true, ['vauthors'] = true, ['year'] = true, } local limited_numbered_arguments_t = { ['author#'] = true, ['author-first#'] = true, ['author#-first'] = true, ['author-given#'] = true, ['author#-given'] = true, ['author-last#'] = true, ['author#-last'] = true, ['author-surname#'] = true, ['author#-surname'] = true, ['author-link#'] = true, ['author#-link'] = true, ['authorlink#'] = true, ['author#link'] = true, ['author-mask#'] = true, ['author#-mask'] = true, ['first#'] = true, ['given#'] = true, ['last#'] = true, ['surname#'] = true, } --[[--------------------------< U N I Q U E _ A R G U M E N T S >---------------------------------------------- Some templates have unique parameters. Those templates and their unique parameters are listed here. Keys in this table are the template's CitationClass parameter value Same conventions for true/false/tracked/nil as above. ]] local unique_arguments_t = { ['audio-visual'] = { ['people'] = true, ['transcript'] = true, ['transcript-format'] = true, ['transcript-url'] = true, }, conference = { ['book-title'] = true, ['conference'] = true, ['conference-format'] = true, ['conference-url'] = true, ['event'] = true, }, episode = { ['airdate'] = true, ['air-date'] = true, ['credits'] = true, ['episode-link'] = true, -- alias of |title-link= ['network'] = true, ['people'] = true, ['season'] = true, ['series-link'] = true, ['series-no'] = true, ['series-number'] = true, ['station'] = true, ['transcript'] = true, ['transcript-format'] = true, ['transcript-url'] = true, }, mailinglist = { ['mailing-list'] = true, }, map = { ['cartography'] = true, ['inset'] = true, ['map'] = true, ['map-format'] = true, ['map-url'] = true, ['map-url-access'] = true, ['script-map'] = true, ['sections'] = true, ['sheet'] = true, ['sheets'] = true, ['trans-map'] = true, }, newsgroup = { ['message-id'] = true, ['newsgroup'] = true, }, report = { ['docket'] = true, }, serial = { ['airdate'] = true, ['air-date'] = true, ['credits'] = true, ['episode'] = true, -- cite serial only TODO: make available to cite episode? ['episode-link'] = true, -- alias of |title-link= ['network'] = true, ['people'] = true, ['series-link'] = true, ['station'] = true, }, speech = { ['conference'] = true, ['conference-format'] = true, ['conference-url'] = true, ['event'] = true, }, thesis = { ['degree'] = true, ['docket'] = true, }, } --[[--------------------------< C I T E _ D O C U M E N T >---------------------------------------------------- Special case for cite document. This template takes the limited basic and limited enumerated parameters plus others that are apply only to standalone published sources that cannot be cited any other way; no url, book, periodical, etc parameters; limited support for name lists and named identifiers. when validating parameters in {{cite document}} templates, the basic and ]] local document_arguments_t = { ['bibcode'] = true, ['bibcode-access'] = true, ['doi'] = true, ['DOI'] = true, ['doi-access'] = true, ['doi-broken-date'] = true, ['hdl'] = true, ['HDL'] = true, ['hdl-access'] = true, ['id'] = true, ['ID'] = true, ['jfm'] = true, ['JFM'] = true, ['lang'] = true, ['location'] = true, ['mr'] = true, ['MR'] = true, ['no-pp'] = true, ['orig-date'] = true, ['origyear'] = true, ['orig-year'] = true, ['osti'] = true, ['OSTI'] = true, ['osti-access'] = true, ['place'] = true, ['publisher'] = true, ['quote-page'] = true, ['quote-pages'] = true, ['script-quote'] = true, ['script-title'] = true, ['title-link'] = true, ['translator'] = true, ['translator-first'] = true, ['translator-given'] = true, ['translator-last'] = true, ['translator-surname'] = true, ['translator-link'] = true, ['translator-mask'] = true, ['trans-quote'] = true, ['type'] = true, ['zbl'] = true, ['ZBL'] = true, } local document_numbered_arguments_t = { ['translator#'] = true, ['translator-first#'] = true, ['translator#-first'] = true, ['translator-given#'] = true, ['translator#-given'] = true, ['translator-last#'] = true, ['translator#-last'] = true, ['translator-surname#'] = true, ['translator#-surname'] = true, ['translator-link#'] = true, ['translator#-link'] = true, ['translator-mask#'] = true, ['translator#-mask'] = true, } --[[--------------------------< L I S T _ C O M B I N E >------------------------------------------------------ makes one table from a list of tables. <lists_t> is a sequence of tables to be combined ]] local function list_combine (lists_t) local out_t = {}; for _, list_t in ipairs (lists_t) do -- for each list in <lists_t> for k, v in pairs (list_t) do -- extract each k/v pair out_t[k] = v; -- add to <out_t> end end return out_t; -- and done end --[[--------------------------< T E M P L A T E _ L I S T _ G E T >-------------------------------------------- gets a list of the templates from table t ]] local function template_list_get (t) local out_t = {}; -- a table for output for k, _ in pairs (t) do -- spin through the table and collect the keys table.insert (out_t, k) -- add each key to the output table end return out_t; -- and done end --[[--------------------------< E X P O R T E D T A B L E S >------------------------------------------------ ]] return { preprint_arguments_t = preprint_arguments_t, preprint_template_list_t = template_list_get (preprint_arguments_t), -- make a template list from preprint_arguments{} table unique_arguments_t = unique_arguments_t, unique_param_template_list_t = template_list_get (unique_arguments_t), -- make a template list from unique_arguments{} table document_parameters_t = list_combine ({limited_basic_arguments_t, limited_numbered_arguments_t, document_arguments_t, document_numbered_arguments_t}); common_parameters_t = list_combine ({basic_arguments_t, numbered_arguments_t}); limited_parameters_t = list_combine ({limited_basic_arguments_t, limited_numbered_arguments_t}); }; baub5v4d976tff8ebf3konhoua4ojgu 382130 382127 2026-06-05T00:49:21Z MacTire02 219 Undid revision [[Special:Diff/382127|382127]] by [[Special:Contributions/MacTire02|MacTire02]] ([[User talk:MacTire02|talk]]) 382130 Scribunto text/plain --[[--------------------------< S U P P O R T E D P A R A M E T E R S >-------------------------------------- Because a steady-state signal conveys no useful information, whitelist.basic_arguments[] list items can have three values: true - these parameters are valid and supported parameters false - these parameters are deprecated but still supported tracked - these parameters are valid and supported parameters tracked in an eponymous properties category nil - these parameters are no longer supported. remove entirely ]] local basic_arguments = { ['accessdate'] = true, ['access-date'] = true, ['agency'] = true, ['archivedate'] = true, ['archive-date'] = true, ['archive-format'] = true, ['archiveurl'] = true, ['archive-url'] = true, ['article'] = true, ['article-format'] = true, ['article-url'] = true, ['article-url-access'] = true, ['arxiv'] = true, -- cite arxiv; here because allowed in cite ... as identifier ['asin'] = true, ['ASIN'] = true, ['asin-tld'] = true, ['at'] = true, ['author'] = true, ['author-first'] = true, ['author-given'] = true, ['author-last'] = true, ['author-surname'] = true, ['authorlink'] = true, ['author-link'] = true, ['author-mask'] = true, ['authors'] = true, ['bibcode'] = true, ['bibcode-access'] = true, ['biorxiv'] = true, -- cite biorxiv; here because allowed in cite ... as identifier ['chapter'] = true, ['chapter-format'] = true, ['chapter-url'] = true, ['chapter-url-access'] = true, ['citeseerx'] = true, -- cite citeseerx; here because allowed in cite ... as identifier ['collaboration'] = true, ['contribution'] = true, ['contribution-format'] = true, ['contribution-url'] = true, ['contribution-url-access'] = true, ['contributor'] = true, ['contributor-first'] = true, ['contributor-given'] = true, ['contributor-last'] = true, ['contributor-surname'] = true, ['contributor-link'] = true, ['contributor-mask'] = true, ['date'] = true, ['department'] = true, ['df'] = true, ['dictionary'] = true, ['display-authors'] = true, ['display-contributors'] = true, ['display-editors'] = true, ['display-interviewers'] = true, ['display-subjects'] = true, ['display-translators'] = true, ['doi'] = true, ['DOI'] = true, ['doi-access'] = true, ['doi-broken-date'] = true, ['edition'] = true, ['editor'] = true, ['editor-first'] = true, ['editor-given'] = true, ['editor-last'] = true, ['editor-surname'] = true, ['editor-link'] = true, ['editor-mask'] = true, ['eissn'] = true, ['EISSN'] = true, ['encyclopaedia'] = true, ['encyclopedia'] = true, ['entry'] = true, ['entry-format'] = true, ['entry-url'] = true, ['entry-url-access'] = true, ['eprint'] = true, -- cite arxiv; here because allowed in cite ... as identifier ['first'] = true, ['format'] = true, ['given'] = true, ['hdl'] = true, ['HDL'] = true, ['hdl-access'] = true, ['host'] = true, -- unique to certain templates? ['id'] = true, ['ID'] = true, ['institution'] = true, -- constrain to cite thesis? ['interviewer'] = true, ['interviewer-first'] = true, ['interviewer-given'] = true, ['interviewer-last'] = true, ['interviewer-surname'] = true, ['interviewer-link'] = true, ['interviewer-mask'] = true, ['isbn'] = true, ['ISBN'] = true, ['ismn'] = true, ['ISMN'] = true, ['issn'] = true, ['ISSN'] = true, ['issue'] = true, ['jfm'] = true, ['JFM'] = true, ['journal'] = true, ['jstor'] = true, ['JSTOR'] = true, ['jstor-access'] = true, ['lang'] = true, ['language'] = true, ['last'] = true, ['lay-date'] = false, ['lay-format'] = false, ['lay-source'] = false, ['lay-url'] = false, ['lccn'] = true, ['LCCN'] = true, ['location'] = true, ['magazine'] = true, ['medium'] = true, ['minutes'] = true, -- constrain to cite AV media and podcast? ['mode'] = true, ['mr'] = true, ['MR'] = true, ['name-list-style'] = true, ['newspaper'] = true, ['no-pp'] = true, ['no-tracking'] = true, ['number'] = true, ['oclc'] = true, ['OCLC'] = true, ['ol'] = true, ['OL'] = true, ['ol-access'] = true, ['orig-date'] = true, ['origyear'] = true, ['orig-year'] = true, ['osti'] = true, ['OSTI'] = true, ['osti-access'] = true, ['others'] = true, ['p'] = true, ['page'] = true, ['pages'] = true, ['people'] = true, ['periodical'] = true, ['place'] = true, ['pmc'] = true, ['PMC'] = true, ['pmc-embargo-date'] = true, ['pmid'] = true, ['PMID'] = true, ['postscript'] = true, ['pp'] = true, ['publication-date'] = true, ['publication-place'] = true, ['publisher'] = true, ['quotation'] = true, ['quote'] = true, ['quote-page'] = true, ['quote-pages'] = true, ['ref'] = true, ['rfc'] = true, ['RFC'] = true, ['sbn'] = true, ['SBN'] = true, ['scale'] = true, ['script-article'] = true, ['script-chapter'] = true, ['script-contribution'] = true, ['script-entry'] = true, ['script-journal'] = true, ['script-magazine'] = true, ['script-newspaper'] = true, ['script-periodical'] = true, ['script-quote'] = true, ['script-section'] = true, ['script-title'] = true, ['script-website'] = true, ['script-work'] = true, ['section'] = true, ['section-format'] = true, ['section-url'] = true, ['section-url-access'] = true, ['series'] = true, ['ssrn'] = true, -- cite ssrn; these three here because allowed in cite ... as identifier ['SSRN'] = true, ['ssrn-access'] = true, ['subject'] = true, ['subject-link'] = true, ['subject-mask'] = true, ['surname'] = true, ['s2cid'] = true, ['S2CID'] = true, ['s2cid-access'] = true, ['template-doc-demo'] = true, ['time'] = true, -- constrain to cite av media and podcast? ['time-caption'] = true, -- constrain to cite av media and podcast? ['title'] = true, ['title-link'] = true, ['translator'] = true, ['translator-first'] = true, ['translator-given'] = true, ['translator-last'] = true, ['translator-surname'] = true, ['translator-link'] = true, ['translator-mask'] = true, ['trans-article'] = true, ['trans-chapter'] = true, ['trans-contribution'] = true, ['trans-entry'] = true, ['trans-journal'] = true, ['trans-magazine'] = true, ['trans-newspaper'] = true, ['trans-periodical'] = true, ['trans-quote'] = true, ['trans-section'] = true, ['trans-title'] = true, ['trans-website'] = true, ['trans-work'] = true, ['type'] = true, ['url'] = true, ['URL'] = true, ['url-access'] = true, ['url-status'] = true, ['vauthors'] = true, ['veditors'] = true, ['version'] = true, ['via'] = true, ['volume'] = true, ['website'] = true, ['work'] = true, ['year'] = true, ['zbl'] = true, ['ZBL'] = true, } local numbered_arguments = { ['author#'] = true, ['author-first#'] = true, ['author#-first'] = true, ['author-given#'] = true, ['author#-given'] = true, ['author-last#'] = true, ['author#-last'] = true, ['author-surname#'] = true, ['author#-surname'] = true, ['author-link#'] = true, ['author#-link'] = true, ['authorlink#'] = true, ['author#link'] = true, ['author-mask#'] = true, ['author#-mask'] = true, ['contributor#'] = true, ['contributor-first#'] = true, ['contributor#-first'] = true, ['contributor-given#'] = true, ['contributor#-given'] = true, ['contributor-last#'] = true, ['contributor#-last'] = true, ['contributor-surname#'] = true, ['contributor#-surname'] = true, ['contributor-link#'] = true, ['contributor#-link'] = true, ['contributor-mask#'] = true, ['contributor#-mask'] = true, ['editor#'] = true, ['editor-first#'] = true, ['editor#-first'] = true, ['editor-given#'] = true, ['editor#-given'] = true, ['editor-last#'] = true, ['editor#-last'] = true, ['editor-surname#'] = true, ['editor#-surname'] = true, ['editor-link#'] = true, ['editor#-link'] = true, ['editor-mask#'] = true, ['editor#-mask'] = true, ['first#'] = true, ['given#'] = true, ['host#'] = true, ['interviewer#'] = true, ['interviewer-first#'] = true, ['interviewer#-first'] = true, ['interviewer-given#'] = true, ['interviewer#-given'] = true, ['interviewer-last#'] = true, ['interviewer#-last'] = true, ['interviewer-surname#'] = true, ['interviewer#-surname'] = true, ['interviewer-link#'] = true, ['interviewer#-link'] = true, ['interviewer-mask#'] = true, ['interviewer#-mask'] = true, ['last#'] = true, ['subject#'] = true, ['subject-link#'] = true, ['subject#-link'] = true, ['subject-mask#'] = true, ['subject#-mask'] = true, ['surname#'] = true, ['translator#'] = true, ['translator-first#'] = true, ['translator#-first'] = true, ['translator-given#'] = true, ['translator#-given'] = true, ['translator-last#'] = true, ['translator#-last'] = true, ['translator-surname#'] = true, ['translator#-surname'] = true, ['translator-link#'] = true, ['translator#-link'] = true, ['translator-mask#'] = true, ['translator#-mask'] = true, } --[[--------------------------< P R E P R I N T S U P P O R T E D P A R A M E T E R S >-------------------- Cite arXiv, cite biorxiv, cite citeseerx, and cite ssrn are preprint templates that use the limited set of parameters defined in the limited_basic_arguments and limited_numbered_arguments tables. Those lists are supplemented with a template-specific list of parameters that are required by the particular template and may be exclusive to one of the preprint templates. Some of these parameters may also be available to the general cs1|2 templates. Same conventions for true/false/tracked/nil as above. ]] local preprint_arguments = { arxiv = { ['arxiv'] = true, -- cite arxiv and arxiv identifiers ['class'] = true, ['eprint'] = true, -- cite arxiv and arxiv identifiers }, biorxiv = { ['biorxiv'] = true, }, citeseerx = { ['citeseerx'] = true, }, ssrn = { ['ssrn'] = true, ['SSRN'] = true, ['ssrn-access'] = true, }, } --[[--------------------------< L I M I T E D S U P P O R T E D P A R A M E T E R S >---------------------- cite arxiv, cite biorxiv, cite citeseerx, and cite ssrn templates are preprint templates so are allowed only a limited subset of parameters allowed to all other cs1|2 templates. The limited subset is defined here. Same conventions for true/false/tracked/nil as above. ]] local limited_basic_arguments = { ['at'] = true, ['author'] = true, ['author-first'] = true, ['author-given'] = true, ['author-last'] = true, ['author-surname'] = true, ['author-link'] = true, ['authorlink'] = true, ['author-mask'] = true, ['authors'] = true, ['collaboration'] = true, ['date'] = true, ['df'] = true, ['display-authors'] = true, ['first'] = true, ['given'] = true, ['language'] = true, ['last'] = true, ['mode'] = true, ['name-list-style'] = true, ['no-tracking'] = true, ['p'] = true, ['page'] = true, ['pages'] = true, ['postscript'] = true, ['pp'] = true, ['quotation'] = true, ['quote'] = true, ['ref'] = true, ['surname'] = true, ['template-doc-demo'] = true, ['title'] = true, ['trans-title'] = true, ['vauthors'] = true, ['year'] = true, } local limited_numbered_arguments = { ['author#'] = true, ['author-first#'] = true, ['author#-first'] = true, ['author-given#'] = true, ['author#-given'] = true, ['author-last#'] = true, ['author#-last'] = true, ['author-surname#'] = true, ['author#-surname'] = true, ['author-link#'] = true, ['author#-link'] = true, ['authorlink#'] = true, ['author#link'] = true, ['author-mask#'] = true, ['author#-mask'] = true, ['first#'] = true, ['given#'] = true, ['last#'] = true, ['surname#'] = true, } --[[--------------------------< U N I Q U E _ A R G U M E N T S >---------------------------------------------- Some templates have unique parameters. Those templates and their unique parameters are listed here. Keys in this table are the template's CitationClass parameter value Same conventions for true/false/tracked/nil as above. ]] local unique_arguments = { ['audio-visual'] = { ['transcript'] = true, ['transcript-format'] = true, ['transcript-url'] = true, }, conference = { ['book-title'] = true, ['conference'] = true, ['conference-format'] = true, ['conference-url'] = true, ['event'] = true, }, episode = { ['airdate'] = true, ['air-date'] = true, ['credits'] = true, ['episode-link'] = true, -- alias of |title-link= ['network'] = true, ['season'] = true, ['series-link'] = true, ['series-no'] = true, ['series-number'] = true, ['station'] = true, ['transcript'] = true, ['transcript-format'] = true, ['transcripturl'] = false, ['transcript-url'] = true, }, mailinglist = { ['mailing-list'] = true, }, map = { ['cartography'] = true, ['inset'] = true, ['map'] = true, ['map-format'] = true, ['map-url'] = true, ['map-url-access'] = true, ['script-map'] = true, ['sections'] = true, ['sheet'] = true, ['sheets'] = true, ['trans-map'] = true, }, newsgroup = { ['message-id'] = true, ['newsgroup'] = true, }, report = { ['docket'] = true, }, serial = { ['airdate'] = true, ['air-date'] = true, ['credits'] = true, ['episode'] = true, -- cite serial only TODO: make available to cite episode? ['episode-link'] = true, -- alias of |title-link= ['network'] = true, ['series-link'] = true, ['station'] = true, }, speech = { ['conference'] = true, ['conference-format'] = true, ['conference-url'] = true, ['event'] = true, }, thesis = { ['degree'] = true, ['docket'] = true, }, } --[[--------------------------< T E M P L A T E _ L I S T _ G E T >-------------------------------------------- gets a list of the templates from table t ]] local function template_list_get (t) local out = {}; -- a table for output for k, _ in pairs (t) do -- spin through the table and collect the keys table.insert (out, k) -- add each key to the output table end return out; -- and done end --[[--------------------------< E X P O R T E D T A B L E S >------------------------------------------------ ]] return { basic_arguments = basic_arguments, numbered_arguments = numbered_arguments, limited_basic_arguments = limited_basic_arguments, limited_numbered_arguments = limited_numbered_arguments, preprint_arguments = preprint_arguments, preprint_template_list = template_list_get (preprint_arguments), -- make a template list from preprint_arguments{} table unique_arguments = unique_arguments, unique_param_template_list = template_list_get (unique_arguments), -- make a template list from unique_arguments{} table }; c31769ha0b0k636k736zgv3no6leh8l Ronney:Ruggyryn 'sy vlein 1869 14 27120 382212 347935 2026-06-05T01:29:58Z MacTire02 219 clowan noa 382212 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1746 14 27127 382112 348081 2026-06-05T00:21:04Z MacTire02 219 clowan noa 382112 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1722 14 27167 382123 348102 2026-06-05T00:27:03Z MacTire02 219 clowan noa 382123 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1817 14 27186 382169 347847 2026-06-05T01:16:21Z MacTire02 219 clowan noa 382169 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1705 14 27320 382139 348121 2026-06-05T00:53:22Z MacTire02 219 clowan noa 382139 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1711 14 27536 382136 348115 2026-06-05T00:52:44Z MacTire02 219 clowan noa 382136 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 2005 14 27581 382347 380562 2026-06-05T02:09:21Z MacTire02 219 clowan noa 382347 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1801 14 27583 382154 380947 2026-06-05T01:06:06Z MacTire02 219 clowan noa 382154 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1835 14 27828 382184 347884 2026-06-05T01:23:13Z MacTire02 219 clowan noa 382184 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1893 14 27935 382235 380926 2026-06-05T01:35:41Z MacTire02 219 clowan noa 382235 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1760 14 28431 382103 348065 2026-06-05T00:10:57Z MacTire02 219 clowan noa 382103 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Maria Gaetana Agnesi 0 28512 382132 348106 2026-06-05T00:50:26Z MacTire02 219 ++ 382132 wikitext text/x-wiki {{WD Kishtey Fys Dooinney | boayl_ruggyr = [[Milano]], [[Diucaght Milano]] | boayl_baaish = Milano, [[Yn Phobblaght Chisalpagh|y Phobblaght Chisalpagh]] | date_baaish = {{date baaish as eash|df=y|1799|7|9|1718|5|16}} | ashoonaght = [[Iddaalee|Iddaalagh]] }} She maddaghteyr, fallsoonagh, jeeoilagh, as deincharrey Iddaalagh va '''Maria Gaetana Agnesi''' ({{nowrap|16 Boaldyn 1718 – 9 Jerrey Geuree 1799}}). She ish va'n chied ven laue-lioar maddaght y screeu as [[rolley mraane 'sy vaddaght|y chied ven ve pointit myr olloo maddaght]] ec ollooscoill ennagh. Ta treisht currit j'ee er-yn-oyr dy nee ish ren screeu y chied lioar ren resooney magh [[calcalys anchaslyssagh]] chammah's [[calcalys earrooagh]] as v'ee ny oltey jeh'n olloo-rheynn ayns [[Ollooscoill Bologna]], ga nagh ren ee shirveishaghey. Chur ee yn kiare jeihaght jerrinagh jeh'n vea eck da studeyryssyn er y [[jeeoilys]] (yn [[ayr-oaylleeaght]] er lheh) as da'n obbyr ghiastyllagh tendeil er ny boghtyn. She [[Yn Agglish Chatoleagh|Catoleagh]] irrinagh v'ee as ren ee screeu dy liooar er y vestey eddyr e lorgey toiggaltagh as y tursmooinaght oaylyssagh, dy mooar 'sy traaght eck ''Il cielo mistico'' ("Y Niau Oaylyssagh"). Ren ee cur shilley er sursmooinaght resoonagh Yee myr dooie padjer as sursmooinaght vea, vaaish, as irree seose reesht Yeesey Chreest.<ref>{{cite journal | last = Mazzotti | first = Massimo | date = Mee ny Nollick 2001 | issue = 4 | journal = [[Isis (earishlioar) | Isis]] | jstor = 3080337 | pages = 657–683 | title = Maria Gaetana Agnesi: Mathematics and the making of the Catholic enlightenment | url = http://history.berkeley.edu/sites/default/files/Maria%20Gaetana%20Agnesi.pdf | archiveurl = https://web.archive.org/web/20141224170023/http://history.berkeley.edu/sites/default/files/Maria%20Gaetana%20Agnesi.pdf | archivedate = 24 Mee ny Nollick 2014 | url-status = dead | volume = 92| hdl = 10036/28899 | s2cid = 143457046 | hdl-access = free }}</ref> Va [[Maria Teresa Agnesi Pinottini]], [[cruitçhchoardey|cruitçhchoardeyr]] as [[cummeyder]], ny shuyr lhee. ==Jeeagh er neesht== * [[Elena Cornaro Piscopia]] * [[Cristina Roccati]] ==Imraaghyn== {{rolleyimraaghyn}} {{gurneil eaghtyrys}} {{DEFAULTSORT:Agnesi, Maria Gaetana}} [[Ronney:Ruggyryn 'sy vlein 1718]] [[Ronney:Baaseyn 'sy vlein 1799]] [[Ronney:Maddaghteyryn bwoirrin Iddaalagh]] [[Ronney:Oaylleeyn bwoirrin Iddaalagh]] [[Ronney:Jeeoilee Chatoleagh Raueagh Iddaalagh]] [[Ronney:Çhengoaylleeyn Iddaalagh]] [[Ronney:Feallee ass Milaan]] [[Ronney:Fallsoonee Chatoleagh]] [[Ronney:Çhengoaylleeyn bwoirrin]] [[Ronney:Fallsoonee woirrin Iddaalagh]] [[Ronney:Screeudeyryn bwoirrin Iddaalagh]] owdnrdqcjsrqp3fcgjthghv8fuh5gfs Ronney:Ruggyryn 'sy vlein 1718 14 28513 382125 348105 2026-06-05T00:27:31Z MacTire02 219 clowan noa 382125 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1754 14 28601 382108 348071 2026-06-05T00:17:34Z MacTire02 219 clowan noa 382108 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1880 14 28674 382224 348000 2026-06-05T01:32:55Z MacTire02 219 clowan noa 382224 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1895 14 28684 382237 380920 2026-06-05T01:41:12Z MacTire02 219 clowan noa 382237 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1866 14 28846 382209 347941 2026-06-05T01:27:55Z MacTire02 219 clowan noa 382209 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1740 14 28916 382114 348086 2026-06-05T00:21:42Z MacTire02 219 clowan noa 382114 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1713 14 29207 382135 348111 2026-06-05T00:52:23Z MacTire02 219 clowan noa 382135 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Christian Gmelin 0 29375 382149 323028 2026-06-05T01:05:13Z MacTire02 219 ronney elley 382149 wikitext text/x-wiki {{WD Kishtey Fys Dooinney}} She meain-oayllee as kemmigagh Germaanagh va '''Christian Gottlob Gmelin''' (12 Jerrey Fouyir 1792 – 13 Boaldyn 1860). V'eh ruggit ayns [[Tübingen]], y Ghermaan, as she oe lesh Johann Konrad Gmelin as aa-oe lesh [[Johann Georg Gmelin]] v'eh. ==Coorse bea oaylleeagh== Ayns 1818, she Gmelin va nane jeh ny chied deiney fakin dy vel [[sollanyn litçhey]] cur magh daah jiarg gial tra t'eh lostit. Ayns 1826, va [[Jean-Baptiste Guimet]] treishtit lesh çhymnaghey obbreeaght da jantys laue-jeant [[feer-ghorrymid]]. Daa vlein ny yei, ayns 1828, hoilshee Gmelin magh e obbreeaght hene da jantys laue-jeant feer-ghorrymid. Er-yn-oyr dy nee Gmelin va'n chied dooinney yn obbreeaght shen y hoilshaghey magh, hooar eshyn enney da'n eddynys shen. 'Sy chur magh echey, dooyrt Gmelin dy nee [[silickey]], [[ocsaid ollymin]], as [[soda]] ny preeu-vynayrnyn jeh feer-ghorrymid as ta'n daah mea çheet ass [[sulfur]].<ref name=":0">{{Cite book|url=https://books.google.com/books?id=PC5GAAAAcAAJ&q=gmelin&pg=PA216|title=The Quarterly journal of science, literature and art|date=1828-01-01|language=en}}</ref> ==Baase== Hooar Gmelin baase er 13 Boaldyn 1860 ayns Tübingen,<ref name=":1">{{Cite book|url=https://daten.digitale-sammlungen.de/bsb00008367/images/index.html?seite=268|author=Kopp, Hermann |year=1879 |title=Gmelin, Christian Gottlob |publisher= ''[[Allgemeine Deutsche Biographie (ADB)]]'', Duncker & Humblot |language=Germaanish |volume= 9|location= Leipzig | pages=266}}</ref> raad cheau eh yn slane vea echey. ==Obbraghyn== * ''Einleitung in die Chemie'' . Vol.1&2 . Laupp, Thüringen 1835-1837 [http://nbn-resolving.de/urn:nbn:de:hbz:061:2-29131 Lhieggan bun-earrooagh] liorish [[Lioarlann Ollooscoill as Steat, Düsseldorf]] ==Imraaghyn== {{Rolleyimraaghyn}} {{DEFAULTSORT:Gmelin, Christian}} [[Ronney:Ruggyryn 'sy vlein 1792]] [[Ronney:Baaseyn 'sy vlein 1860]] [[Ronney:Kemmigee irryn Ghermaanagh]] [[Ronney:Meain-oaylleeyn Germaanagh]] [[Ronney:Feallee ass Tübingen]] 9ynm5k4hgwsw2k2b3dwnodayfh1ckbo Ronney:Ruggyryn 'sy vlein 1792 14 29377 382148 349171 2026-06-05T01:02:15Z MacTire02 219 clowan noa 382148 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Module:Citation/CS1/Utilities 828 29975 382128 324814 2026-06-05T00:40:25Z MacTire02 219 ++ 382128 Scribunto text/plain local z = { error_cats_t = {}; -- for categorizing citations that contain errors error_ids_t = {}; -- list of error identifiers; used to prevent duplication of certain errors; local to this module error_msgs_t = {}; -- sequence table of error messages maint_cats_t = {}; -- for categorizing citations that aren't erroneous per se, but could use a little work prop_cats_t = {}; -- for categorizing citations based on certain properties, language of source for instance prop_keys_t = {}; -- for adding classes to the citation's <cite> tag }; --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- ]] local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration --[[--------------------------< I S _ S E T >------------------------------------------------------------------ Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string. ]] local function is_set (var) return not (var == nil or var == ''); end --[[--------------------------< I N _ A R R A Y >-------------------------------------------------------------- Whether needle is in haystack ]] local function in_array (needle, haystack) if needle == nil then return false; end for n, v in ipairs (haystack) do if v == needle then return n; end end return false; end --[[--------------------------< H A S _ A C C E P T _ A S _ W R I T T E N >------------------------------------ When <str> is wholly wrapped in accept-as-written markup, return <str> without markup and true; return <str> and false else with allow_empty = false, <str> must have at least one character inside the markup with allow_empty = true, <str> the markup frame can be empty like (()) to distinguish an empty template parameter from the specific condition "has no applicable value" in citation-context. After further evaluation the two cases might be merged at a later stage, but should be kept separated for now. ]] local function has_accept_as_written (str, allow_empty) if not is_set (str) then return str, false; end local count; if true == allow_empty then str, count = str:gsub ('^%(%((.*)%)%)$', '%1'); -- allows (()) to be an empty set else str, count = str:gsub ('^%(%((.+)%)%)$', '%1'); end return str, 0 ~= count; end --[[--------------------------< S U B S T I T U T E >---------------------------------------------------------- Populates numbered arguments in a message string using an argument table. <args> may be a single string or a sequence table of multiple strings. ]] local function substitute (msg, args) return args and mw.message.newRawMessage (msg, args):plain() or msg; end --[[--------------------------< E R R O R _ C O M M E N T >---------------------------------------------------- Wraps error messages with CSS markup according to the state of hidden. <content> may be a single string or a sequence table of multiple strings. ]] local function error_comment (content, hidden) return substitute (hidden and cfg.presentation['hidden-error'] or cfg.presentation['visible-error'], content); end --[[--------------------------< H Y P H E N _ T O _ D A S H >-------------------------------------------------- Converts a hyphen, endash, emdash to endash under certain conditions. The hyphen/en/em must separate like items; unlike items are returned unmodified. These forms are modified: letter - letter (A-B) digit - digit (4-5) digit separator digit - digit separator digit (4.1-4.5 or 4-1-4-5) letterdigit - letterdigit (A1-A5) (an optional separator between letter and digit is supported – a.1-a.5 or a-1-a-5) digitletter - digitletter (5a-5d) (an optional separator between letter and digit is supported – 5.a-5.d or 5-a-5-d) any other forms are returned unmodified. str may be a comma- or semicolon-separated list of page ranges with/without single pages ]] local function hyphen_to_dash (str) if not is_set (str) then return str; end str = str:gsub ("(%(%(.-%)%))", function(m) return m:gsub(",", ","):gsub(";", ";") end) -- replace commas and semicolons in accept-as-written markup with similar unicode characters so they'll be ignored during the split str = str:gsub ('&[nm]dash;', {['&ndash;'] = '–', ['&mdash;'] = '—'}); -- replace &mdash; and &ndash; entities with their characters; semicolon mucks up the text.split str = str:gsub ('&#45;', '-'); -- replace HTML numeric entity with hyphen character str = str:gsub ('&nbsp;', ' '); -- replace &nbsp; entity with generic keyboard space character local out = {}; local list = mw.text.split (str, '%s*[,;]%s*'); -- split str at comma or semicolon separators if there are any local accept; -- boolean for _, item in ipairs (list) do -- for each item in the list item, accept = has_accept_as_written (item); -- remove accept-this-as-written markup when it wraps all of item if not accept and mw.ustring.match (item, '^%w*[%.%-]?%w+%s*[—–-]%s*%w*[%.%-]?%w+$') then -- if pagination uses <hyphen|dot> separators with hyphen/endash/emdash <range separator> if mw.ustring.match (item, '^%a+[%.%-]%d+%s*[—–-]%s*%a+[%.%-]%d+$') or -- letter<hyphen|dot>digit <range separator> letter<hyphen|dot>digit (requires <hyphen|dot> separator between letter and digit) mw.ustring.match (item, '^%d+[%.%-]%a+%s*[—–-]%s*%d+[%.%-]%a+$') or -- digit<hyphen|dot>letter <range separator> digit<hyphen|dot>letter (requires <hyphen|dot> separator between digit and letter) mw.ustring.match (item, '^%d+[%.%-]%d+%s*[—–-]%s*%d+[%.%-]%d+$') then -- digit<hyphen|dot>digit <range separator> digit<hyphen|dot>digit (requires <hyphen|dot> separator between digit and digit) item = mw.ustring.gsub (item, '(%w*[%.%-]%w+)%s*[—–-]%s*(%w*[%.%-]%w+)', '<span class="nowrap">%1 –</span> <span class="nowrap">%2</span>'); -- replace <range separator>, with spaced endash elseif mw.ustring.match (item, '^%d+%a+%s*[—–-]%s*%d+%a+$') or -- digitletter <range separator> digitletter mw.ustring.match (item, '^%a+%d+%s*[—–-]%s*%a+%d+$') or -- letterdigit <range separator> letterdigit mw.ustring.match (item, '^%d+%s*[—–-]%s*%d+$') or -- digit <range separator> digit mw.ustring.match (item, '^%a+%s*[—–-]%s*%a+$') then -- letter<range separator> letter item = mw.ustring.gsub (item, '(%w+)%s*[—–-]%s*(%w+)', '<span class="nowrap">%1–</span>%2'); -- replace <range separator> with endash, remove extraneous space characters else -- item = mw.ustring.gsub (item, '%s*[—–-]%s*', '–'); -- disabled; here when 'unlike' items so return <item> as is end end table.insert (out, item); -- add the (possibly modified) item to the output table end local temp_str = ''; -- concatenate the output table into a comma separated string temp_str, accept = has_accept_as_written (table.concat (out, ', ')); -- remove accept-this-as-written markup when it wraps all of concatenated out if accept then temp_str = has_accept_as_written (str); -- when global markup removed, return original str; do it this way to suppress boolean second return value return temp_str:gsub(",", ","):gsub(";", ";"); else return temp_str:gsub(",", ","):gsub(";", ";"); -- else, return assembled temp_str end end --[=[-------------------------< M A K E _ W I K I L I N K >---------------------------------------------------- Makes a wikilink; when both link and display text is provided, returns a wikilink in the form [[L|D]]; if only link is provided (or link and display are the same), returns a wikilink in the form [[L]]; if neither are provided or link is omitted, returns an empty string. ]=] local function make_wikilink (link, display) if not is_set (link) then return '' end if is_set (display) and link ~= display then return table.concat ({'[[', link, '|', display, ']]'}); else return table.concat ({'[[', link, ']]'}); end end --[[--------------------------< S E T _ M E S S A G E >---------------------------------------------------------- Sets an error message using the ~/Configuration error_conditions{} table along with arguments supplied in the function call, inserts the resulting message in z.error_msgs_t{} sequence table, and returns the error message. <error_id> – key value for appropriate error handler in ~/Configuration error_conditions{} table <arguments> – may be a single string or a sequence table of multiple strings to be subsititued into error_conditions[error_id].message <raw> – boolean true – causes this function to return the error message not wrapped in visible-error, hidden-error span tag; returns error_conditions[error_id].hidden as a second return value does not add message to z.error_msgs_t sequence table false, nil – adds message wrapped in visible-error, hidden-error span tag to z.error_msgs_t returns the error message wrapped in visible-error, hidden-error span tag; there is no second return value <prefix> – string to be prepended to <message> -- TODO: remove support for these unused(?) arguments? <suffix> – string to be appended to <message> TODO: change z.error_cats_t and z.maint_cats_t to have the form cat_name = true? this to avoid dups without having to have an extra table ]] local added_maint_cats = {} -- list of maintenance categories that have been added to z.maint_cats_t; TODO: figure out how to delete this table local function set_message (error_id, arguments, raw, prefix, suffix) local error_state = cfg.error_conditions[error_id]; prefix = prefix or ''; suffix = suffix or ''; if error_state == nil then error (cfg.messages['undefined_error'] .. ': ' .. error_id); -- because missing error handler in Module:Citation/CS1/Configuration elseif is_set (error_state.category) then if error_state.message then -- when error_state.message defined, this is an error message table.insert (z.error_cats_t, error_state.category); else if not added_maint_cats[error_id] then added_maint_cats[error_id] = true; -- note that we've added this category table.insert (z.maint_cats_t, substitute (error_state.category, arguments)); -- make cat name then add to table end return; -- because no message, nothing more to do end end local message = substitute (error_state.message, arguments); message = table.concat ( { message, ' (', make_wikilink ( table.concat ( { cfg.messages['help page link'], '#', error_state.anchor }), cfg.messages['help page label']), ')' }); z.error_ids_t[error_id] = true; if z.error_ids_t['err_citation_missing_title'] and -- if missing-title error already noted in_array (error_id, {'err_bare_url_missing_title', 'err_trans_missing_title'}) then -- and this error is one of these return '', false; -- don't bother because one flavor of missing title is sufficient end message = table.concat ({prefix, message, suffix}); if true == raw then return message, error_state.hidden; -- return message not wrapped in visible-error, hidden-error span tag end message = error_comment (message, error_state.hidden); -- wrap message in visible-error, hidden-error span tag table.insert (z.error_msgs_t, message); -- add it to the messages sequence table return message; -- and done; return value generally not used but is used as a flag in various functions of ~/Identifiers end --[[-------------------------< I S _ A L I A S _ U S E D >----------------------------------------------------- This function is used by select_one() to determine if one of a list of alias parameters is in the argument list provided by the template. Input: args – pointer to the arguments table from calling template alias – one of the list of possible aliases in the aliases lists from Module:Citation/CS1/Configuration index – for enumerated parameters, identifies which one enumerated – true/false flag used to choose how enumerated aliases are examined value – value associated with an alias that has previously been selected; nil if not yet selected selected – the alias that has previously been selected; nil if not yet selected error_list – list of aliases that are duplicates of the alias already selected Returns: value – value associated with alias we selected or that was previously selected or nil if an alias not yet selected selected – the alias we selected or the alias that was previously selected or nil if an alias not yet selected ]] local function is_alias_used (args, alias, index, enumerated, value, selected, error_list) if enumerated then -- is this a test for an enumerated parameters? alias = alias:gsub ('#', index); -- replace '#' with the value in index else alias = alias:gsub ('#', ''); -- remove '#' if it exists end if is_set (args[alias]) then -- alias is in the template's argument list if value ~= nil and selected ~= alias then -- if we have already selected one of the aliases local skip; for _, v in ipairs (error_list) do -- spin through the error list to see if we've added this alias if v == alias then skip = true; break; -- has been added so stop looking end end if not skip then -- has not been added so table.insert (error_list, alias); -- add error alias to the error list end else value = args[alias]; -- not yet selected an alias, so select this one selected = alias; end end return value, selected; -- return newly selected alias, or previously selected alias end --[[--------------------------< A D D _ M A I N T _ C A T >------------------------------------------------------ Adds a category to z.maint_cats_t using names from the configuration file with additional text if any. To prevent duplication, the added_maint_cats table lists the categories by key that have been added to z.maint_cats_t. ]] local function add_maint_cat (key, arguments) if not added_maint_cats [key] then added_maint_cats [key] = true; -- note that we've added this category table.insert (z.maint_cats_t, substitute (cfg.maint_cats [key], arguments)); -- make name then add to table end end --[[--------------------------< A D D _ P R O P _ C A T >-------------------------------------------------------- Adds a category to z.prop_cats_t using names from the configuration file with additional text if any. foreign_lang_source and foreign_lang_source_2 keys have a language code appended to them so that multiple languages may be categorized but multiples of the same language are not categorized. added_prop_cats is a table declared in page scope variables above ]] local added_prop_cats = {}; -- list of property categories that have been added to z.prop_cats_t local function add_prop_cat (key, arguments, key_modifier) local key_modified = key .. ((key_modifier and key_modifier) or ''); -- modify <key> with <key_modifier> if present and not nil if not added_prop_cats [key_modified] then added_prop_cats [key_modified] = true; -- note that we've added this category table.insert (z.prop_cats_t, substitute (cfg.prop_cats [key], arguments)); -- make name then add to table table.insert (z.prop_keys_t, 'cs1-prop-' .. key); -- convert key to class for use in the citation's <cite> tag end end --[[--------------------------< S A F E _ F O R _ I T A L I C S >---------------------------------------------- Protects a string that will be wrapped in wiki italic markup '' ... '' Note: We cannot use <i> for italics, as the expected behavior for italics specified by ''...'' in the title is that they will be inverted (i.e. unitalicized) in the resulting references. In addition, <i> and '' tend to interact poorly under Mediawiki's HTML tidy. ]] local function safe_for_italics (str) if not is_set (str) then return str end if str:sub (1, 1) == "'" then str = "<span></span>" .. str; end if str:sub (-1, -1) == "'" then str = str .. "<span></span>"; end return str:gsub ('\n', ' '); -- Remove newlines as they break italics. end --[[--------------------------< W R A P _ S T Y L E >---------------------------------------------------------- Applies styling to various parameters. Supplied string is wrapped using a message_list configuration taking one argument; protects italic styled parameters. Additional text taken from citation_config.presentation - the reason this function is similar to but separate from wrap_msg(). ]] local function wrap_style (key, str) if not is_set (str) then return ""; elseif in_array (key, {'italic-title', 'trans-italic-title'}) then str = safe_for_italics (str); end return substitute (cfg.presentation[key], {str}); end --[[--------------------------< M A K E _ S E P _ L I S T >------------------------------------------------------------ make a separated list of items using provided separators. <sep_list> - typically '<comma><space>' <sep_list_pair> - typically '<space>and<space>' <sep_list_end> - typically '<comma><space>and<space>' or '<comma><space>&<space>' defaults to cfg.presentation['sep_list'], cfg.presentation['sep_list_pair'], and cfg.presentation['sep_list_end'] if <sep_list_end> is specified, <sep_list> and <sep_list_pair> must also be supplied ]] local function make_sep_list (count, list_seq, sep_list, sep_list_pair, sep_list_end) local list = ''; if not sep_list then -- set the defaults sep_list = cfg.presentation['sep_list']; sep_list_pair = cfg.presentation['sep_list_pair']; sep_list_end = cfg.presentation['sep_list_end']; end if 2 >= count then list = table.concat (list_seq, sep_list_pair); -- insert separator between two items; returns list_seq[1] then only one item elseif 2 < count then list = table.concat (list_seq, sep_list, 1, count - 1); -- concatenate all but last item with plain list separator list = table.concat ({list, list_seq[count]}, sep_list_end); -- concatenate last item onto end of <list> with final separator end return list; end --[[--------------------------< S E L E C T _ O N E >---------------------------------------------------------- Chooses one matching parameter from a list of parameters to consider. The list of parameters to consider is just names. For parameters that may be enumerated, the position of the numerator in the parameter name is identified by the '#' so |author-last1= and |author1-last= are represented as 'author-last#' and 'author#-last'. Because enumerated parameter |<param>1= is an alias of |<param>= we must test for both possibilities. Generates an error if more than one match is present. ]] local function select_one (args, aliases_list, error_condition, index) local value = nil; -- the value assigned to the selected parameter local selected = ''; -- the name of the parameter we have chosen local error_list = {}; if index ~= nil then index = tostring(index); end for _, alias in ipairs (aliases_list) do -- for each alias in the aliases list if alias:match ('#') then -- if this alias can be enumerated if '1' == index then -- when index is 1 test for enumerated and non-enumerated aliases value, selected = is_alias_used (args, alias, index, false, value, selected, error_list); -- first test for non-enumerated alias end value, selected = is_alias_used (args, alias, index, true, value, selected, error_list); -- test for enumerated alias else value, selected = is_alias_used (args, alias, index, false, value, selected, error_list); -- test for non-enumerated alias end end if #error_list > 0 and 'none' ~= error_condition then -- for cases where this code is used outside of extract_names() for i, v in ipairs (error_list) do error_list[i] = wrap_style ('parameter', v); end table.insert (error_list, wrap_style ('parameter', selected)); set_message (error_condition, {make_sep_list (#error_list, error_list)}); end return value, selected; end --[=[-------------------------< R E M O V E _ W I K I _ L I N K >---------------------------------------------- Gets the display text from a wikilink like [[A|B]] or [[B]] gives B The str:gsub() returns either A|B froma [[A|B]] or B from [[B]] or B from B (no wikilink markup). In l(), l:gsub() removes the link and pipe (if they exist); the second :gsub() trims whitespace from the label if str was wrapped in wikilink markup. Presumably, this is because without wikimarkup in str, there is no match in the initial gsub, the replacement function l() doesn't get called. ]=] local function remove_wiki_link (str) return (str:gsub ("%[%[([^%[%]]*)%]%]", function(l) return l:gsub ("^[^|]*|(.*)$", "%1" ):gsub ("^%s*(.-)%s*$", "%1"); end)); end --[=[-------------------------< I S _ W I K I L I N K >-------------------------------------------------------- Determines if str is a wikilink, extracts, and returns the wikilink type, link text, and display text parts. If str is a complex wikilink ([[L|D]]): returns wl_type 2 and D and L from [[L|D]]; if str is a simple wikilink ([[D]]) returns wl_type 1 and D from [[D]] and L as empty string; if not a wikilink: returns wl_type 0, str as D, and L as empty string. trims leading and trailing whitespace and pipes from L and D ([[L|]] and [[|D]] are accepted by MediaWiki and treated like [[D]]; while [[|D|]] is not accepted by MediaWiki, here, we accept it and return D without the pipes). ]=] local function is_wikilink (str) local D, L local wl_type = 2; -- assume that str is a complex wikilink [[L|D]] if not str:match ('^%[%[[^%]]+%]%]$') then -- is str some sort of a wikilink (must have some sort of content) return 0, str, ''; -- not a wikilink; return wl_type as 0, str as D, and empty string as L end L, D = str:match ('^%[%[([^|]+)|([^%]]+)%]%]$'); -- get L and D from [[L|D]] if not is_set (D) then -- if no separate display D = str:match ('^%[%[([^%]]*)|*%]%]$'); -- get D from [[D]] or [[D|]] wl_type = 1; end D = mw.text.trim (D, '%s|'); -- trim white space and pipe characters return wl_type, D, L or ''; end --[[--------------------------< S T R I P _ A P O S T R O P H E _ M A R K U P >-------------------------------- Strip wiki italic and bold markup from argument so that it doesn't contaminate COinS metadata. This function strips common patterns of apostrophe markup. We presume that editors who have taken the time to markup a title have, as a result, provided valid markup. When they don't, some single apostrophes are left behind. Returns the argument without wiki markup and a number; the number is more-or-less meaningless except as a flag to indicate that markup was replaced; do not rely on it as an indicator of how many of any kind of markup was removed; returns the argument and nil when no markup removed ]] local function strip_apostrophe_markup (argument) if not is_set (argument) then return argument, nil; -- no argument, nothing to do end if nil == argument:find ( "''", 1, true ) then -- Is there at least one double apostrophe? If not, exit. return argument, nil; end local flag; while true do if argument:find ("'''''", 1, true) then -- bold italic (5) argument, flag = argument:gsub ("%'%'%'%'%'", ""); -- remove all instances of it elseif argument:find ("''''", 1, true) then -- italic start and end without content (4) argument, flag=argument:gsub ("%'%'%'%'", ""); elseif argument:find ("'''", 1, true) then -- bold (3) argument, flag=argument:gsub ("%'%'%'", ""); elseif argument:find ("''", 1, true) then -- italic (2) argument, flag = argument:gsub ("%'%'", ""); else break; end end return argument, flag; -- done end --[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >-------------------------------------- Sets local cfg table to same (live or sandbox) as that used by the other modules. ]] local function set_selected_modules (cfg_table_ptr) cfg = cfg_table_ptr; end --[[--------------------------< E X P O R T S >---------------------------------------------------------------- ]] return { add_maint_cat = add_maint_cat, -- exported functions add_prop_cat = add_prop_cat, error_comment = error_comment, has_accept_as_written = has_accept_as_written, hyphen_to_dash = hyphen_to_dash, in_array = in_array, is_set = is_set, is_wikilink = is_wikilink, make_sep_list = make_sep_list, make_wikilink = make_wikilink, remove_wiki_link = remove_wiki_link, safe_for_italics = safe_for_italics, select_one = select_one, set_message = set_message, set_selected_modules = set_selected_modules, strip_apostrophe_markup = strip_apostrophe_markup, substitute = substitute, wrap_style = wrap_style, z = z, -- exported table } ipuk2skv52zxnbboa2zzah6ug9yuin7 382131 382128 2026-06-05T00:49:45Z MacTire02 219 Undid revision [[Special:Diff/382128|382128]] by [[Special:Contributions/MacTire02|MacTire02]] ([[User talk:MacTire02|talk]]) 382131 Scribunto text/plain local z = { error_cats_t = {}; -- for categorizing citations that contain errors error_ids_t = {}; -- list of error identifiers; used to prevent duplication of certain errors; local to this module error_msgs_t = {}; -- sequence table of error messages maint_cats_t = {}; -- for categorizing citations that aren't erroneous per se, but could use a little work prop_cats_t = {}; -- for categorizing citations based on certain properties, language of source for instance prop_keys_t = {}; -- for adding classes to the citation's <cite> tag }; --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- ]] local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration --[[--------------------------< I S _ S E T >------------------------------------------------------------------ Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string. ]] local function is_set (var) return not (var == nil or var == ''); end --[[--------------------------< I N _ A R R A Y >-------------------------------------------------------------- Whether needle is in haystack ]] local function in_array (needle, haystack) if needle == nil then return false; end for n, v in ipairs (haystack) do if v == needle then return n; end end return false; end --[[--------------------------< H A S _ A C C E P T _ A S _ W R I T T E N >------------------------------------ When <str> is wholly wrapped in accept-as-written markup, return <str> without markup and true; return <str> and false else with allow_empty = false, <str> must have at least one character inside the markup with allow_empty = true, <str> the markup frame can be empty like (()) to distinguish an empty template parameter from the specific condition "has no applicable value" in citation-context. After further evaluation the two cases might be merged at a later stage, but should be kept separated for now. ]] local function has_accept_as_written (str, allow_empty) if not is_set (str) then return str, false; end local count; if true == allow_empty then str, count = str:gsub ('^%(%((.*)%)%)$', '%1'); -- allows (()) to be an empty set else str, count = str:gsub ('^%(%((.+)%)%)$', '%1'); end return str, 0 ~= count; end --[[--------------------------< S U B S T I T U T E >---------------------------------------------------------- Populates numbered arguments in a message string using an argument table. <args> may be a single string or a sequence table of multiple strings. ]] local function substitute (msg, args) return args and mw.message.newRawMessage (msg, args):plain() or msg; end --[[--------------------------< E R R O R _ C O M M E N T >---------------------------------------------------- Wraps error messages with CSS markup according to the state of hidden. <content> may be a single string or a sequence table of multiple strings. ]] local function error_comment (content, hidden) return substitute (hidden and cfg.presentation['hidden-error'] or cfg.presentation['visible-error'], content); end --[[--------------------------< H Y P H E N _ T O _ D A S H >-------------------------------------------------- Converts a hyphen to a dash under certain conditions. The hyphen must separate like items; unlike items are returned unmodified. These forms are modified: letter - letter (A - B) digit - digit (4-5) digit separator digit - digit separator digit (4.1-4.5 or 4-1-4-5) letterdigit - letterdigit (A1-A5) (an optional separator between letter and digit is supported – a.1-a.5 or a-1-a-5) digitletter - digitletter (5a - 5d) (an optional separator between letter and digit is supported – 5.a-5.d or 5-a-5-d) any other forms are returned unmodified. str may be a comma- or semicolon-separated list ]] local function hyphen_to_dash (str) if not is_set (str) then return str; end local accept; -- boolean str = str:gsub ("(%(%(.-%)%))", function(m) return m:gsub(",", ","):gsub(";", ";") end) -- replace commas and semicolons in accept-as-written markup with similar unicode characters so they'll be ignored during the split str = str:gsub ('&[nm]dash;', {['&ndash;'] = '–', ['&mdash;'] = '—'}); -- replace &mdash; and &ndash; entities with their characters; semicolon mucks up the text.split str = str:gsub ('&#45;', '-'); -- replace HTML numeric entity with hyphen character str = str:gsub ('&nbsp;', ' '); -- replace &nbsp; entity with generic keyboard space character local out = {}; local list = mw.text.split (str, '%s*[,;]%s*'); -- split str at comma or semicolon separators if there are any for _, item in ipairs (list) do -- for each item in the list item, accept = has_accept_as_written (item); -- remove accept-this-as-written markup when it wraps all of item if not accept and mw.ustring.match (item, '^%w*[%.%-]?%w+%s*[%-–—]%s*%w*[%.%-]?%w+$') then -- if a hyphenated range or has endash or emdash separators if item:match ('^%a+[%.%-]?%d+%s*%-%s*%a+[%.%-]?%d+$') or -- letterdigit hyphen letterdigit (optional separator between letter and digit) item:match ('^%d+[%.%-]?%a+%s*%-%s*%d+[%.%-]?%a+$') or -- digitletter hyphen digitletter (optional separator between digit and letter) item:match ('^%d+[%.%-]%d+%s*%-%s*%d+[%.%-]%d+$') or -- digit separator digit hyphen digit separator digit item:match ('^%d+%s*%-%s*%d+$') or -- digit hyphen digit item:match ('^%a+%s*%-%s*%a+$') then -- letter hyphen letter item = item:gsub ('(%w*[%.%-]?%w+)%s*%-%s*(%w*[%.%-]?%w+)', '%1–%2'); -- replace hyphen, remove extraneous space characters else item = mw.ustring.gsub (item, '%s*[–—]%s*', '–'); -- for endash or emdash separated ranges, replace em with en, remove extraneous whitespace end end table.insert (out, item); -- add the (possibly modified) item to the output table end local temp_str = ''; -- concatenate the output table into a comma separated string temp_str, accept = has_accept_as_written (table.concat (out, ', ')); -- remove accept-this-as-written markup when it wraps all of concatenated out if accept then temp_str = has_accept_as_written (str); -- when global markup removed, return original str; do it this way to suppress boolean second return value return temp_str:gsub(",", ","):gsub(";", ";"); else return temp_str:gsub(",", ","):gsub(";", ";"); -- else, return assembled temp_str end end --[=[-------------------------< M A K E _ W I K I L I N K >---------------------------------------------------- Makes a wikilink; when both link and display text is provided, returns a wikilink in the form [[L|D]]; if only link is provided (or link and display are the same), returns a wikilink in the form [[L]]; if neither are provided or link is omitted, returns an empty string. ]=] local function make_wikilink (link, display) if not is_set (link) then return '' end if is_set (display) and link ~= display then return table.concat ({'[[', link, '|', display, ']]'}); else return table.concat ({'[[', link, ']]'}); end end --[[--------------------------< S E T _ M E S S A G E >---------------------------------------------------------- Sets an error message using the ~/Configuration error_conditions{} table along with arguments supplied in the function call, inserts the resulting message in z.error_msgs_t{} sequence table, and returns the error message. <error_id> – key value for appropriate error handler in ~/Configuration error_conditions{} table <arguments> – may be a single string or a sequence table of multiple strings to be subsititued into error_conditions[error_id].message <raw> – boolean true – causes this function to return the error message not wrapped in visible-error, hidden-error span tag; returns error_conditions[error_id].hidden as a second return value does not add message to z.error_msgs_t sequence table false, nil – adds message wrapped in visible-error, hidden-error span tag to z.error_msgs_t returns the error message wrapped in visible-error, hidden-error span tag; there is no second return value <prefix> – string to be prepended to <message> -- TODO: remove support for these unused(?) arguments? <suffix> – string to be appended to <message> TODO: change z.error_cats_t and z.maint_cats_t to have the form cat_name = true? this to avoid dups without having to have an extra table ]] local added_maint_cats = {} -- list of maintenance categories that have been added to z.maint_cats_t; TODO: figure out how to delete this table local function set_message (error_id, arguments, raw, prefix, suffix) local error_state = cfg.error_conditions[error_id]; prefix = prefix or ''; suffix = suffix or ''; if error_state == nil then error (cfg.messages['undefined_error'] .. ': ' .. error_id); -- because missing error handler in Module:Citation/CS1/Configuration elseif is_set (error_state.category) then if error_state.message then -- when error_state.message defined, this is an error message table.insert (z.error_cats_t, error_state.category); else if not added_maint_cats[error_id] then added_maint_cats[error_id] = true; -- note that we've added this category table.insert (z.maint_cats_t, substitute (error_state.category, arguments)); -- make cat name then add to table end return; -- because no message, nothing more to do end end local message = substitute (error_state.message, arguments); message = table.concat ( { message, ' (', make_wikilink ( table.concat ( { cfg.messages['help page link'], '#', error_state.anchor }), cfg.messages['help page label']), ')' }); z.error_ids_t[error_id] = true; if z.error_ids_t['err_citation_missing_title'] and -- if missing-title error already noted in_array (error_id, {'err_bare_url_missing_title', 'err_trans_missing_title'}) then -- and this error is one of these return '', false; -- don't bother because one flavor of missing title is sufficient end message = table.concat ({prefix, message, suffix}); if true == raw then return message, error_state.hidden; -- return message not wrapped in visible-error, hidden-error span tag end message = error_comment (message, error_state.hidden); -- wrap message in visible-error, hidden-error span tag table.insert (z.error_msgs_t, message); -- add it to the messages sequence table return message; -- and done; return value generally not used but is used as a flag in various functions of ~/Identifiers end --[[-------------------------< I S _ A L I A S _ U S E D >----------------------------------------------------- This function is used by select_one() to determine if one of a list of alias parameters is in the argument list provided by the template. Input: args – pointer to the arguments table from calling template alias – one of the list of possible aliases in the aliases lists from Module:Citation/CS1/Configuration index – for enumerated parameters, identifies which one enumerated – true/false flag used to choose how enumerated aliases are examined value – value associated with an alias that has previously been selected; nil if not yet selected selected – the alias that has previously been selected; nil if not yet selected error_list – list of aliases that are duplicates of the alias already selected Returns: value – value associated with alias we selected or that was previously selected or nil if an alias not yet selected selected – the alias we selected or the alias that was previously selected or nil if an alias not yet selected ]] local function is_alias_used (args, alias, index, enumerated, value, selected, error_list) if enumerated then -- is this a test for an enumerated parameters? alias = alias:gsub ('#', index); -- replace '#' with the value in index else alias = alias:gsub ('#', ''); -- remove '#' if it exists end if is_set (args[alias]) then -- alias is in the template's argument list if value ~= nil and selected ~= alias then -- if we have already selected one of the aliases local skip; for _, v in ipairs (error_list) do -- spin through the error list to see if we've added this alias if v == alias then skip = true; break; -- has been added so stop looking end end if not skip then -- has not been added so table.insert (error_list, alias); -- add error alias to the error list end else value = args[alias]; -- not yet selected an alias, so select this one selected = alias; end end return value, selected; -- return newly selected alias, or previously selected alias end --[[--------------------------< A D D _ M A I N T _ C A T >------------------------------------------------------ Adds a category to z.maint_cats_t using names from the configuration file with additional text if any. To prevent duplication, the added_maint_cats table lists the categories by key that have been added to z.maint_cats_t. ]] local function add_maint_cat (key, arguments) if not added_maint_cats [key] then added_maint_cats [key] = true; -- note that we've added this category table.insert (z.maint_cats_t, substitute (cfg.maint_cats [key], arguments)); -- make name then add to table end end --[[--------------------------< A D D _ P R O P _ C A T >-------------------------------------------------------- Adds a category to z.prop_cats_t using names from the configuration file with additional text if any. foreign_lang_source and foreign_lang_source_2 keys have a language code appended to them so that multiple languages may be categorized but multiples of the same language are not categorized. added_prop_cats is a table declared in page scope variables above ]] local added_prop_cats = {}; -- list of property categories that have been added to z.prop_cats_t local function add_prop_cat (key, arguments, key_modifier) local key_modified = key .. ((key_modifier and key_modifier) or ''); -- modify <key> with <key_modifier> if present and not nil if not added_prop_cats [key_modified] then added_prop_cats [key_modified] = true; -- note that we've added this category table.insert (z.prop_cats_t, substitute (cfg.prop_cats [key], arguments)); -- make name then add to table table.insert (z.prop_keys_t, 'cs1-prop-' .. key); -- convert key to class for use in the citation's <cite> tag end end --[[--------------------------< S A F E _ F O R _ I T A L I C S >---------------------------------------------- Protects a string that will be wrapped in wiki italic markup '' ... '' Note: We cannot use <i> for italics, as the expected behavior for italics specified by ''...'' in the title is that they will be inverted (i.e. unitalicized) in the resulting references. In addition, <i> and '' tend to interact poorly under Mediawiki's HTML tidy. ]] local function safe_for_italics (str) if not is_set (str) then return str end if str:sub (1, 1) == "'" then str = "<span></span>" .. str; end if str:sub (-1, -1) == "'" then str = str .. "<span></span>"; end return str:gsub ('\n', ' '); -- Remove newlines as they break italics. end --[[--------------------------< W R A P _ S T Y L E >---------------------------------------------------------- Applies styling to various parameters. Supplied string is wrapped using a message_list configuration taking one argument; protects italic styled parameters. Additional text taken from citation_config.presentation - the reason this function is similar to but separate from wrap_msg(). ]] local function wrap_style (key, str) if not is_set (str) then return ""; elseif in_array (key, {'italic-title', 'trans-italic-title'}) then str = safe_for_italics (str); end return substitute (cfg.presentation[key], {str}); end --[[--------------------------< M A K E _ S E P _ L I S T >------------------------------------------------------------ make a separated list of items using provided separators. <sep_list> - typically '<comma><space>' <sep_list_pair> - typically '<space>and<space>' <sep_list_end> - typically '<comma><space>and<space>' or '<comma><space>&<space>' defaults to cfg.presentation['sep_list'], cfg.presentation['sep_list_pair'], and cfg.presentation['sep_list_end'] if <sep_list_end> is specified, <sep_list> and <sep_list_pair> must also be supplied ]] local function make_sep_list (count, list_seq, sep_list, sep_list_pair, sep_list_end) local list = ''; if not sep_list then -- set the defaults sep_list = cfg.presentation['sep_list']; sep_list_pair = cfg.presentation['sep_list_pair']; sep_list_end = cfg.presentation['sep_list_end']; end if 2 >= count then list = table.concat (list_seq, sep_list_pair); -- insert separator between two items; returns list_seq[1] then only one item elseif 2 < count then list = table.concat (list_seq, sep_list, 1, count - 1); -- concatenate all but last item with plain list separator list = table.concat ({list, list_seq[count]}, sep_list_end); -- concatenate last item onto end of <list> with final separator end return list; end --[[--------------------------< S E L E C T _ O N E >---------------------------------------------------------- Chooses one matching parameter from a list of parameters to consider. The list of parameters to consider is just names. For parameters that may be enumerated, the position of the numerator in the parameter name is identified by the '#' so |author-last1= and |author1-last= are represented as 'author-last#' and 'author#-last'. Because enumerated parameter |<param>1= is an alias of |<param>= we must test for both possibilities. Generates an error if more than one match is present. ]] local function select_one (args, aliases_list, error_condition, index) local value = nil; -- the value assigned to the selected parameter local selected = ''; -- the name of the parameter we have chosen local error_list = {}; if index ~= nil then index = tostring(index); end for _, alias in ipairs (aliases_list) do -- for each alias in the aliases list if alias:match ('#') then -- if this alias can be enumerated if '1' == index then -- when index is 1 test for enumerated and non-enumerated aliases value, selected = is_alias_used (args, alias, index, false, value, selected, error_list); -- first test for non-enumerated alias end value, selected = is_alias_used (args, alias, index, true, value, selected, error_list); -- test for enumerated alias else value, selected = is_alias_used (args, alias, index, false, value, selected, error_list); -- test for non-enumerated alias end end if #error_list > 0 and 'none' ~= error_condition then -- for cases where this code is used outside of extract_names() for i, v in ipairs (error_list) do error_list[i] = wrap_style ('parameter', v); end table.insert (error_list, wrap_style ('parameter', selected)); set_message (error_condition, {make_sep_list (#error_list, error_list)}); end return value, selected; end --[=[-------------------------< R E M O V E _ W I K I _ L I N K >---------------------------------------------- Gets the display text from a wikilink like [[A|B]] or [[B]] gives B The str:gsub() returns either A|B froma [[A|B]] or B from [[B]] or B from B (no wikilink markup). In l(), l:gsub() removes the link and pipe (if they exist); the second :gsub() trims whitespace from the label if str was wrapped in wikilink markup. Presumably, this is because without wikimarkup in str, there is no match in the initial gsub, the replacement function l() doesn't get called. ]=] local function remove_wiki_link (str) return (str:gsub ("%[%[([^%[%]]*)%]%]", function(l) return l:gsub ("^[^|]*|(.*)$", "%1" ):gsub ("^%s*(.-)%s*$", "%1"); end)); end --[=[-------------------------< I S _ W I K I L I N K >-------------------------------------------------------- Determines if str is a wikilink, extracts, and returns the wikilink type, link text, and display text parts. If str is a complex wikilink ([[L|D]]): returns wl_type 2 and D and L from [[L|D]]; if str is a simple wikilink ([[D]]) returns wl_type 1 and D from [[D]] and L as empty string; if not a wikilink: returns wl_type 0, str as D, and L as empty string. trims leading and trailing whitespace and pipes from L and D ([[L|]] and [[|D]] are accepted by MediaWiki and treated like [[D]]; while [[|D|]] is not accepted by MediaWiki, here, we accept it and return D without the pipes). ]=] local function is_wikilink (str) local D, L local wl_type = 2; -- assume that str is a complex wikilink [[L|D]] if not str:match ('^%[%[[^%]]+%]%]$') then -- is str some sort of a wikilink (must have some sort of content) return 0, str, ''; -- not a wikilink; return wl_type as 0, str as D, and empty string as L end L, D = str:match ('^%[%[([^|]+)|([^%]]+)%]%]$'); -- get L and D from [[L|D]] if not is_set (D) then -- if no separate display D = str:match ('^%[%[([^%]]*)|*%]%]$'); -- get D from [[D]] or [[D|]] wl_type = 1; end D = mw.text.trim (D, '%s|'); -- trim white space and pipe characters return wl_type, D, L or ''; end --[[--------------------------< S T R I P _ A P O S T R O P H E _ M A R K U P >-------------------------------- Strip wiki italic and bold markup from argument so that it doesn't contaminate COinS metadata. This function strips common patterns of apostrophe markup. We presume that editors who have taken the time to markup a title have, as a result, provided valid markup. When they don't, some single apostrophes are left behind. Returns the argument without wiki markup and a number; the number is more-or-less meaningless except as a flag to indicate that markup was replaced; do not rely on it as an indicator of how many of any kind of markup was removed; returns the argument and nil when no markup removed ]] local function strip_apostrophe_markup (argument) if not is_set (argument) then return argument, nil; -- no argument, nothing to do end if nil == argument:find ( "''", 1, true ) then -- Is there at least one double apostrophe? If not, exit. return argument, nil; end local flag; while true do if argument:find ("'''''", 1, true) then -- bold italic (5) argument, flag = argument:gsub ("%'%'%'%'%'", ""); -- remove all instances of it elseif argument:find ("''''", 1, true) then -- italic start and end without content (4) argument, flag=argument:gsub ("%'%'%'%'", ""); elseif argument:find ("'''", 1, true) then -- bold (3) argument, flag=argument:gsub ("%'%'%'", ""); elseif argument:find ("''", 1, true) then -- italic (2) argument, flag = argument:gsub ("%'%'", ""); else break; end end return argument, flag; -- done end --[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >-------------------------------------- Sets local cfg table to same (live or sandbox) as that used by the other modules. ]] local function set_selected_modules (cfg_table_ptr) cfg = cfg_table_ptr; end --[[--------------------------< E X P O R T S >---------------------------------------------------------------- ]] return { add_maint_cat = add_maint_cat, -- exported functions add_prop_cat = add_prop_cat, error_comment = error_comment, has_accept_as_written = has_accept_as_written, hyphen_to_dash = hyphen_to_dash, in_array = in_array, is_set = is_set, is_wikilink = is_wikilink, make_sep_list = make_sep_list, make_wikilink = make_wikilink, remove_wiki_link = remove_wiki_link, safe_for_italics = safe_for_italics, select_one = select_one, set_message = set_message, set_selected_modules = set_selected_modules, strip_apostrophe_markup = strip_apostrophe_markup, substitute = substitute, wrap_style = wrap_style, z = z, -- exported table } kk801mqzkv4xrvmuck62gy23fyu6dl0 Ronney:Ruggyryn 'sy vlein 1725 14 30010 382121 348099 2026-06-05T00:26:39Z MacTire02 219 clowan noa 382121 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1830 14 30020 382179 347894 2026-06-05T01:22:11Z MacTire02 219 clowan noa 382179 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Module:Citation/CS1/Identifiers 828 30232 382126 325426 2026-06-05T00:35:39Z MacTire02 219 ++ 382126 Scribunto text/plain --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- ]] local has_accept_as_written, is_set, in_array, set_message, select_one, -- functions in Module:Citation/CS1/Utilities substitute, make_wikilink; local z; -- table of tables defined in Module:Citation/CS1/Utilities local cfg; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration --[[--------------------------< P A G E S C O P E V A R I A B L E S >-------------------------------------- declare variables here that have page-wide scope that are not brought in from other modules; that are created here and used here ]] local auto_link_urls = {}; -- holds identifier URLs for those identifiers that can auto-link |title= --============================<< H E L P E R F U N C T I O N S >>============================================ --[[--------------------------< W I K I D A T A _ A R T I C L E _ N A M E _ G E T >---------------------------- as an aid to internationalizing identifier-label wikilinks, gets identifier article names from Wikidata. returns w:<lang code>:<article title> when <q> has an <article title> for <lang code>; nil else. 'w:<lang code>' ensures that sister project (like wiktionary) will link to the <lang code>.wikipedia article. for identifiers that do not have <q>, returns nil for wikis that do not have mw.wikibase installed, returns nil ]] local function wikidata_article_name_get (q) if not is_set (q) or (q and not mw.wikibase) then -- when no q number or when a q number but mw.wikibase not installed on this wiki return nil; -- abandon end local wd_article; local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org wd_article = mw.wikibase.getSitelink (q, this_wiki_code .. 'wiki'); -- fetch article title from WD; nil when no title available at this wiki if wd_article then wd_article = table.concat ({'w:', this_wiki_code, ':', wd_article}); -- interwiki-style link without brackets if taken from WD; leading 'w:' required end return wd_article; -- article title from WD; nil else end --[[--------------------------< L A B E L _ L I N K _ M A K E >------------------------------------------------ common function to create a link for an identifier label from handler table or from Wikidata returns the first available of: 1. redirect from local wiki's handler table (if enabled) 2. Wikidata sitelink to the local language wikipedia article (if there is a Wikidata entry for this identifier in the local language) 3. link to wikipedia article specified in the local wiki's handler table ]] local function label_link_make (handler) local wd_article; if not (cfg.use_identifier_redirects and is_set (handler.redirect)) then -- redirect has priority so if enabled and available don't fetch from Wikidata because expensive wd_article = wikidata_article_name_get (handler.q); -- if Wikidata has an article title for this wiki, get it; end return (cfg.use_identifier_redirects and is_set (handler.redirect) and handler.redirect) or wd_article or handler.link; end --[[--------------------------< E X T E R N A L _ L I N K _ I D >---------------------------------------------- Formats a wiki-style external link ]] local function external_link_id (options) local url_string = options.id; local ext_link; local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org local wd_article; -- article title from Wikidata if options.encode == true or options.encode == nil then url_string = mw.uri.encode (url_string, 'PATH'); end if options.auto_link and is_set (options.access) then auto_link_urls[options.auto_link] = table.concat ({options.prefix, url_string, options.suffix}); end ext_link = mw.ustring.format ('[%s%s%s %s]', options.prefix, url_string, options.suffix or "", mw.text.nowiki (options.id)); if is_set (options.access) then ext_link = substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[options.access].class, cfg.presentation[options.access].title, ext_link}); -- add the free-to-read / paywall lock end return table.concat ({ make_wikilink (label_link_make (options), options.label), -- redirect, Wikidata link, or locally specified link (in that order) options.separator or '&nbsp;', ext_link }); end --[[--------------------------< I N T E R N A L _ L I N K _ I D >---------------------------------------------- Formats a wiki-style internal link TODO: Does not currently need to support options.access, options.encode, auto-linking and COinS (as in external_link_id), but may be needed in the future for :m:Interwiki_map custom-prefixes like :arxiv:, :bibcode:, :DOI:, :hdl:, :ISSN:, :JSTOR:, :Openlibrary:, :PMID:, :RFC:. ]] local function internal_link_id (options) local id = mw.ustring.gsub (options.id, '%d', cfg.date_names.local_digits); -- translate 'local' digits to Western 0-9 return table.concat ( { make_wikilink (label_link_make (options), options.label), -- wiki-link the identifier label options.separator or '&nbsp;', -- add the separator make_wikilink ( table.concat ( { options.prefix, id, -- translated to Western digits options.suffix or '' }), substitute (cfg.presentation['bdi'], {'', mw.text.nowiki (options.id)}) -- bdi tags to prevent Latin script identifiers from being reversed at RTL language wikis ); -- nowiki because MediaWiki still has magic links for ISBN and the like; TODO: is it really required? }); end --[[--------------------------< I S _ E M B A R G O E D >------------------------------------------------------ Determines if a PMC identifier's online version is embargoed. Compares the date in |pmc-embargo-date= against today's date. If embargo date is in the future, returns the content of |pmc-embargo-date=; otherwise, returns an empty string because the embargo has expired or because |pmc-embargo-date= was not set in this cite. ]] local function is_embargoed (embargo) if is_set (embargo) then local lang = mw.getContentLanguage(); local good1, embargo_date, todays_date; good1, embargo_date = pcall (lang.formatDate, lang, 'U', embargo); todays_date = lang:formatDate ('U'); if good1 then -- if embargo date is a good date if tonumber (embargo_date) >= tonumber (todays_date) then -- is embargo date is in the future? return embargo; -- still embargoed else set_message ('maint_pmc_embargo'); -- embargo has expired; add main cat return ''; -- unset because embargo has expired end end end return ''; -- |pmc-embargo-date= not set return empty string end --[=[-------------------------< I S _ V A L I D _ R X I V _ D A T E >------------------------------------------ for biorxiv, returns true if: 2019-12-11T00:00Z <= biorxiv_date < today + 2 days for medrxiv, returns true if: 2020-01-01T00:00Z <= medrxiv_date < today + 2 days The dated form of biorxiv identifier has a start date of 2019-12-11. The Unix timestamp for that date is {{#time:U|2019-12-11}} = 1576022400 The medrxiv identifier has a start date of 2020-01-01. The Unix timestamp for that date is {{#time:U|2020-01-01}} = 1577836800 <rxiv_date> is the date provided in those |biorxiv= parameter values that are dated and in |medrxiv= parameter values at time 00:00:00 UTC <today> is the current date at time 00:00:00 UTC plus 48 hours if today's date is 2023-01-01T00:00:00 then adding 24 hours gives 2023-01-02T00:00:00 – one second more than today adding 24 hours gives 2023-01-03T00:00:00 – one second more than tomorrow inputs: <y>, <m>, <d> – year, month, day parts of the date from the birxiv or medrxiv identifier <select> 'b' for biorxiv, 'm' for medrxiv; defaults to 'b' ]=] local function is_valid_rxiv_date (y, m, d, select) if 0 == tonumber (m) and 12 < tonumber (m) then -- <m> must be a number 1–12 return false; end if 0 == tonumber (d) and 31 < tonumber (d) then -- <d> must be a number 1–31; TODO: account for month length and leap yer? return false; end local rxiv_date = table.concat ({y, m, d}, '-'); -- make ymd date string local good1, good2; local rxiv_ts, tomorrow_ts; -- to hold Unix timestamps representing the dates local lang_object = mw.getContentLanguage(); good1, rxiv_ts = pcall (lang_object.formatDate, lang_object, 'U', rxiv_date); -- convert rxiv_date value to Unix timestamp good2, tomorrow_ts = pcall (lang_object.formatDate, lang_object, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow if good1 and good2 then -- lang.formatDate() returns a timestamp in the local script which tonumber() may not understand rxiv_ts = tonumber (rxiv_ts) or lang_object:parseFormattedNumber (rxiv_ts); -- convert to numbers for the comparison; tomorrow_ts = tonumber (tomorrow_ts) or lang_object:parseFormattedNumber (tomorrow_ts); else return false; -- one or both failed to convert to Unix timestamp end local limit_ts = ((select and ('m' == select)) and 1577836800) or 1576022400; -- choose the appropriate limit timesatmp return ((limit_ts <= rxiv_ts) and (rxiv_ts < tomorrow_ts)) -- limit_ts <= rxiv_date < tomorrow's date end --[[--------------------------< IS _ V A L I D _ I S X N >----------------------------------------------------- ISBN-10 and ISSN validator code calculates checksum across all ISBN/ISSN digits including the check digit. ISBN-13 is checked in isbn(). If the number is valid the result will be 0. Before calling this function, ISBN/ISSN must be checked for length and stripped of dashes, spaces and other non-ISxN characters. ]] local function is_valid_isxn (isxn_str, len) local temp = 0; isxn_str = { isxn_str:byte(1, len) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39, 'X' → 0x58 len = len + 1; -- adjust to be a loop counter for i, v in ipairs (isxn_str) do -- loop through all of the bytes and calculate the checksum if v == string.byte ("X" ) then -- if checkdigit is X (compares the byte value of 'X' which is 0x58) temp = temp + 10 * (len - i); -- it represents 10 decimal else temp = temp + tonumber (string.char (v) )*(len-i); end end return temp % 11 == 0; -- returns true if calculation result is zero end --[[--------------------------< IS _ V A L I D _ I S X N _ 1 3 >----------------------------------------------- ISBN-13 and ISMN validator code calculates checksum across all 13 ISBN/ISMN digits including the check digit. If the number is valid, the result will be 0. Before calling this function, ISBN-13/ISMN must be checked for length and stripped of dashes, spaces and other non-ISxN-13 characters. ]] local function is_valid_isxn_13 (isxn_str) local temp=0; isxn_str = { isxn_str:byte(1, 13) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39 for i, v in ipairs (isxn_str) do temp = temp + (3 - 2*(i % 2)) * tonumber (string.char (v) ); -- multiply odd index digits by 1, even index digits by 3 and sum; includes check digit end return temp % 10 == 0; -- sum modulo 10 is zero when ISBN-13/ISMN is correct end --[[--------------------------< N O R M A L I Z E _ L C C N >-------------------------------------------------- LCCN normalization (https://www.loc.gov/marc/lccn-namespace.html#normalization) 1. Remove all blanks. 2. If there is a forward slash (/) in the string, remove it, and remove all characters to the right of the forward slash. 3. If there is a hyphen in the string: a. Remove it. b. Inspect the substring following (to the right of) the (removed) hyphen. Then (and assuming that steps 1 and 2 have been carried out): 1. All these characters should be digits, and there should be six or less. (not done in this function) 2. If the length of the substring is less than 6, left-fill the substring with zeroes until the length is six. Returns a normalized LCCN for lccn() to validate. There is no error checking (step 3.b.1) performed in this function. ]] local function normalize_lccn (lccn) lccn = lccn:gsub ("%s", ""); -- 1. strip whitespace if nil ~= string.find (lccn, '/') then lccn = lccn:match ("(.-)/"); -- 2. remove forward slash and all character to the right of it end local prefix local suffix prefix, suffix = lccn:match ("(.+)%-(.+)"); -- 3.a remove hyphen by splitting the string into prefix and suffix if nil ~= suffix then -- if there was a hyphen suffix = string.rep("0", 6-string.len (suffix)) .. suffix; -- 3.b.2 left fill the suffix with 0s if suffix length less than 6 lccn = prefix..suffix; -- reassemble the LCCN end return lccn; end --============================<< I D E N T I F I E R F U N C T I O N S >>==================================== --[[--------------------------< A R X I V >-------------------------------------------------------------------- See: https://arxiv.org/help/arxiv_identifier format and error check arXiv identifier. There are three valid forms of the identifier: the first form, valid only between date codes 9107 and 0703, is: arXiv:<archive>.<class>/<date code><number><version> where: <archive> is a string of alpha characters - may be hyphenated; no other punctuation <class> is a string of alpha characters - may be hyphenated; no other punctuation; not the same as |class= parameter which is not supported in this form <date code> is four digits in the form YYMM where YY is the last two digits of the four-digit year and MM is the month number January = 01 first digit of YY for this form can only 9 and 0 <number> is a three-digit number <version> is a 1 or more digit number preceded with a lowercase v; no spaces (undocumented) the second form, valid from April 2007 through December 2014 is: arXiv:<date code>.<number><version> where: <date code> is four digits in the form YYMM where YY is the last two digits of the four-digit year and MM is the month number January = 01 <number> is a four-digit number <version> is a 1 or more digit number preceded with a lowercase v; no spaces the third form, valid from January 2015 is: arXiv:<date code>.<number><version> where: <date code> and <version> are as defined for 0704-1412 <number> is a five-digit number ]] local function arxiv (options) local id = options.id; local class = options.Class; -- TODO: lowercase? local handler = options.handler; local year, month, version; local err_msg = false; -- assume no error message local text; -- output text if id:match("^%a[%a%.%-]+/[90]%d[01]%d%d%d%d$") or id:match("^%a[%a%.%-]+/[90]%d[01]%d%d%d%dv%d+$") then -- test for the 9107-0703 format with or without version year, month = id:match("^%a[%a%.%-]+/([90]%d)([01]%d)%d%d%d[v%d]*$"); year = tonumber (year); month = tonumber (month); if ((not (90 < year or 8 > year)) or (1 > month or 12 < month)) or -- if invalid year or invalid month ((91 == year and 7 > month) or (7 == year and 3 < month)) then -- if years ok, are starting and ending months ok? err_msg = true; -- flag for error message end elseif id:match("^%d%d[01]%d%.%d%d%d%d$") or id:match("^%d%d[01]%d%.%d%d%d%dv%d+$") then -- test for the 0704-1412 with or without version year, month = id:match("^(%d%d)([01]%d)%.%d%d%d%d[v%d]*$"); year = tonumber (year); month = tonumber (month); if ((7 > year) or (14 < year) or (1 > month or 12 < month)) or -- is year invalid or is month invalid? (doesn't test for future years) ((7 == year) and (4 > month)) then -- when year is 07, is month invalid (before April)? err_msg = true; -- flag for error message end elseif id:match("^%d%d[01]%d%.%d%d%d%d%d$") or id:match("^%d%d[01]%d%.%d%d%d%d%dv%d+$") then -- test for the 1501- format with or without version year, month = id:match("^(%d%d)([01]%d)%.%d%d%d%d%d[v%d]*$"); year = tonumber (year); month = tonumber (month); if ((15 > year) or (1 > month or 12 < month)) then -- is year invalid or is month invalid? (doesn't test for future years) err_msg = true; -- flag for error message end else err_msg = true; -- not a recognized format; flag for error message end if err_msg then options.coins_list_t['ARXIV'] = nil; -- when error, unset so not included in COinS end local err_msg_t = {}; if err_msg then set_message ('err_bad_arxiv'); end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); if is_set (class) then if id:match ('^%d+') then text = table.concat ({text, ' [[https://arxiv.org/archive/', class, ' ', class, ']]'}); -- external link within square brackets, not wikilink else set_message ('err_class_ignored'); end else -- class not set if id:match ('^%d+') and options.CitationClass == 'arxiv' then -- new (post 2007) format; {{cite arxiv}} only set_message ('maint_missing_class'); -- add maint cat end end return text; end --[[--------------------------< B I B C O D E >-------------------------------------------------------------------- Validates (sort of) and formats a bibcode ID. Format for bibcodes is specified here: https://adsabs.harvard.edu/abs_doc/help_pages/data.html#bibcodes But, this: 2015arXiv151206696F is apparently valid so apparently, the only things that really matter are length, 19 characters and first four digits must be a year. This function makes these tests: length must be 19 characters characters in position 1–4 must be digits and must represent a year in the range of 1000 – next year 5 must be a letter 6–8 must be letter, digit, ampersand, or dot (ampersand cannot directly precede a dot; &. ) 9–18 must be letter, digit, or dot 19 must be a letter or dot ]] local function bibcode (options) local id = options.id; local access = options.access; local handler = options.handler; local ignore_invalid = options.accept; local err_type; local err_msg = ''; local year; local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access}); if 19 ~= id:len() then err_type = cfg.err_msg_supl.length; else year = id:match ("^(%d%d%d%d)[%a][%w&%.][%w&%.][%w&%.][%w.]+[%a%.]$"); if not year then -- if nil then no pattern match err_type = cfg.err_msg_supl.value; -- so value error else local next_year = tonumber (os.date ('%Y')) + 1; -- get the current year as a number and add one for next year year = tonumber (year); -- convert year portion of bibcode to a number if (1000 > year) or (year > next_year) then err_type = cfg.err_msg_supl.year; -- year out of bounds end if id:find('&%.') then err_type = cfg.err_msg_supl.journal; -- journal abbreviation must not have '&.' (if it does it's missing a letter) end if id:match ('.........%.tmp%.') then -- temporary bibcodes when positions 10–14 are '.tmp.' set_message ('maint_bibcode'); end end end if is_set (err_type) and not ignore_invalid then -- if there was an error detected and accept-as-written markup not used set_message ('err_bad_bibcode', {err_type}); options.coins_list_t['BIBCODE'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< B I O R X I V >----------------------------------------------------------------- Format bioRxiv ID and do simple error checking. Before 2019-12-11, biorXiv IDs were 10.1101/ followed by exactly 6 digits. After 2019-12-11, biorXiv IDs retained the six-digit identifier but prefixed that with a yyyy.mm.dd. date and suffixed with an optional version identifier. From December 2025 biorxiv added a new 'doi' prefix: 10.64898: 10.64898/2025.12.10.693067 The bioRxiv ID is the string of characters: https://doi.org/10.1101/078733 -> 10.1101/078733 or a date followed by a six-digit number followed by an optional version indicator 'v' and one or more digits: https://www.biorxiv.org/content/10.1101/2019.12.11.123456v2 -> 10.1101/2019.12.11.123456v2 see https://www.biorxiv.org/about-biorxiv ]] local function biorxiv (options) local id = options.id; local handler = options.handler; local err_msg = true; -- flag; assume that there will be an error local patterns = { '^10%.1101/%d%d%d%d%d%d$', -- simple 6-digit identifier (before 2019-12-11) '^10%.1101/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%dv%d+$', -- y.m.d. date + 6-digit identifier + version (after 2019-12-11) '^10%.1101/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%d$', -- y.m.d. date + 6-digit identifier (after 2019-12-11) '^10%.64898/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%dv%d+$', -- y.m.d. date + 6-digit identifier + version (from December 2025) '^10%.64898/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%d$', -- y.m.d. date + 6-digit identifier (from December 2025) } for _, pattern in ipairs (patterns) do -- spin through the patterns looking for a match if id:match (pattern) then local y, m, d = id:match (pattern); -- found a match, attempt to get year, month and date from the identifier if m then -- m is nil when id is the six-digit form if not is_valid_rxiv_date (y, m, d, 'b') then -- validate the encoded date; 'b' for biorxiv limit break; -- date fail; break out early so we don't unset the error message end end err_msg = nil; -- we found a match so unset the error message break; -- and done end end -- err_cat remains set here when no match if err_msg then options.coins_list_t['BIORXIV'] = nil; -- when error, unset so not included in COinS set_message ('err_bad_biorxiv'); -- and set the error message end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); end --[[--------------------------< C I T E S E E R X >------------------------------------------------------------ CiteSeerX use their own notion of "doi" (not to be confused with the identifiers resolved via doi.org). The description of the structure of this identifier can be found at Help_talk:Citation_Style_1/Archive_26#CiteSeerX_id_structure ]] local function citeseerx (options) local id = options.id; local handler = options.handler; local matched; local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); matched = id:match ("^10%.1%.1%.[1-9]%d?%d?%d?%.[1-9]%d?%d?%d?$"); if not matched then set_message ('err_bad_citeseerx' ); options.coins_list_t['CITESEERX'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< D O I >------------------------------------------------------------------------ Formats a DOI and checks for DOI errors. DOI names contain two parts: prefix and suffix separated by a forward slash. Prefix: directory indicator '10.' followed by a registrant code Suffix: character string of any length chosen by the registrant This function checks a DOI name for: prefix/suffix. If the DOI name contains spaces or endashes, or, if it ends with a period or a comma, this function will emit a bad_doi error message. DOI names are case-insensitive and can incorporate any printable Unicode characters so the test for spaces, endash, and terminal punctuation may not be technically correct but it appears, that in practice these characters are rarely if ever used in DOI names. https://www.doi.org/doi_handbook/2_Numbering.html -- 2.2 Syntax of a DOI name https://www.doi.org/doi_handbook/2_Numbering.html#2.2.2 -- 2.2.2 DOI prefix ]] local function doi (options) local id = options.id; local inactive = options.DoiBroken local access = options.access; local ignore_invalid = options.accept; local handler = options.handler; local err_flag; local function is_extended_free (registrant, suffix) -- local function to check those few registrants that are mixed; identifiable by the doi suffix <incipit> suffix = suffix:lower(); -- ascii [a-z] same as [A-Z] in doi names; see §3.4.4 Case Insensitivity of the Doi Name if cfg.extended_registrants_t[registrant] then -- if this registrant has known free-to-read extentions for _, incipit in ipairs (cfg.extended_registrants_t[registrant]) do -- loop through the registrant's incipits if mw.ustring.find (suffix, '^' .. incipit:lower()) then -- ascii [a-z] same as [A-Z] in doi names return true; -- if foundm done end end end end local text; if is_set (inactive) then local inactive_year = inactive:match("%d%d%d%d"); -- try to get the year portion from the inactive date local inactive_month, good; if is_set (inactive_year) then if 4 < inactive:len() then -- inactive date has more than just a year (could be anything) local lang_obj = mw.getContentLanguage(); -- get a language object for this wiki good, inactive_month = pcall (lang_obj.formatDate, lang_obj, 'F', inactive); -- try to get the month name from the inactive date if not good then inactive_month = nil; -- something went wrong so make sure this is unset end end end -- otherwise, |doi-broken-date= has something but it isn't a date if is_set (inactive_year) and is_set (inactive_month) then set_message ('maint_doi_inactive_dated', {inactive_year, inactive_month, ' '}); elseif is_set (inactive_year) then set_message ('maint_doi_inactive_dated', {inactive_year, '', ''}); else set_message ('maint_doi_inactive'); end inactive = substitute (cfg.messages['inactive'], inactive ); end local suffix; local registrant, suffix = mw.ustring.match (id, '^10%.([^/]+)/([^%s–]-[^%.,])$'); -- registrant and suffix set when DOI has the proper basic form; both nil else local registrant_err_patterns = { -- these patterns are for code ranges that are not supported '^[^1-3]%d%d%d%d%.%d+$', -- 5 digits with subcode (reject 0xxxx, 40000+); accepts: 10000–39999 '^[^1-8]%d%d%d%d$', -- 5 digits without subcode (reject 0xxxx, 90000+); accepts: 10000–89999 '^[^1-9]%d%d%d%.%d+$', -- 4 digits with subcode (reject 0xxx); accepts: 1000–9999 '^[^1-9]%d%d%d$', -- 4 digits without subcode (reject 0xxx); accepts: 1000–9999 '^%d%d%d%d%d%d+', -- 6 or more digits '^%d%d?%d?$', -- less than 4 digits without subcode (3 digits with subcode is legitimate) '^%d%d?%.[%d%.]+', -- 1 or 2 digits with subcode '^5555$', -- test registrant will never resolve '[^%d%.]', -- any character that isn't a digit or a dot } if not ignore_invalid then if registrant then -- when DOI has proper form for i, pattern in ipairs (registrant_err_patterns) do -- spin through error patterns if registrant:match (pattern) then -- to validate registrant codes err_flag = set_message ('err_bad_doi'); -- when found, mark this DOI as bad break; -- and done end end else err_flag = set_message ('err_bad_doi'); -- invalid directory or malformed end else set_message ('maint_doi_ignore'); end if err_flag then options.coins_list_t['DOI'] = nil; -- when error, unset so not included in COinS else -- here when doi has no errors or has been wrapped in accept-as-written markup suffix = mw.ustring.match (id, '^10%.[^/]+/(.+)'); -- refetch suffix because doi may have been wrapped in accept-as-written markup if not access and (cfg.known_free_doi_registrants_t[registrant] or is_extended_free (registrant, suffix)) then -- |doi-access=free not set and <registrant> is known to be free set_message ('maint_doi_unflagged_free'); -- set a maint cat end end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access, auto_link = not (err_flag or is_set (inactive) or ignore_invalid) and 'doi' or nil -- do not auto-link when |doi-broken-date= has a value or when there is a DOI error or (to play it safe, after all, auto-linking is not essential) when invalid DOIs are ignored }) .. (inactive or ''); return text; end --[[--------------------------< H D L >------------------------------------------------------------------------ Formats an HDL with minor error checking. HDL names contain two parts: prefix and suffix separated by a forward slash. Prefix: character string using any character in the UCS-2 character set except '/' Suffix: character string of any length using any character in the UCS-2 character set chosen by the registrant This function checks a HDL name for: prefix/suffix. If the HDL name contains spaces, endashes, or, if it ends with a period or a comma, this function will emit a bad_hdl error message. HDL names are case-insensitive and can incorporate any printable Unicode characters so the test for endashes and terminal punctuation may not be technically correct but it appears, that in practice these characters are rarely if ever used in HDLs. Query string parameters are named here: https://www.handle.net/proxy_servlet.html. query strings are not displayed but since '?' is an allowed character in an HDL, '?' followed by one of the query parameters is the only way we have to detect the query string so that it isn't URL-encoded with the rest of the identifier. ]] local function hdl (options) local id = options.id; local access = options.access; local handler = options.handler; local query_params = { -- list of known query parameters from https://www.handle.net/proxy_servlet.html 'noredirect', 'ignore_aliases', 'auth', 'cert', 'index', 'type', 'urlappend', 'locatt', 'action', } local hdl, suffix, param = id:match ('(.-)(%?(%a+).+)$'); -- look for query string local found; if hdl then -- when there are query strings, this is the handle identifier portion for _, q in ipairs (query_params) do -- spin through the list of query parameters if param:match ('^' .. q) then -- if the query string begins with one of the parameters found = true; -- announce a find break; -- and stop looking end end end if found then id = hdl; -- found so replace id with the handle portion; this will be URL-encoded, suffix will not else suffix = ''; -- make sure suffix is empty string for concatenation else end local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, suffix = suffix, separator = handler.separator, encode = handler.encode, access = access}) if nil == id:match("^[^%s–]-/[^%s–]-[^%.,]$") then -- HDL must contain a forward slash, must not contain spaces, endashes, and must not end with period or comma set_message ('err_bad_hdl' ); options.coins_list_t['HDL'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< I S B N >---------------------------------------------------------------------- Determines whether an ISBN string is valid ]] local function isbn (options_t) local isbn_str = options_t.id; local ignore_invalid = options_t.accept; local handler = options_t.handler; local year = options_t.Year; -- when set, valid anchor_year; may have a disambiguator which must be removed local function return_result (check, err_type) -- local function to handle the various returns local ISBN = internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect, prefix = handler.prefix, id = isbn_str, separator = handler.separator}); if ignore_invalid then -- if ignoring ISBN errors set_message ('maint_isbn_ignore'); -- add a maint category even when there is no error else -- here when not ignoring if not check then -- and there is an error options_t.coins_list_t['ISBN'] = nil; -- when error, unset so not included in COinS set_message ('err_bad_isbn', err_type); -- set an error message return ISBN; -- return id text end end return ISBN; -- return id text end if year and not ignore_invalid then -- year = year:match ('%d%d%d%d?'); -- strip disambiguator if present if year and (1965 > tonumber(year)) then -- <year> will be nil here when |year=n.d. or |year=nd set_message ('err_invalid_isbn_date'); -- set an error message return internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect, prefix = handler.prefix, id = isbn_str, separator = handler.separator}); end end if nil ~= isbn_str:match ('[^%s-0-9X]') then return return_result (false, cfg.err_msg_supl.char); -- fail if isbn_str contains anything but digits, hyphens, or the uppercase X end local id = isbn_str:gsub ('[%s-]', ''); -- remove hyphens and whitespace local len = id:len(); if len ~= 10 and len ~= 13 then return return_result (false, cfg.err_msg_supl.length); -- fail if incorrect length end if len == 10 then if id:match ('^%d*X?$') == nil then -- fail if isbn_str has 'X' anywhere but last position return return_result (false, cfg.err_msg_supl.form); end if not is_valid_isxn (id, 10) then -- test isbn-10 for numerical validity return return_result (false, cfg.err_msg_supl.check); -- fail if isbn-10 is not numerically valid end if id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not valid isbn group ids but are used by amazon as numeric identifiers (asin) return return_result (false, cfg.err_msg_supl.group); -- fail if isbn-10 begins with 630/1 end return return_result (true, cfg.err_msg_supl.check); -- pass if isbn-10 is numerically valid else if id:match ('^%d+$') == nil then return return_result (false, cfg.err_msg_supl.char); -- fail if ISBN-13 is not all digits end if id:match ('^97[89]%d*$') == nil then return return_result (false, cfg.err_msg_supl.prefix); -- fail when ISBN-13 does not begin with 978 or 979 end if id:match ('^9790') then return return_result (false, cfg.err_msg_supl.group); -- group identifier '0' is reserved to ISMN end return return_result (is_valid_isxn_13 (id), cfg.err_msg_supl.check); end end --[[--------------------------< A S I N >---------------------------------------------------------------------- Formats a link to Amazon. Do simple error checking: ASIN must be mix of 10 numeric or uppercase alpha characters. If a mix, first character must be uppercase alpha; if all numeric, ASINs must be 10-digit ISBN. If 10-digit ISBN, add a maintenance category so a bot or AWB script can replace |asin= with |isbn=. Error message if not 10 characters, if not ISBN-10, if mixed and first character is a digit. |asin=630....... and |asin=631....... are (apparently) not a legitimate ISBN though it checksums as one; these do not cause this function to emit the maint_asin message This function is positioned here because it calls isbn() ]] local function asin (options) local id = options.id; local domain = options.ASINTLD; local err_flag; if not id:match("^[%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u]$") then err_flag = set_message ('err_bad_asin'); -- ASIN is not a mix of 10 uppercase alpha and numeric characters else if id:match("^%d%d%d%d%d%d%d%d%d[%dX]$") then -- if 10-digit numeric (or 9 digits with terminal X) if is_valid_isxn (id, 10) then -- see if ASIN value is or validates as ISBN-10 if not id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not a valid isbn prefixes but are used by amazon as a numeric identifier err_flag = set_message ('err_bad_asin'); -- ASIN has ISBN-10 form but begins with something other than 630/1 so probably an isbn end elseif not is_set (err_flag) then err_flag = set_message ('err_bad_asin'); -- ASIN is not ISBN-10 end elseif not id:match("^%u[%d%u]+$") then err_flag = set_message ('err_bad_asin'); -- asin doesn't begin with uppercase alpha end end if (not is_set (domain)) or in_array (domain, {'us'}) then -- default: United States domain = "com"; elseif in_array (domain, {'jp', 'uk'}) then -- Japan, United Kingdom domain = "co." .. domain; elseif in_array (domain, {'z.cn'}) then -- China domain = "cn"; elseif in_array (domain, {'au', 'br', 'mx', 'sg', 'tr'}) then -- Australia, Brazil, Mexico, Singapore, Turkey domain = "com." .. domain; elseif not in_array (domain, {'ae', 'ca', 'cn', 'de', 'es', 'fr', 'in', 'it', 'nl', 'pl', 'sa', 'se', 'co.jp', 'co.uk', 'com', 'com.au', 'com.br', 'com.mx', 'com.sg', 'com.tr'}) then -- Arabic Emirates, Canada, China, Germany, Spain, France, Indonesia, Italy, Netherlands, Poland, Saudi Arabia, Sweden (as of 2021-03 Austria (.at), Liechtenstein (.li) and Switzerland (.ch) still redirect to the German site (.de) with special settings, so don't maintain local ASINs for them) err_flag = set_message ('err_bad_asin_tld'); -- unsupported asin-tld value end local handler = options.handler; if not is_set (err_flag) then options.coins_list_t['ASIN'] = handler.prefix .. domain .. "/dp/" .. id; -- asin for coins else options.coins_list_t['ASIN'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix .. domain .. "/dp/", id = id, encode = handler.encode, separator = handler.separator}) end --[[--------------------------< I S M N >---------------------------------------------------------------------- Determines whether an ISMN string is valid. Similar to ISBN-13, ISMN is 13 digits beginning 979-0-... and uses the same check digit calculations. See https://www.ismn-international.org/download/Web_ISMN_Users_Manual_2008-6.pdf section 2, pages 9–12. ismn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx) or an identifier registered at info-uri.info (info:) ]] local function ismn (options) local id = options.id; local handler = options.handler; local text; local valid_ismn = true; local id_copy; id_copy = id; -- save a copy because this testing is destructive id = id:gsub ('[%s-]', ''); -- remove hyphens and white space if 13 ~= id:len() or id:match ("^9790%d*$" ) == nil then -- ISMN must be 13 digits and begin with 9790 valid_ismn = false; else valid_ismn=is_valid_isxn_13 (id); -- validate ISMN end -- text = internal_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, -- use this (or external version) when there is some place to link to -- prefix = handler.prefix, id = id_copy, separator = handler.separator, encode = handler.encode}) text = table.concat ( -- because no place to link to yet { make_wikilink (label_link_make (handler), handler.label), handler.separator, id_copy }); if false == valid_ismn then options.coins_list_t['ISMN'] = nil; -- when error, unset so not included in COinS; not really necessary here because ismn not made part of COinS set_message ('err_bad_ismn'); -- create an error message if the ISMN is invalid end return text; end --[[--------------------------< I S S N >---------------------------------------------------------------------- Validate and format an ISSN. This code fixes the case where an editor has included an ISSN in the citation but has separated the two groups of four digits with a space. When that condition occurred, the resulting link looked like this: |issn=0819 4327 gives: [https://www.worldcat.org/issn/0819 4327 0819 4327] -- can't have spaces in an external link This code now prevents that by inserting a hyphen at the ISSN midpoint. It also validates the ISSN for length and makes sure that the checkdigit agrees with the calculated value. Incorrect length (8 digits), characters other than 0-9 and X, or checkdigit / calculated value mismatch will all cause a check ISSN error message. The ISSN is always displayed with a hyphen, even if the ISSN was given as a single group of 8 digits. ]] local function issn (options) local id = options.id; local handler = options.handler; local ignore_invalid = options.accept; local issn_copy = id; -- save a copy of unadulterated ISSN; use this version for display if ISSN does not validate local text; local valid_issn = true; id = id:gsub ('[%s-]', ''); -- remove hyphens and whitespace if 8 ~= id:len() or nil == id:match ("^%d*X?$" ) then -- validate the ISSN: 8 digits long, containing only 0-9 or X in the last position valid_issn = false; -- wrong length or improper character else valid_issn = is_valid_isxn (id, 8); -- validate ISSN end if true == valid_issn then id = string.sub (id, 1, 4 ) .. "-" .. string.sub (id, 5 ); -- if valid, display correctly formatted version else id = issn_copy; -- if not valid, show the invalid ISSN with error message end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}) if ignore_invalid then set_message ('maint_issn_ignore'); else if false == valid_issn then options.coins_list_t['ISSN'] = nil; -- when error, unset so not included in COinS set_message ('err_bad_issn', (options.hkey == 'EISSN') and 'e' or ''); -- create an error message if the ISSN is invalid end end return text; end --[[--------------------------< J F M >----------------------------------------------------------------------- A numerical identifier in the form nn.nnnn.nn ]] local function jfm (options) local id = options.id; local handler = options.handler; local id_num; id_num = id:match ('^[Jj][Ff][Mm](.*)$'); -- identifier with jfm prefix; extract identifier if is_set (id_num) then set_message ('maint_jfm_format'); else -- plain number without JFM prefix id_num = id; -- if here id does not have prefix end if id_num and id_num:match('^%d%d%.%d%d%d%d%.%d%d$') then id = id_num; -- jfm matches pattern else set_message ('err_bad_jfm' ); -- set an error message options.coins_list_t['JFM'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< J S T O R >-------------------------------------------------------------------- Format a JSTOR with some error checking ]] local function jstor (options) local id = options.id; local access = options.access; local handler = options.handler; if id:find ('[Jj][Ss][Tt][Oo][Rr]') or id:find ('^https?://') or id:find ('%s') then set_message ('err_bad_jstor'); -- set an error message options.coins_list_t['JSTOR'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access}); end --[[--------------------------< L C C N >---------------------------------------------------------------------- Format LCCN link and do simple error checking. LCCN is a character string 8-12 characters long. The length of the LCCN dictates the character type of the first 1-3 characters; the rightmost eight are always digits. https://oclc-research.github.io/infoURI-Frozen/info-uri.info/info:lccn/reg.html length = 8 then all digits length = 9 then lccn[1] is lowercase alpha length = 10 then lccn[1] and lccn[2] are both lowercase alpha or both digits length = 11 then lccn[1] is lower case alpha, lccn[2] and lccn[3] are both lowercase alpha or both digits length = 12 then lccn[1] and lccn[2] are both lowercase alpha ]] local function lccn (options) local lccn = options.id; local handler = options.handler; local err_flag; -- presume that LCCN is valid local id = lccn; -- local copy of the LCCN id = normalize_lccn (id); -- get canonical form (no whitespace, hyphens, forward slashes) local len = id:len(); -- get the length of the LCCN if 8 == len then if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits) err_flag = set_message ('err_bad_lccn'); -- set an error message end elseif 9 == len then -- LCCN should be adddddddd if nil == id:match("%l%d%d%d%d%d%d%d%d") then -- does it match our pattern? err_flag = set_message ('err_bad_lccn'); -- set an error message end elseif 10 == len then -- LCCN should be aadddddddd or dddddddddd if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits) ... if nil == id:match("^%l%l%d%d%d%d%d%d%d%d") then -- ... see if it matches our pattern err_flag = set_message ('err_bad_lccn'); -- no match, set an error message end end elseif 11 == len then -- LCCN should be aaadddddddd or adddddddddd if not (id:match("^%l%l%l%d%d%d%d%d%d%d%d") or id:match("^%l%d%d%d%d%d%d%d%d%d%d")) then -- see if it matches one of our patterns err_flag = set_message ('err_bad_lccn'); -- no match, set an error message end elseif 12 == len then -- LCCN should be aadddddddddd if not id:match("^%l%l%d%d%d%d%d%d%d%d%d%d") then -- see if it matches our pattern err_flag = set_message ('err_bad_lccn'); -- no match, set an error message end else err_flag = set_message ('err_bad_lccn'); -- wrong length, set an error message end if not is_set (err_flag) and nil ~= lccn:find ('%s') then err_flag = set_message ('err_bad_lccn'); -- lccn contains a space, set an error message end if is_set (err_flag) then options.coins_list_t['LCCN'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = lccn, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< M E D R X I V >----------------------------------------------------------------- Format medRxiv ID and do simple error checking. Similar to later bioRxiv IDs, medRxiv IDs are prefixed with a yyyy.mm.dd. date and suffixed with an optional version identifier. Ealiest date accepted is 2020.01.01 The medRxiv ID is a date followed by an eight-digit number followed by an optional version indicator 'v' and one or more digits: https://www.medrxiv.org/content/10.1101/2020.11.16.20232009v2 -> 10.1101/2020.11.16.20232009v2 ]] local function medrxiv (options) local id = options.id; local handler = options.handler; local err_msg_flag = true; -- flag; assume that there will be an error local patterns = { '^%d%d%d%d%d%d%d%d$', -- simple 8-digit identifier; these should be relatively rare '^10%.1101/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%d%d%dv%d+$', -- y.m.d. date + 8-digit identifier + version (2020-01-01 and later) '^10%.1101/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%d%d%d$', -- y.m.d. date + 8-digit identifier (2020-01-01 and later) '^10%.64898/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%d%d%dv%d+$', -- y.m.d. date + 8-digit identifier + version (2025-12-01 and later) '^10%.64898/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%d%d%d$', -- y.m.d. date + 8-digit identifier (2025-12-01 and later) } for _, pattern in ipairs (patterns) do -- spin through the patterns looking for a match if id:match (pattern) then local y, m, d = id:match (pattern); -- found a match, attempt to get year, month and date from the identifier if m then -- m is nil when id is the 8-digit form if not is_valid_rxiv_date (y, m, d, 'b') then -- validate the encoded date; 'b' for medrxiv limit break; -- date fail; break out early so we don't unset the error message end end err_msg_flag = nil; -- we found a match so unset the error message break; -- and done end end -- <err_msg_flag> remains set here when no match if err_msg_flag then options.coins_list_t['MEDRXIV'] = nil; -- when error, unset so not included in COinS set_message ('err_bad_medrxiv'); -- and set the error message end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); end --[[--------------------------< M R >-------------------------------------------------------------------------- A seven digit number; if not seven digits, zero-fill leading digits to make seven digits. ]] local function mr (options) local id = options.id; local handler = options.handler; local id_num; local id_len; id_num = id:match ('^[Mm][Rr](%d+)$'); -- identifier with mr prefix if is_set (id_num) then set_message ('maint_mr_format'); -- add maint cat else -- plain number without mr prefix id_num = id:match ('^%d+$'); -- if here id is all digits end id_len = id_num and id_num:len() or 0; if (7 >= id_len) and (0 ~= id_len) then id = string.rep ('0', 7-id_len) .. id_num; -- zero-fill leading digits else set_message ('err_bad_mr'); -- set an error message options.coins_list_t['MR'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< O C L C >---------------------------------------------------------------------- Validate and format an OCLC ID. https://www.oclc.org/batchload/controlnumber.en.html {{dead link}} archived at: https://web.archive.org/web/20161228233804/https://www.oclc.org/batchload/controlnumber.en.html ]] local function oclc (options) local id = options.id; local handler = options.handler; local number; if id:match('^ocm%d%d%d%d%d%d%d%d$') then -- ocm prefix and 8 digits; 001 field (12 characters) number = id:match('ocm(%d+)'); -- get the number elseif id:match('^ocn%d%d%d%d%d%d%d%d%d$') then -- ocn prefix and 9 digits; 001 field (12 characters) number = id:match('ocn(%d+)'); -- get the number elseif id:match('^on%d%d%d%d%d%d%d%d%d%d+$') then -- on prefix and 10 or more digits; 001 field (12 characters) number = id:match('^on(%d%d%d%d%d%d%d%d%d%d+)$'); -- get the number elseif id:match('^%(OCoLC%)[1-9]%d*$') then -- (OCoLC) prefix and variable number digits; no leading zeros; 035 field number = id:match('%(OCoLC%)([1-9]%d*)'); -- get the number if 9 < number:len() then number = nil; -- constrain to 1 to 9 digits; change this when OCLC issues 10-digit numbers end elseif id:match('^%d+$') then -- no prefix number = id; -- get the number if tonumber (id) > handler.id_limit then number = nil; -- unset when id value exceeds the limit end end if number then -- proper format id = number; -- exclude prefix, if any, from external link else set_message ('err_bad_oclc') -- add an error message if the id is malformed options.coins_list_t['OCLC'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< O P E N L I B R A R Y >-------------------------------------------------------- Formats an OpenLibrary link, and checks for associated errors. ]] local function openlibrary (options) local id = options.id; local access = options.access; local handler = options.handler; local ident, code = id:gsub('^OL', ''):match("^(%d+([AMW]))$"); -- strip optional OL prefix followed immediately by digits followed by 'A', 'M', or 'W'; local err_flag; local prefix = { -- these are appended to the handler.prefix according to code ['A']='authors/OL', ['M']='books/OL', ['W']='works/OL', ['X']='OL' -- not a code; spoof when 'code' in id is invalid }; if not ident then code = 'X'; -- no code or id completely invalid ident = id; -- copy id to ident so that we display the flawed identifier err_flag = set_message ('err_bad_ol'); end if not is_set (err_flag) then options.coins_list_t['OL'] = handler.prefix .. prefix[code] .. ident; -- experiment for ol coins else options.coins_list_t['OL'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix .. prefix[code], id = ident, separator = handler.separator, encode = handler.encode, access = access}); end --[[--------------------------< O S T I >---------------------------------------------------------------------- Format OSTI and do simple error checking. OSTIs are sequential numbers beginning at 1 and counting up. This code checks the OSTI to see that it contains only digits and is less than test_limit specified in the configuration; the value in test_limit will need to be updated periodically as more OSTIs are issued. NB. 1018 is the lowest OSTI number found in the wild (so far) and resolving OK on the OSTI site ]] local function osti (options) local id = options.id; local access = options.access; local handler = options.handler; if id:match("[^%d]") then -- if OSTI has anything but digits set_message ('err_bad_osti'); -- set an error message options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS else -- OSTI is only digits local id_num = tonumber (id); -- convert id to a number for range testing if 1018 > id_num or handler.id_limit < id_num then -- if OSTI is outside test limit boundaries set_message ('err_bad_osti'); -- set an error message options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS end end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access}); end --[[--------------------------< P M C >------------------------------------------------------------------------ Format a PMC, do simple error checking, and check for embargoed articles. The embargo parameter takes a date for a value. If the embargo date is in the future the PMC identifier will not be linked to the article. If the embargo date is today or in the past, or if it is empty or omitted, then the PMC identifier is linked to the article through the link at cfg.id_handlers['PMC'].prefix. PMC embargo date testing is done in function is_embargoed () which is called earlier because when the citation has |pmc=<value> but does not have a |url= then |title= is linked with the PMC link. Function is_embargoed () returns the embargo date if the PMC article is still embargoed, otherwise it returns an empty string. PMCs are sequential numbers beginning at 1 and counting up. This code checks the PMC to see that it contains only digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically as more PMCs are issued. ]] local function pmc (options) local id = options.id; local embargo = options.Embargo; -- TODO: lowercase? local handler = options.handler; local err_flag; local id_num; local text; id_num = id:match ('^[Pp][Mm][Cc](%d+)$'); -- identifier with PMC prefix if is_set (id_num) then set_message ('maint_pmc_format'); else -- plain number without PMC prefix id_num = id:match ('^%d+$'); -- if here id is all digits end if is_set (id_num) then -- id_num has a value so test it id_num = tonumber (id_num); -- convert id_num to a number for range testing if 1 > id_num or handler.id_limit < id_num then -- if PMC is outside test limit boundaries err_flag = set_message ('err_bad_pmc'); -- set an error message else id = tostring (id_num); -- make sure id is a string end else -- when id format incorrect err_flag = set_message ('err_bad_pmc'); -- set an error message end if is_set (embargo) and is_set (is_embargoed (embargo)) then -- is PMC is still embargoed? text = table.concat ( -- still embargoed so no external link { make_wikilink (label_link_make (handler), handler.label), handler.separator, id, }); else text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, -- no embargo date or embargo has expired, ok to link to article prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access, auto_link = not err_flag and 'pmc' or nil -- do not auto-link when PMC has error }); end if err_flag then options.coins_list_t['PMC'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< P M I D >---------------------------------------------------------------------- Format PMID and do simple error checking. PMIDs are sequential numbers beginning at 1 and counting up. This code checks the PMID to see that it contains only digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically as more PMIDs are issued. ]] local function pmid (options) local id = options.id; local handler = options.handler; if id:match("[^%d]") then -- if PMID has anything but digits set_message ('err_bad_pmid'); -- set an error message options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS else -- PMID is only digits local id_num = tonumber (id); -- convert id to a number for range testing if 1 > id_num or handler.id_limit < id_num then -- if PMID is outside test limit boundaries set_message ('err_bad_pmid'); -- set an error message options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS end end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< R F C >------------------------------------------------------------------------ Format RFC and do simple error checking. RFCs are sequential numbers beginning at 1 and counting up. This code checks the RFC to see that it contains only digits and is less than test_limit specified in the configuration; the value in test_limit will need to be updated periodically as more RFCs are issued. An index of all RFCs is here: https://tools.ietf.org/rfc/ ]] local function rfc (options) local id = options.id; local handler = options.handler; if id:match("[^%d]") then -- if RFC has anything but digits set_message ('err_bad_rfc'); -- set an error message options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS else -- RFC is only digits local id_num = tonumber (id); -- convert id to a number for range testing if 1 > id_num or handler.id_limit < id_num then -- if RFC is outside test limit boundaries set_message ('err_bad_rfc'); -- set an error message options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS end end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); end --[[--------------------------< S 2 C I D >-------------------------------------------------------------------- Format an S2CID, do simple error checking S2CIDs are sequential numbers beginning at 1 and counting up. This code checks the S2CID to see that it is only digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically as more S2CIDs are issued. ]] local function s2cid (options) local id = options.id; local access = options.access; local handler = options.handler; local id_num; local text; id_num = id:match ('^[1-9]%d*$'); -- id must be all digits; must not begin with 0; no open access flag if is_set (id_num) then -- id_num has a value so test it id_num = tonumber (id_num); -- convert id_num to a number for range testing if handler.id_limit < id_num then -- if S2CID is outside test limit boundaries set_message ('err_bad_s2cid'); -- set an error message options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS end else -- when id format incorrect set_message ('err_bad_s2cid'); -- set an error message options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access}); return text; end --[[--------------------------< S B N >------------------------------------------------------------------------ 9-digit form of ISBN-10; uses same check-digit validation when SBN is prefixed with an additional '0' to make 10 digits sbn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx) or an identifier registered at info-uri.info (info:) ]] local function sbn (options) local id = options.id; local ignore_invalid = options.accept; local handler = options.handler; local function return_result (check, err_type) -- local function to handle the various returns local SBN = internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator}); if not ignore_invalid then -- if not ignoring SBN errors if not check then options.coins_list_t['SBN'] = nil; -- when error, unset so not included in COinS; not really necessary here because sbn not made part of COinS set_message ('err_bad_sbn', {err_type}); -- display an error message return SBN; end else set_message ('maint_isbn_ignore'); -- add a maint category even when there is no error (ToDo: Possibly switch to separate message for SBNs only) end return SBN; end if id:match ('[^%s-0-9X]') then return return_result (false, cfg.err_msg_supl.char); -- fail if SBN contains anything but digits, hyphens, or the uppercase X end local ident = id:gsub ('[%s-]', ''); -- remove hyphens and whitespace; they interfere with the rest of the tests if 9 ~= ident:len() then return return_result (false, cfg.err_msg_supl.length); -- fail if incorrect length end if ident:match ('^%d*X?$') == nil then return return_result (false, cfg.err_msg_supl.form); -- fail if SBN has 'X' anywhere but last position end return return_result (is_valid_isxn ('0' .. ident, 10), cfg.err_msg_supl.check); end --[[--------------------------< S S R N >---------------------------------------------------------------------- Format an SSRN, do simple error checking SSRNs are sequential numbers beginning at 100? and counting up. This code checks the SSRN to see that it is only digits and is greater than 99 and less than test_limit; the value in local variable test_limit will need to be updated periodically as more SSRNs are issued. ]] local function ssrn (options) local id = options.id; local handler = options.handler; local id_num; local text; id_num = id:match ('^%d+$'); -- id must be all digits if is_set (id_num) then -- id_num has a value so test it id_num = tonumber (id_num); -- convert id_num to a number for range testing if 100 > id_num or handler.id_limit < id_num then -- if SSRN is outside test limit boundaries set_message ('err_bad_ssrn'); -- set an error message options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS end else -- when id format incorrect set_message ('err_bad_ssrn'); -- set an error message options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = options.access}); return text; end --[[--------------------------< U S E N E T _ I D >------------------------------------------------------------ Validate and format a usenet message id. Simple error checking, looks for 'id-left@id-right' not enclosed in '<' and/or '>' angle brackets. ]] local function usenet_id (options) local id = options.id; local handler = options.handler; local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}) if not id:match('^.+@.+$') or not id:match('^[^<].*[^>]$') then -- doesn't have '@' or has one or first or last character is '< or '>' set_message ('err_bad_usenet_id') -- add an error message if the message id is invalid options.coins_list_t['USENETID'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< Z B L >----------------------------------------------------------------------- A numerical identifier in the form nnnn.nnnnn - leading zeros in the first quartet optional format described here: http://emis.mi.sanu.ac.rs/ZMATH/zmath/en/help/search/ temporary format is apparently eight digits. Anything else is an error ]] local function zbl (options) local id = options.id; local handler = options.handler; if id:match('^%d%d%d%d%d%d%d%d$') then -- is this identifier using temporary format? set_message ('maint_zbl'); -- yes, add maint cat elseif not id:match('^%d?%d?%d?%d%.%d%d%d%d%d$') then -- not temporary, is it normal format? set_message ('err_bad_zbl'); -- no, set an error message options.coins_list_t['ZBL'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --============================<< I N T E R F A C E F U N C T I O N S >>========================================== --[[--------------------------< E X T R A C T _ I D S >------------------------------------------------------------ Populates ID table from arguments using configuration settings. Loops through cfg.id_handlers and searches args for any of the parameters listed in each cfg.id_handlers['...'].parameters. If found, adds the parameter and value to the identifier list. Emits redundant error message if more than one alias exists in args ]] local function extract_ids (args) local id_list = {}; -- list of identifiers found in args for k, v in pairs (cfg.id_handlers) do -- k is uppercase identifier name as index to cfg.id_handlers; e.g. cfg.id_handlers['ISBN'], v is a table v = select_one (args, v.parameters, 'err_redundant_parameters' ); -- v.parameters is a table of aliases for k; here we pick one from args if present if is_set (v) then id_list[k] = v; end -- if found in args, add identifier to our list end return id_list; end --[[--------------------------< E X T R A C T _ I D _ A C C E S S _ L E V E L S >-------------------------------------- Fetches custom id access levels from arguments using configuration settings. Parameters which have a predefined access level (e.g. arxiv) do not use this function as they are directly rendered as free without using an additional parameter. returns a table of k/v pairs where k is same as the identifier's key in cfg.id_handlers and v is the assigned (valid) keyword access-level values must match the case used in cfg.keywords_lists['id-access'] (lowercase unless there is some special reason for something else) ]] local function extract_id_access_levels (args, id_list) local id_accesses_list = {}; for k, v in pairs (cfg.id_handlers) do local access_param = v.custom_access; -- name of identifier's access-level parameter if is_set (access_param) then local access_level = args[access_param]; -- get the assigned value if there is one if is_set (access_level) then if not in_array (access_level, cfg.keywords_lists['id-access']) then -- exact match required set_message ('err_invalid_param_val', {access_param, access_level}); access_level = nil; -- invalid so unset end if not is_set (id_list[k]) then -- identifier access-level must have a matching identifier set_message ('err_param_access_requires_param', {k:lower()}); -- parameter name is uppercase in cfg.id_handlers (k); lowercase for error message end id_accesses_list[k] = cfg.keywords_xlate[access_level]; -- get translated keyword end end end return id_accesses_list; end --[[--------------------------< B U I L D _ I D _ L I S T >---------------------------------------------------- render the identifiers into a sorted sequence table <ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value <options_t> is a table of various k/v option pairs provided in the call to new_build_id_list(); modified by this function and passed to all identifier rendering functions <access_levels_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value (if valid) returns a sequence table of sorted (by hkey - 'handler' key) rendered identifier strings ]] local function build_id_list (ID_list_coins_t, options_t, access_levels_t) local ID_list_t = {}; local accept; local func_map = { --function map points to functions associated with hkey identifier ['ARXIV'] = arxiv, ['ASIN'] = asin, ['BIBCODE'] = bibcode, ['BIORXIV'] = biorxiv, ['CITESEERX'] = citeseerx, ['DOI'] = doi, ['EISSN'] = issn, ['HDL'] = hdl, ['ISBN'] = isbn, ['ISMN'] = ismn, ['ISSN'] = issn, ['JFM'] = jfm, ['JSTOR'] = jstor, ['LCCN'] = lccn, ['MEDRXIV'] = medrxiv, ['MR'] = mr, ['OCLC'] = oclc, ['OL'] = openlibrary, ['OSTI'] = osti, ['PMC'] = pmc, ['PMID'] = pmid, ['RFC'] = rfc, ['S2CID'] = s2cid, ['SBN'] = sbn, ['SSRN'] = ssrn, ['USENETID'] = usenet_id, ['ZBL'] = zbl, } for hkey, v in pairs (ID_list_coins_t) do v, accept = has_accept_as_written (v); -- remove accept-as-written markup if present; accept is boolean true when markup removed; false else -- every function gets the options table with value v and accept boolean options_t.hkey = hkey; -- ~/Configuration handler key options_t.id = v; -- add that identifier value to the options table options_t.accept = accept; -- add the accept boolean flag options_t.access = access_levels_t[hkey]; -- add the access level for those that have an |<identifier-access= parameter options_t.handler = cfg.id_handlers[hkey]; options_t.coins_list_t = ID_list_coins_t; -- pointer to ID_list_coins_t; for |asin= and |ol=; also to keep erroneous values out of the citation's metadata options_t.coins_list_t[hkey] = v; -- id value without accept-as-written markup for metadata if options_t.handler.access and not in_array (options_t.handler.access, cfg.keywords_lists['id-access']) then error (cfg.messages['unknown_ID_access'] .. options_t.handler.access); -- here when handler access key set to a value not listed in list of allowed id access keywords end if func_map[hkey] then local id_text = func_map[hkey] (options_t); -- call the function to get identifier text and any error message table.insert (ID_list_t, {hkey, id_text}); -- add identifier text to the output sequence table else error (cfg.messages['unknown_ID_key'] .. hkey); -- here when func_map doesn't have a function for hkey end end local function comp (a, b) -- used by following table.sort() return a[1]:lower() < b[1]:lower(); -- sort by hkey end table.sort (ID_list_t, comp); -- sequence table of tables sort for k, v in ipairs (ID_list_t) do -- convert sequence table of tables to simple sequence table of strings ID_list_t[k] = v[2]; -- v[2] is the identifier rendering from the call to the various functions in func_map{} end return ID_list_t; end --[[--------------------------< O P T I O N S _ C H E C K >---------------------------------------------------- check that certain option parameters have their associated identifier parameters with values <ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value <ID_support_t> is a sequence table of tables created in citation0() where each subtable has four elements: [1] is the support parameter's assigned value; empty string if not set [2] is a text string same as key in cfg.id_handlers [3] is cfg.error_conditions key used to create error message [4] is original ID support parameter name used to create error message returns nothing; on error emits an appropriate error message ]] local function options_check (ID_list_coins_t, ID_support_t) for _, v in ipairs (ID_support_t) do if is_set (v[1]) and not ID_list_coins_t[v[2]] then -- when support parameter has a value but matching identifier parameter is missing or empty set_message (v[3], (v[4])); -- emit the appropriate error message end end end --[[--------------------------< I D E N T I F I E R _ L I S T S _ G E T >-------------------------------------- Creates two identifier lists: a k/v table of identifiers and their values to be used locally and for use in the COinS metadata, and a sequence table of the rendered identifier strings that will be included in the rendered citation. ]] local function identifier_lists_get (args_t, options_t, ID_support_t) local ID_list_coins_t = extract_ids (args_t); -- get a table of identifiers and their values for use locally and for use in COinS options_check (ID_list_coins_t, ID_support_t); -- ID support parameters must have matching identifier parameters local ID_access_levels_t = extract_id_access_levels (args_t, ID_list_coins_t); -- get a table of identifier access levels local ID_list_t = build_id_list (ID_list_coins_t, options_t, ID_access_levels_t); -- get a sequence table of rendered identifier strings return ID_list_t, ID_list_coins_t; -- return the tables end --[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >-------------------------------------- Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules. ]] local function set_selected_modules (cfg_table_ptr, utilities_page_ptr) cfg = cfg_table_ptr; has_accept_as_written = utilities_page_ptr.has_accept_as_written; -- import functions from select Module:Citation/CS1/Utilities module is_set = utilities_page_ptr.is_set; in_array = utilities_page_ptr.in_array; set_message = utilities_page_ptr.set_message; select_one = utilities_page_ptr.select_one; substitute = utilities_page_ptr.substitute; make_wikilink = utilities_page_ptr.make_wikilink; z = utilities_page_ptr.z; -- table of tables in Module:Citation/CS1/Utilities end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return { auto_link_urls = auto_link_urls, -- table of identifier URLs to be used when auto-linking |title= identifier_lists_get = identifier_lists_get, -- experiment to replace individual calls to build_id_list(), extract_ids, extract_id_access_levels is_embargoed = is_embargoed; set_selected_modules = set_selected_modules; } e4jc9mw0kujge8fok9aztk214jmz0lr 382129 382126 2026-06-05T00:48:59Z MacTire02 219 Undid revision [[Special:Diff/382126|382126]] by [[Special:Contributions/MacTire02|MacTire02]] ([[User talk:MacTire02|talk]]) 382129 Scribunto text/plain --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- ]] local has_accept_as_written, is_set, in_array, set_message, select_one, -- functions in Module:Citation/CS1/Utilities substitute, make_wikilink; local z; -- table of tables defined in Module:Citation/CS1/Utilities local cfg; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration --[[--------------------------< P A G E S C O P E V A R I A B L E S >-------------------------------------- declare variables here that have page-wide scope that are not brought in from other modules; that are created here and used here ]] local auto_link_urls = {}; -- holds identifier URLs for those identifiers that can auto-link |title= --============================<< H E L P E R F U N C T I O N S >>============================================ --[[--------------------------< W I K I D A T A _ A R T I C L E _ N A M E _ G E T >---------------------------- as an aid to internationalizing identifier-label wikilinks, gets identifier article names from Wikidata. returns :<lang code>:<article title> when <q> has an <article title> for <lang code>; nil else for identifiers that do not have q, returns nil for wikis that do not have mw.wikibase installed, returns nil ]] local function wikidata_article_name_get (q) if not is_set (q) or (q and not mw.wikibase) then -- when no q number or when a q number but mw.wikibase not installed on this wiki return nil; -- abandon end local wd_article; local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org wd_article = mw.wikibase.getSitelink (q, this_wiki_code .. 'wiki'); -- fetch article title from WD; nil when no title available at this wiki if wd_article then wd_article = table.concat ({':', this_wiki_code, ':', wd_article}); -- interwiki-style link without brackets if taken from WD; leading colon required end return wd_article; -- article title from WD; nil else end --[[--------------------------< L I N K _ L A B E L _ M A K E >------------------------------------------------ common function to create identifier link label from handler table or from Wikidata returns the first available of 1. redirect from local wiki's handler table (if enabled) 2. Wikidata (if there is a Wikidata entry for this identifier in the local wiki's language) 3. label specified in the local wiki's handler table ]] local function link_label_make (handler) local wd_article; if not (cfg.use_identifier_redirects and is_set (handler.redirect)) then -- redirect has priority so if enabled and available don't fetch from Wikidata because expensive wd_article = wikidata_article_name_get (handler.q); -- if Wikidata has an article title for this wiki, get it; end return (cfg.use_identifier_redirects and is_set (handler.redirect) and handler.redirect) or wd_article or handler.link; end --[[--------------------------< E X T E R N A L _ L I N K _ I D >---------------------------------------------- Formats a wiki-style external link ]] local function external_link_id (options) local url_string = options.id; local ext_link; local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org local wd_article; -- article title from Wikidata if options.encode == true or options.encode == nil then url_string = mw.uri.encode (url_string, 'PATH'); end if options.auto_link and is_set (options.access) then auto_link_urls[options.auto_link] = table.concat ({options.prefix, url_string, options.suffix}); end ext_link = mw.ustring.format ('[%s%s%s %s]', options.prefix, url_string, options.suffix or "", mw.text.nowiki (options.id)); if is_set (options.access) then ext_link = substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[options.access].class, cfg.presentation[options.access].title, ext_link}); -- add the free-to-read / paywall lock end return table.concat ({ make_wikilink (link_label_make (options), options.label), -- redirect, Wikidata link, or locally specified link (in that order) options.separator or '&nbsp;', ext_link }); end --[[--------------------------< I N T E R N A L _ L I N K _ I D >---------------------------------------------- Formats a wiki-style internal link TODO: Does not currently need to support options.access, options.encode, auto-linking and COinS (as in external_link_id), but may be needed in the future for :m:Interwiki_map custom-prefixes like :arxiv:, :bibcode:, :DOI:, :hdl:, :ISSN:, :JSTOR:, :Openlibrary:, :PMID:, :RFC:. ]] local function internal_link_id (options) local id = mw.ustring.gsub (options.id, '%d', cfg.date_names.local_digits); -- translate 'local' digits to Western 0-9 return table.concat ( { make_wikilink (link_label_make (options), options.label), -- wiki-link the identifier label options.separator or '&nbsp;', -- add the separator make_wikilink ( table.concat ( { options.prefix, id, -- translated to Western digits options.suffix or '' }), substitute (cfg.presentation['bdi'], {'', mw.text.nowiki (options.id)}) -- bdi tags to prevent Latin script identifiers from being reversed at RTL language wikis ); -- nowiki because MediaWiki still has magic links for ISBN and the like; TODO: is it really required? }); end --[[--------------------------< I S _ E M B A R G O E D >------------------------------------------------------ Determines if a PMC identifier's online version is embargoed. Compares the date in |pmc-embargo-date= against today's date. If embargo date is in the future, returns the content of |pmc-embargo-date=; otherwise, returns an empty string because the embargo has expired or because |pmc-embargo-date= was not set in this cite. ]] local function is_embargoed (embargo) if is_set (embargo) then local lang = mw.getContentLanguage(); local good1, embargo_date, todays_date; good1, embargo_date = pcall (lang.formatDate, lang, 'U', embargo); todays_date = lang:formatDate ('U'); if good1 then -- if embargo date is a good date if tonumber (embargo_date) >= tonumber (todays_date) then -- is embargo date is in the future? return embargo; -- still embargoed else set_message ('maint_pmc_embargo'); -- embargo has expired; add main cat return ''; -- unset because embargo has expired end end end return ''; -- |pmc-embargo-date= not set return empty string end --[=[-------------------------< I S _ V A L I D _ R X I V _ D A T E >------------------------------------------ for biorxiv, returns true if: 2019-12-11T00:00Z <= biorxiv_date < today + 2 days for medrxiv, returns true if: 2020-01-01T00:00Z <= medrxiv_date < today + 2 days The dated form of biorxiv identifier has a start date of 2019-12-11. The Unix timestamp for that date is {{#time:U|2019-12-11}} = 1576022400 The medrxiv identifier has a start date of 2020-01-01. The Unix timestamp for that date is {{#time:U|2020-01-01}} = 1577836800 <rxiv_date> is the date provided in those |biorxiv= parameter values that are dated and in |medrxiv= parameter values at time 00:00:00 UTC <today> is the current date at time 00:00:00 UTC plus 48 hours if today's date is 2023-01-01T00:00:00 then adding 24 hours gives 2023-01-02T00:00:00 – one second more than today adding 24 hours gives 2023-01-03T00:00:00 – one second more than tomorrow inputs: <y>, <m>, <d> – year, month, day parts of the date from the birxiv or medrxiv identifier <select> 'b' for biorxiv, 'm' for medrxiv; defaults to 'b' ]=] local function is_valid_rxiv_date (y, m, d, select) if 0 == tonumber (m) and 12 < tonumber (m) then -- <m> must be a number 1–12 return false; end if 0 == tonumber (d) and 31 < tonumber (d) then -- <d> must be a number 1–31; TODO: account for month length and leap yer? return false; end local rxiv_date = table.concat ({y, m, d}, '-'); -- make ymd date string local good1, good2; local rxiv_ts, tomorrow_ts; -- to hold Unix timestamps representing the dates local lang_object = mw.getContentLanguage(); good1, rxiv_ts = pcall (lang_object.formatDate, lang_object, 'U', rxiv_date); -- convert rxiv_date value to Unix timestamp good2, tomorrow_ts = pcall (lang_object.formatDate, lang_object, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow if good1 and good2 then -- lang.formatDate() returns a timestamp in the local script which tonumber() may not understand rxiv_ts = tonumber (rxiv_ts) or lang_object:parseFormattedNumber (rxiv_ts); -- convert to numbers for the comparison; tomorrow_ts = tonumber (tomorrow_ts) or lang_object:parseFormattedNumber (tomorrow_ts); else return false; -- one or both failed to convert to Unix timestamp end local limit_ts = ((select and ('m' == select)) and 1577836800) or 1576022400; -- choose the appropriate limit timesatmp return ((limit_ts <= rxiv_ts) and (rxiv_ts < tomorrow_ts)) -- limit_ts <= rxiv_date < tomorrow's date end --[[--------------------------< IS _ V A L I D _ I S X N >----------------------------------------------------- ISBN-10 and ISSN validator code calculates checksum across all ISBN/ISSN digits including the check digit. ISBN-13 is checked in isbn(). If the number is valid the result will be 0. Before calling this function, ISBN/ISSN must be checked for length and stripped of dashes, spaces and other non-ISxN characters. ]] local function is_valid_isxn (isxn_str, len) local temp = 0; isxn_str = { isxn_str:byte(1, len) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39, 'X' → 0x58 len = len + 1; -- adjust to be a loop counter for i, v in ipairs (isxn_str) do -- loop through all of the bytes and calculate the checksum if v == string.byte ("X" ) then -- if checkdigit is X (compares the byte value of 'X' which is 0x58) temp = temp + 10 * (len - i); -- it represents 10 decimal else temp = temp + tonumber (string.char (v) )*(len-i); end end return temp % 11 == 0; -- returns true if calculation result is zero end --[[--------------------------< IS _ V A L I D _ I S X N _ 1 3 >----------------------------------------------- ISBN-13 and ISMN validator code calculates checksum across all 13 ISBN/ISMN digits including the check digit. If the number is valid, the result will be 0. Before calling this function, ISBN-13/ISMN must be checked for length and stripped of dashes, spaces and other non-ISxN-13 characters. ]] local function is_valid_isxn_13 (isxn_str) local temp=0; isxn_str = { isxn_str:byte(1, 13) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39 for i, v in ipairs (isxn_str) do temp = temp + (3 - 2*(i % 2)) * tonumber (string.char (v) ); -- multiply odd index digits by 1, even index digits by 3 and sum; includes check digit end return temp % 10 == 0; -- sum modulo 10 is zero when ISBN-13/ISMN is correct end --[[--------------------------< N O R M A L I Z E _ L C C N >-------------------------------------------------- LCCN normalization (https://www.loc.gov/marc/lccn-namespace.html#normalization) 1. Remove all blanks. 2. If there is a forward slash (/) in the string, remove it, and remove all characters to the right of the forward slash. 3. If there is a hyphen in the string: a. Remove it. b. Inspect the substring following (to the right of) the (removed) hyphen. Then (and assuming that steps 1 and 2 have been carried out): 1. All these characters should be digits, and there should be six or less. (not done in this function) 2. If the length of the substring is less than 6, left-fill the substring with zeroes until the length is six. Returns a normalized LCCN for lccn() to validate. There is no error checking (step 3.b.1) performed in this function. ]] local function normalize_lccn (lccn) lccn = lccn:gsub ("%s", ""); -- 1. strip whitespace if nil ~= string.find (lccn, '/') then lccn = lccn:match ("(.-)/"); -- 2. remove forward slash and all character to the right of it end local prefix local suffix prefix, suffix = lccn:match ("(.+)%-(.+)"); -- 3.a remove hyphen by splitting the string into prefix and suffix if nil ~= suffix then -- if there was a hyphen suffix = string.rep("0", 6-string.len (suffix)) .. suffix; -- 3.b.2 left fill the suffix with 0s if suffix length less than 6 lccn = prefix..suffix; -- reassemble the LCCN end return lccn; end --============================<< I D E N T I F I E R F U N C T I O N S >>==================================== --[[--------------------------< A R X I V >-------------------------------------------------------------------- See: https://arxiv.org/help/arxiv_identifier format and error check arXiv identifier. There are three valid forms of the identifier: the first form, valid only between date codes 9107 and 0703, is: arXiv:<archive>.<class>/<date code><number><version> where: <archive> is a string of alpha characters - may be hyphenated; no other punctuation <class> is a string of alpha characters - may be hyphenated; no other punctuation; not the same as |class= parameter which is not supported in this form <date code> is four digits in the form YYMM where YY is the last two digits of the four-digit year and MM is the month number January = 01 first digit of YY for this form can only 9 and 0 <number> is a three-digit number <version> is a 1 or more digit number preceded with a lowercase v; no spaces (undocumented) the second form, valid from April 2007 through December 2014 is: arXiv:<date code>.<number><version> where: <date code> is four digits in the form YYMM where YY is the last two digits of the four-digit year and MM is the month number January = 01 <number> is a four-digit number <version> is a 1 or more digit number preceded with a lowercase v; no spaces the third form, valid from January 2015 is: arXiv:<date code>.<number><version> where: <date code> and <version> are as defined for 0704-1412 <number> is a five-digit number ]] local function arxiv (options) local id = options.id; local class = options.Class; -- TODO: lowercase? local handler = options.handler; local year, month, version; local err_msg = false; -- assume no error message local text; -- output text if id:match("^%a[%a%.%-]+/[90]%d[01]%d%d%d%d$") or id:match("^%a[%a%.%-]+/[90]%d[01]%d%d%d%dv%d+$") then -- test for the 9107-0703 format with or without version year, month = id:match("^%a[%a%.%-]+/([90]%d)([01]%d)%d%d%d[v%d]*$"); year = tonumber (year); month = tonumber (month); if ((not (90 < year or 8 > year)) or (1 > month or 12 < month)) or -- if invalid year or invalid month ((91 == year and 7 > month) or (7 == year and 3 < month)) then -- if years ok, are starting and ending months ok? err_msg = true; -- flag for error message end elseif id:match("^%d%d[01]%d%.%d%d%d%d$") or id:match("^%d%d[01]%d%.%d%d%d%dv%d+$") then -- test for the 0704-1412 with or without version year, month = id:match("^(%d%d)([01]%d)%.%d%d%d%d[v%d]*$"); year = tonumber (year); month = tonumber (month); if ((7 > year) or (14 < year) or (1 > month or 12 < month)) or -- is year invalid or is month invalid? (doesn't test for future years) ((7 == year) and (4 > month)) then -- when year is 07, is month invalid (before April)? err_msg = true; -- flag for error message end elseif id:match("^%d%d[01]%d%.%d%d%d%d%d$") or id:match("^%d%d[01]%d%.%d%d%d%d%dv%d+$") then -- test for the 1501- format with or without version year, month = id:match("^(%d%d)([01]%d)%.%d%d%d%d%d[v%d]*$"); year = tonumber (year); month = tonumber (month); if ((15 > year) or (1 > month or 12 < month)) then -- is year invalid or is month invalid? (doesn't test for future years) err_msg = true; -- flag for error message end else err_msg = true; -- not a recognized format; flag for error message end if err_msg then options.coins_list_t['ARXIV'] = nil; -- when error, unset so not included in COinS end local err_msg_t = {}; if err_msg then set_message ('err_bad_arxiv'); end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); if is_set (class) then if id:match ('^%d+') then text = table.concat ({text, ' [[https://arxiv.org/archive/', class, ' ', class, ']]'}); -- external link within square brackets, not wikilink else set_message ('err_class_ignored'); end end return text; end --[[--------------------------< B I B C O D E >-------------------------------------------------------------------- Validates (sort of) and formats a bibcode ID. Format for bibcodes is specified here: https://adsabs.harvard.edu/abs_doc/help_pages/data.html#bibcodes But, this: 2015arXiv151206696F is apparently valid so apparently, the only things that really matter are length, 19 characters and first four digits must be a year. This function makes these tests: length must be 19 characters characters in position 1–4 must be digits and must represent a year in the range of 1000 – next year 5 must be a letter 6–8 must be letter, digit, ampersand, or dot (ampersand cannot directly precede a dot; &. ) 9–18 must be letter, digit, or dot 19 must be a letter or dot ]] local function bibcode (options) local id = options.id; local access = options.access; local handler = options.handler; local ignore_invalid = options.accept; local err_type; local err_msg = ''; local year; local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access}); if 19 ~= id:len() then err_type = cfg.err_msg_supl.length; else year = id:match ("^(%d%d%d%d)[%a][%w&%.][%w&%.][%w&%.][%w.]+[%a%.]$"); if not year then -- if nil then no pattern match err_type = cfg.err_msg_supl.value; -- so value error else local next_year = tonumber (os.date ('%Y')) + 1; -- get the current year as a number and add one for next year year = tonumber (year); -- convert year portion of bibcode to a number if (1000 > year) or (year > next_year) then err_type = cfg.err_msg_supl.year; -- year out of bounds end if id:find('&%.') then err_type = cfg.err_msg_supl.journal; -- journal abbreviation must not have '&.' (if it does it's missing a letter) end if id:match ('.........%.tmp%.') then -- temporary bibcodes when positions 10–14 are '.tmp.' set_message ('maint_bibcode'); end end end if is_set (err_type) and not ignore_invalid then -- if there was an error detected and accept-as-written markup not used set_message ('err_bad_bibcode', {err_type}); options.coins_list_t['BIBCODE'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< B I O R X I V >----------------------------------------------------------------- Format bioRxiv ID and do simple error checking. Before 2019-12-11, biorXiv IDs were 10.1101/ followed by exactly 6 digits. After 2019-12-11, biorXiv IDs retained the six-digit identifier but prefixed that with a yyyy.mm.dd. date and suffixed with an optional version identifier. The bioRxiv ID is the string of characters: https://doi.org/10.1101/078733 -> 10.1101/078733 or a date followed by a six-digit number followed by an optional version indicator 'v' and one or more digits: https://www.biorxiv.org/content/10.1101/2019.12.11.123456v2 -> 10.1101/2019.12.11.123456v2 see https://www.biorxiv.org/about-biorxiv ]] local function biorxiv (options) local id = options.id; local handler = options.handler; local err_msg = true; -- flag; assume that there will be an error local patterns = { '^10%.1101/%d%d%d%d%d%d$', -- simple 6-digit identifier (before 2019-12-11) '^10%.1101/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%dv%d+$', -- y.m.d. date + 6-digit identifier + version (after 2019-12-11) '^10%.1101/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%d$', -- y.m.d. date + 6-digit identifier (after 2019-12-11) } for _, pattern in ipairs (patterns) do -- spin through the patterns looking for a match if id:match (pattern) then local y, m, d = id:match (pattern); -- found a match, attempt to get year, month and date from the identifier if m then -- m is nil when id is the six-digit form if not is_valid_rxiv_date (y, m, d, 'b') then -- validate the encoded date; 'b' for biorxiv limit break; -- date fail; break out early so we don't unset the error message end end err_msg = nil; -- we found a match so unset the error message break; -- and done end end -- err_cat remains set here when no match if err_msg then options.coins_list_t['BIORXIV'] = nil; -- when error, unset so not included in COinS set_message ('err_bad_biorxiv'); -- and set the error message end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); end --[[--------------------------< C I T E S E E R X >------------------------------------------------------------ CiteSeerX use their own notion of "doi" (not to be confused with the identifiers resolved via doi.org). The description of the structure of this identifier can be found at Help_talk:Citation_Style_1/Archive_26#CiteSeerX_id_structure ]] local function citeseerx (options) local id = options.id; local handler = options.handler; local matched; local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); matched = id:match ("^10%.1%.1%.[1-9]%d?%d?%d?%.[1-9]%d?%d?%d?$"); if not matched then set_message ('err_bad_citeseerx' ); options.coins_list_t['CITESEERX'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< D O I >------------------------------------------------------------------------ Formats a DOI and checks for DOI errors. DOI names contain two parts: prefix and suffix separated by a forward slash. Prefix: directory indicator '10.' followed by a registrant code Suffix: character string of any length chosen by the registrant This function checks a DOI name for: prefix/suffix. If the DOI name contains spaces or endashes, or, if it ends with a period or a comma, this function will emit a bad_doi error message. DOI names are case-insensitive and can incorporate any printable Unicode characters so the test for spaces, endash, and terminal punctuation may not be technically correct but it appears, that in practice these characters are rarely if ever used in DOI names. https://www.doi.org/doi_handbook/2_Numbering.html -- 2.2 Syntax of a DOI name https://www.doi.org/doi_handbook/2_Numbering.html#2.2.2 -- 2.2.2 DOI prefix ]] local function doi (options) local id = options.id; local inactive = options.DoiBroken local access = options.access; local ignore_invalid = options.accept; local handler = options.handler; local err_flag; local text; if is_set (inactive) then local inactive_year = inactive:match("%d%d%d%d"); -- try to get the year portion from the inactive date local inactive_month, good; if is_set (inactive_year) then if 4 < inactive:len() then -- inactive date has more than just a year (could be anything) local lang_obj = mw.getContentLanguage(); -- get a language object for this wiki good, inactive_month = pcall (lang_obj.formatDate, lang_obj, 'F', inactive); -- try to get the month name from the inactive date if not good then inactive_month = nil; -- something went wrong so make sure this is unset end end end -- otherwise, |doi-broken-date= has something but it isn't a date if is_set (inactive_year) and is_set (inactive_month) then set_message ('maint_doi_inactive_dated', {inactive_year, inactive_month, ' '}); elseif is_set (inactive_year) then set_message ('maint_doi_inactive_dated', {inactive_year, '', ''}); else set_message ('maint_doi_inactive'); end inactive = " (" .. cfg.messages['inactive'] .. ' ' .. inactive .. ')'; end local registrant = mw.ustring.match (id, '^10%.([^/]+)/[^%s–]-[^%.,]$'); -- registrant set when DOI has the proper basic form local registrant_err_patterns = { -- these patterns are for code ranges that are not supported '^[^1-3]%d%d%d%d%.%d+$', -- 5 digits with subcode (0xxxx, 40000+); accepts: 10000–39999 '^[^1-6]%d%d%d%d$', -- 5 digits without subcode (0xxxx, 60000+); accepts: 10000–69999 '^[^1-9]%d%d%d%.%d+$', -- 4 digits with subcode (0xxx); accepts: 1000–9999 '^[^1-9]%d%d%d$', -- 4 digits without subcode (0xxx); accepts: 1000–9999 '^%d%d%d%d%d%d+', -- 6 or more digits '^%d%d?%d?$', -- less than 4 digits without subcode (3 digits with subcode is legitimate) '^%d%d?%.[%d%.]+', -- 1 or 2 digits with subcode '^5555$', -- test registrant will never resolve '[^%d%.]', -- any character that isn't a digit or a dot } if not ignore_invalid then if registrant then -- when DOI has proper form for i, pattern in ipairs (registrant_err_patterns) do -- spin through error patterns if registrant:match (pattern) then -- to validate registrant codes err_flag = set_message ('err_bad_doi'); -- when found, mark this DOI as bad break; -- and done end end else err_flag = set_message ('err_bad_doi'); -- invalid directory or malformed end else set_message ('maint_doi_ignore'); end if err_flag then options.coins_list_t['DOI'] = nil; -- when error, unset so not included in COinS else if not access and cfg.known_free_doi_registrants_t[registrant] then -- |doi-access=free not set and <registrant> is known to be free set_message ('maint_doi_unflagged_free'); -- set a maint cat end end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access, auto_link = not (err_flag or is_set (inactive) or ignore_invalid) and 'doi' or nil -- do not auto-link when |doi-broken-date= has a value or when there is a DOI error or (to play it safe, after all, auto-linking is not essential) when invalid DOIs are ignored }) .. (inactive or ''); return text; end --[[--------------------------< H D L >------------------------------------------------------------------------ Formats an HDL with minor error checking. HDL names contain two parts: prefix and suffix separated by a forward slash. Prefix: character string using any character in the UCS-2 character set except '/' Suffix: character string of any length using any character in the UCS-2 character set chosen by the registrant This function checks a HDL name for: prefix/suffix. If the HDL name contains spaces, endashes, or, if it ends with a period or a comma, this function will emit a bad_hdl error message. HDL names are case-insensitive and can incorporate any printable Unicode characters so the test for endashes and terminal punctuation may not be technically correct but it appears, that in practice these characters are rarely if ever used in HDLs. Query string parameters are named here: https://www.handle.net/proxy_servlet.html. query strings are not displayed but since '?' is an allowed character in an HDL, '?' followed by one of the query parameters is the only way we have to detect the query string so that it isn't URL-encoded with the rest of the identifier. ]] local function hdl (options) local id = options.id; local access = options.access; local handler = options.handler; local query_params = { -- list of known query parameters from https://www.handle.net/proxy_servlet.html 'noredirect', 'ignore_aliases', 'auth', 'cert', 'index', 'type', 'urlappend', 'locatt', 'action', } local hdl, suffix, param = id:match ('(.-)(%?(%a+).+)$'); -- look for query string local found; if hdl then -- when there are query strings, this is the handle identifier portion for _, q in ipairs (query_params) do -- spin through the list of query parameters if param:match ('^' .. q) then -- if the query string begins with one of the parameters found = true; -- announce a find break; -- and stop looking end end end if found then id = hdl; -- found so replace id with the handle portion; this will be URL-encoded, suffix will not else suffix = ''; -- make sure suffix is empty string for concatenation else end local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, suffix = suffix, separator = handler.separator, encode = handler.encode, access = access}) if nil == id:match("^[^%s–]-/[^%s–]-[^%.,]$") then -- HDL must contain a forward slash, must not contain spaces, endashes, and must not end with period or comma set_message ('err_bad_hdl' ); options.coins_list_t['HDL'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< I S B N >---------------------------------------------------------------------- Determines whether an ISBN string is valid ]] local function isbn (options) local isbn_str = options.id; local ignore_invalid = options.accept; local handler = options.handler; local function return_result (check, err_type) -- local function to handle the various returns local ISBN = internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect, prefix = handler.prefix, id = isbn_str, separator = handler.separator}); if ignore_invalid then -- if ignoring ISBN errors set_message ('maint_isbn_ignore'); -- add a maint category even when there is no error else -- here when not ignoring if not check then -- and there is an error options.coins_list_t['ISBN'] = nil; -- when error, unset so not included in COinS set_message ('err_bad_isbn', err_type); -- set an error message return ISBN; -- return id text end end return ISBN; -- return id text end if nil ~= isbn_str:match ('[^%s-0-9X]') then return return_result (false, cfg.err_msg_supl.char); -- fail if isbn_str contains anything but digits, hyphens, or the uppercase X end local id = isbn_str:gsub ('[%s-]', ''); -- remove hyphens and whitespace local len = id:len(); if len ~= 10 and len ~= 13 then return return_result (false, cfg.err_msg_supl.length); -- fail if incorrect length end if len == 10 then if id:match ('^%d*X?$') == nil then -- fail if isbn_str has 'X' anywhere but last position return return_result (false, cfg.err_msg_supl.form); end if not is_valid_isxn (id, 10) then -- test isbn-10 for numerical validity return return_result (false, cfg.err_msg_supl.check); -- fail if isbn-10 is not numerically valid end if id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not valid isbn group ids but are used by amazon as numeric identifiers (asin) return return_result (false, cfg.err_msg_supl.group); -- fail if isbn-10 begins with 630/1 end return return_result (true, cfg.err_msg_supl.check); -- pass if isbn-10 is numerically valid else if id:match ('^%d+$') == nil then return return_result (false, cfg.err_msg_supl.char); -- fail if ISBN-13 is not all digits end if id:match ('^97[89]%d*$') == nil then return return_result (false, cfg.err_msg_supl.prefix); -- fail when ISBN-13 does not begin with 978 or 979 end if id:match ('^9790') then return return_result (false, cfg.err_msg_supl.group); -- group identifier '0' is reserved to ISMN end return return_result (is_valid_isxn_13 (id), cfg.err_msg_supl.check); end end --[[--------------------------< A S I N >---------------------------------------------------------------------- Formats a link to Amazon. Do simple error checking: ASIN must be mix of 10 numeric or uppercase alpha characters. If a mix, first character must be uppercase alpha; if all numeric, ASINs must be 10-digit ISBN. If 10-digit ISBN, add a maintenance category so a bot or AWB script can replace |asin= with |isbn=. Error message if not 10 characters, if not ISBN-10, if mixed and first character is a digit. |asin=630....... and |asin=631....... are (apparently) not a legitimate ISBN though it checksums as one; these do not cause this function to emit the maint_asin message This function is positioned here because it calls isbn() ]] local function asin (options) local id = options.id; local domain = options.ASINTLD; local err_flag; if not id:match("^[%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u]$") then err_flag = set_message ('err_bad_asin'); -- ASIN is not a mix of 10 uppercase alpha and numeric characters else if id:match("^%d%d%d%d%d%d%d%d%d[%dX]$") then -- if 10-digit numeric (or 9 digits with terminal X) if is_valid_isxn (id, 10) then -- see if ASIN value is or validates as ISBN-10 if not id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not a valid isbn prefixes but are used by amazon as a numeric identifier err_flag = set_message ('err_bad_asin'); -- ASIN has ISBN-10 form but begins with something other than 630/1 so probably an isbn end elseif not is_set (err_flag) then err_flag = set_message ('err_bad_asin'); -- ASIN is not ISBN-10 end elseif not id:match("^%u[%d%u]+$") then err_flag = set_message ('err_bad_asin'); -- asin doesn't begin with uppercase alpha end end if (not is_set (domain)) or in_array (domain, {'us'}) then -- default: United States domain = "com"; elseif in_array (domain, {'jp', 'uk'}) then -- Japan, United Kingdom domain = "co." .. domain; elseif in_array (domain, {'z.cn'}) then -- China domain = "cn"; elseif in_array (domain, {'au', 'br', 'mx', 'sg', 'tr'}) then -- Australia, Brazil, Mexico, Singapore, Turkey domain = "com." .. domain; elseif not in_array (domain, {'ae', 'ca', 'cn', 'de', 'es', 'fr', 'in', 'it', 'nl', 'pl', 'sa', 'se', 'co.jp', 'co.uk', 'com', 'com.au', 'com.br', 'com.mx', 'com.sg', 'com.tr'}) then -- Arabic Emirates, Canada, China, Germany, Spain, France, Indonesia, Italy, Netherlands, Poland, Saudi Arabia, Sweden (as of 2021-03 Austria (.at), Liechtenstein (.li) and Switzerland (.ch) still redirect to the German site (.de) with special settings, so don't maintain local ASINs for them) err_flag = set_message ('err_bad_asin_tld'); -- unsupported asin-tld value end local handler = options.handler; if not is_set (err_flag) then options.coins_list_t['ASIN'] = handler.prefix .. domain .. "/dp/" .. id; -- asin for coins else options.coins_list_t['ASIN'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix .. domain .. "/dp/", id = id, encode = handler.encode, separator = handler.separator}) end --[[--------------------------< I S M N >---------------------------------------------------------------------- Determines whether an ISMN string is valid. Similar to ISBN-13, ISMN is 13 digits beginning 979-0-... and uses the same check digit calculations. See https://www.ismn-international.org/download/Web_ISMN_Users_Manual_2008-6.pdf section 2, pages 9–12. ismn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx) or an identifier registered at info-uri.info (info:) ]] local function ismn (options) local id = options.id; local handler = options.handler; local text; local valid_ismn = true; local id_copy; id_copy = id; -- save a copy because this testing is destructive id = id:gsub ('[%s-]', ''); -- remove hyphens and white space if 13 ~= id:len() or id:match ("^9790%d*$" ) == nil then -- ISMN must be 13 digits and begin with 9790 valid_ismn = false; else valid_ismn=is_valid_isxn_13 (id); -- validate ISMN end -- text = internal_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, -- use this (or external version) when there is some place to link to -- prefix = handler.prefix, id = id_copy, separator = handler.separator, encode = handler.encode}) text = table.concat ( -- because no place to link to yet { make_wikilink (link_label_make (handler), handler.label), handler.separator, id_copy }); if false == valid_ismn then options.coins_list_t['ISMN'] = nil; -- when error, unset so not included in COinS; not really necessary here because ismn not made part of COinS set_message ('err_bad_ismn'); -- create an error message if the ISMN is invalid end return text; end --[[--------------------------< I S S N >---------------------------------------------------------------------- Validate and format an ISSN. This code fixes the case where an editor has included an ISSN in the citation but has separated the two groups of four digits with a space. When that condition occurred, the resulting link looked like this: |issn=0819 4327 gives: [https://www.worldcat.org/issn/0819 4327 0819 4327] -- can't have spaces in an external link This code now prevents that by inserting a hyphen at the ISSN midpoint. It also validates the ISSN for length and makes sure that the checkdigit agrees with the calculated value. Incorrect length (8 digits), characters other than 0-9 and X, or checkdigit / calculated value mismatch will all cause a check ISSN error message. The ISSN is always displayed with a hyphen, even if the ISSN was given as a single group of 8 digits. ]] local function issn (options) local id = options.id; local handler = options.handler; local ignore_invalid = options.accept; local issn_copy = id; -- save a copy of unadulterated ISSN; use this version for display if ISSN does not validate local text; local valid_issn = true; id = id:gsub ('[%s-]', ''); -- remove hyphens and whitespace if 8 ~= id:len() or nil == id:match ("^%d*X?$" ) then -- validate the ISSN: 8 digits long, containing only 0-9 or X in the last position valid_issn = false; -- wrong length or improper character else valid_issn = is_valid_isxn (id, 8); -- validate ISSN end if true == valid_issn then id = string.sub (id, 1, 4 ) .. "-" .. string.sub (id, 5 ); -- if valid, display correctly formatted version else id = issn_copy; -- if not valid, show the invalid ISSN with error message end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}) if ignore_invalid then set_message ('maint_issn_ignore'); else if false == valid_issn then options.coins_list_t['ISSN'] = nil; -- when error, unset so not included in COinS set_message ('err_bad_issn', (options.hkey == 'EISSN') and 'e' or ''); -- create an error message if the ISSN is invalid end end return text; end --[[--------------------------< J F M >----------------------------------------------------------------------- A numerical identifier in the form nn.nnnn.nn ]] local function jfm (options) local id = options.id; local handler = options.handler; local id_num; id_num = id:match ('^[Jj][Ff][Mm](.*)$'); -- identifier with jfm prefix; extract identifier if is_set (id_num) then set_message ('maint_jfm_format'); else -- plain number without JFM prefix id_num = id; -- if here id does not have prefix end if id_num and id_num:match('^%d%d%.%d%d%d%d%.%d%d$') then id = id_num; -- jfm matches pattern else set_message ('err_bad_jfm' ); -- set an error message options.coins_list_t['JFM'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< J S T O R >-------------------------------------------------------------------- Format a JSTOR with some error checking ]] local function jstor (options) local id = options.id; local access = options.access; local handler = options.handler; if id:find ('[Jj][Ss][Tt][Oo][Rr]') or id:find ('^https?://') or id:find ('%s') then set_message ('err_bad_jstor'); -- set an error message options.coins_list_t['JSTOR'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access}); end --[[--------------------------< L C C N >---------------------------------------------------------------------- Format LCCN link and do simple error checking. LCCN is a character string 8-12 characters long. The length of the LCCN dictates the character type of the first 1-3 characters; the rightmost eight are always digits. https://oclc-research.github.io/infoURI-Frozen/info-uri.info/info:lccn/reg.html length = 8 then all digits length = 9 then lccn[1] is lowercase alpha length = 10 then lccn[1] and lccn[2] are both lowercase alpha or both digits length = 11 then lccn[1] is lower case alpha, lccn[2] and lccn[3] are both lowercase alpha or both digits length = 12 then lccn[1] and lccn[2] are both lowercase alpha ]] local function lccn (options) local lccn = options.id; local handler = options.handler; local err_flag; -- presume that LCCN is valid local id = lccn; -- local copy of the LCCN id = normalize_lccn (id); -- get canonical form (no whitespace, hyphens, forward slashes) local len = id:len(); -- get the length of the LCCN if 8 == len then if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits) err_flag = set_message ('err_bad_lccn'); -- set an error message end elseif 9 == len then -- LCCN should be adddddddd if nil == id:match("%l%d%d%d%d%d%d%d%d") then -- does it match our pattern? err_flag = set_message ('err_bad_lccn'); -- set an error message end elseif 10 == len then -- LCCN should be aadddddddd or dddddddddd if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits) ... if nil == id:match("^%l%l%d%d%d%d%d%d%d%d") then -- ... see if it matches our pattern err_flag = set_message ('err_bad_lccn'); -- no match, set an error message end end elseif 11 == len then -- LCCN should be aaadddddddd or adddddddddd if not (id:match("^%l%l%l%d%d%d%d%d%d%d%d") or id:match("^%l%d%d%d%d%d%d%d%d%d%d")) then -- see if it matches one of our patterns err_flag = set_message ('err_bad_lccn'); -- no match, set an error message end elseif 12 == len then -- LCCN should be aadddddddddd if not id:match("^%l%l%d%d%d%d%d%d%d%d%d%d") then -- see if it matches our pattern err_flag = set_message ('err_bad_lccn'); -- no match, set an error message end else err_flag = set_message ('err_bad_lccn'); -- wrong length, set an error message end if not is_set (err_flag) and nil ~= lccn:find ('%s') then err_flag = set_message ('err_bad_lccn'); -- lccn contains a space, set an error message end if is_set (err_flag) then options.coins_list_t['LCCN'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = lccn, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< M E D R X I V >----------------------------------------------------------------- Format medRxiv ID and do simple error checking. Similar to later bioRxiv IDs, medRxiv IDs are prefixed with a yyyy.mm.dd. date and suffixed with an optional version identifier. Ealiest date accepted is 2020.01.01 The medRxiv ID is a date followed by an eight-digit number followed by an optional version indicator 'v' and one or more digits: https://www.medrxiv.org/content/10.1101/2020.11.16.20232009v2 -> 10.1101/2020.11.16.20232009v2 ]] local function medrxiv (options) local id = options.id; local handler = options.handler; local err_msg_flag = true; -- flag; assume that there will be an error local patterns = { '%d%d%d%d%d%d%d%d$', -- simple 8-digit identifier; these should be relatively rare '^10%.1101/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%d%d%dv%d+$', -- y.m.d. date + 8-digit identifier + version (2020-01-01 and later) '^10%.1101/(20%d%d)%.(%d%d)%.(%d%d)%.%d%d%d%d%d%d%d%d$', -- y.m.d. date + 8-digit identifier (2020-01-01 and later) } for _, pattern in ipairs (patterns) do -- spin through the patterns looking for a match if id:match (pattern) then local y, m, d = id:match (pattern); -- found a match, attempt to get year, month and date from the identifier if m then -- m is nil when id is the 8-digit form if not is_valid_rxiv_date (y, m, d, 'b') then -- validate the encoded date; 'b' for medrxiv limit break; -- date fail; break out early so we don't unset the error message end end err_msg_flag = nil; -- we found a match so unset the error message break; -- and done end end -- <err_msg_flag> remains set here when no match if err_msg_flag then options.coins_list_t['MEDRXIV'] = nil; -- when error, unset so not included in COinS set_message ('err_bad_medrxiv'); -- and set the error message end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); end --[[--------------------------< M R >-------------------------------------------------------------------------- A seven digit number; if not seven digits, zero-fill leading digits to make seven digits. ]] local function mr (options) local id = options.id; local handler = options.handler; local id_num; local id_len; id_num = id:match ('^[Mm][Rr](%d+)$'); -- identifier with mr prefix if is_set (id_num) then set_message ('maint_mr_format'); -- add maint cat else -- plain number without mr prefix id_num = id:match ('^%d+$'); -- if here id is all digits end id_len = id_num and id_num:len() or 0; if (7 >= id_len) and (0 ~= id_len) then id = string.rep ('0', 7-id_len) .. id_num; -- zero-fill leading digits else set_message ('err_bad_mr'); -- set an error message options.coins_list_t['MR'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< O C L C >---------------------------------------------------------------------- Validate and format an OCLC ID. https://www.oclc.org/batchload/controlnumber.en.html {{dead link}} archived at: https://web.archive.org/web/20161228233804/https://www.oclc.org/batchload/controlnumber.en.html ]] local function oclc (options) local id = options.id; local handler = options.handler; local number; if id:match('^ocm%d%d%d%d%d%d%d%d$') then -- ocm prefix and 8 digits; 001 field (12 characters) number = id:match('ocm(%d+)'); -- get the number elseif id:match('^ocn%d%d%d%d%d%d%d%d%d$') then -- ocn prefix and 9 digits; 001 field (12 characters) number = id:match('ocn(%d+)'); -- get the number elseif id:match('^on%d%d%d%d%d%d%d%d%d%d+$') then -- on prefix and 10 or more digits; 001 field (12 characters) number = id:match('^on(%d%d%d%d%d%d%d%d%d%d+)$'); -- get the number elseif id:match('^%(OCoLC%)[1-9]%d*$') then -- (OCoLC) prefix and variable number digits; no leading zeros; 035 field number = id:match('%(OCoLC%)([1-9]%d*)'); -- get the number if 9 < number:len() then number = nil; -- constrain to 1 to 9 digits; change this when OCLC issues 10-digit numbers end elseif id:match('^%d+$') then -- no prefix number = id; -- get the number if tonumber (id) > handler.id_limit then number = nil; -- unset when id value exceeds the limit end end if number then -- proper format id = number; -- exclude prefix, if any, from external link else set_message ('err_bad_oclc') -- add an error message if the id is malformed options.coins_list_t['OCLC'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< O P E N L I B R A R Y >-------------------------------------------------------- Formats an OpenLibrary link, and checks for associated errors. ]] local function openlibrary (options) local id = options.id; local access = options.access; local handler = options.handler; local ident, code = id:gsub('^OL', ''):match("^(%d+([AMW]))$"); -- strip optional OL prefix followed immediately by digits followed by 'A', 'M', or 'W'; local err_flag; local prefix = { -- these are appended to the handler.prefix according to code ['A']='authors/OL', ['M']='books/OL', ['W']='works/OL', ['X']='OL' -- not a code; spoof when 'code' in id is invalid }; if not ident then code = 'X'; -- no code or id completely invalid ident = id; -- copy id to ident so that we display the flawed identifier err_flag = set_message ('err_bad_ol'); end if not is_set (err_flag) then options.coins_list_t['OL'] = handler.prefix .. prefix[code] .. ident; -- experiment for ol coins else options.coins_list_t['OL'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix .. prefix[code], id = ident, separator = handler.separator, encode = handler.encode, access = access}); end --[[--------------------------< O S T I >---------------------------------------------------------------------- Format OSTI and do simple error checking. OSTIs are sequential numbers beginning at 1 and counting up. This code checks the OSTI to see that it contains only digits and is less than test_limit specified in the configuration; the value in test_limit will need to be updated periodically as more OSTIs are issued. NB. 1018 is the lowest OSTI number found in the wild (so far) and resolving OK on the OSTI site ]] local function osti (options) local id = options.id; local access = options.access; local handler = options.handler; if id:match("[^%d]") then -- if OSTI has anything but digits set_message ('err_bad_osti'); -- set an error message options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS else -- OSTI is only digits local id_num = tonumber (id); -- convert id to a number for range testing if 1018 > id_num or handler.id_limit < id_num then -- if OSTI is outside test limit boundaries set_message ('err_bad_osti'); -- set an error message options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS end end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access}); end --[[--------------------------< P M C >------------------------------------------------------------------------ Format a PMC, do simple error checking, and check for embargoed articles. The embargo parameter takes a date for a value. If the embargo date is in the future the PMC identifier will not be linked to the article. If the embargo date is today or in the past, or if it is empty or omitted, then the PMC identifier is linked to the article through the link at cfg.id_handlers['PMC'].prefix. PMC embargo date testing is done in function is_embargoed () which is called earlier because when the citation has |pmc=<value> but does not have a |url= then |title= is linked with the PMC link. Function is_embargoed () returns the embargo date if the PMC article is still embargoed, otherwise it returns an empty string. PMCs are sequential numbers beginning at 1 and counting up. This code checks the PMC to see that it contains only digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically as more PMCs are issued. ]] local function pmc (options) local id = options.id; local embargo = options.Embargo; -- TODO: lowercase? local handler = options.handler; local err_flag; local id_num; local text; id_num = id:match ('^[Pp][Mm][Cc](%d+)$'); -- identifier with PMC prefix if is_set (id_num) then set_message ('maint_pmc_format'); else -- plain number without PMC prefix id_num = id:match ('^%d+$'); -- if here id is all digits end if is_set (id_num) then -- id_num has a value so test it id_num = tonumber (id_num); -- convert id_num to a number for range testing if 1 > id_num or handler.id_limit < id_num then -- if PMC is outside test limit boundaries err_flag = set_message ('err_bad_pmc'); -- set an error message else id = tostring (id_num); -- make sure id is a string end else -- when id format incorrect err_flag = set_message ('err_bad_pmc'); -- set an error message end if is_set (embargo) and is_set (is_embargoed (embargo)) then -- is PMC is still embargoed? text = table.concat ( -- still embargoed so no external link { make_wikilink (link_label_make (handler), handler.label), handler.separator, id, }); else text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, -- no embargo date or embargo has expired, ok to link to article prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access, auto_link = not err_flag and 'pmc' or nil -- do not auto-link when PMC has error }); end if err_flag then options.coins_list_t['PMC'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< P M I D >---------------------------------------------------------------------- Format PMID and do simple error checking. PMIDs are sequential numbers beginning at 1 and counting up. This code checks the PMID to see that it contains only digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically as more PMIDs are issued. ]] local function pmid (options) local id = options.id; local handler = options.handler; if id:match("[^%d]") then -- if PMID has anything but digits set_message ('err_bad_pmid'); -- set an error message options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS else -- PMID is only digits local id_num = tonumber (id); -- convert id to a number for range testing if 1 > id_num or handler.id_limit < id_num then -- if PMID is outside test limit boundaries set_message ('err_bad_pmid'); -- set an error message options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS end end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --[[--------------------------< R F C >------------------------------------------------------------------------ Format RFC and do simple error checking. RFCs are sequential numbers beginning at 1 and counting up. This code checks the RFC to see that it contains only digits and is less than test_limit specified in the configuration; the value in test_limit will need to be updated periodically as more RFCs are issued. An index of all RFCs is here: https://tools.ietf.org/rfc/ ]] local function rfc (options) local id = options.id; local handler = options.handler; if id:match("[^%d]") then -- if RFC has anything but digits set_message ('err_bad_rfc'); -- set an error message options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS else -- RFC is only digits local id_num = tonumber (id); -- convert id to a number for range testing if 1 > id_num or handler.id_limit < id_num then -- if RFC is outside test limit boundaries set_message ('err_bad_rfc'); -- set an error message options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS end end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access}); end --[[--------------------------< S 2 C I D >-------------------------------------------------------------------- Format an S2CID, do simple error checking S2CIDs are sequential numbers beginning at 1 and counting up. This code checks the S2CID to see that it is only digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically as more S2CIDs are issued. ]] local function s2cid (options) local id = options.id; local access = options.access; local handler = options.handler; local id_num; local text; id_num = id:match ('^[1-9]%d*$'); -- id must be all digits; must not begin with 0; no open access flag if is_set (id_num) then -- id_num has a value so test it id_num = tonumber (id_num); -- convert id_num to a number for range testing if handler.id_limit < id_num then -- if S2CID is outside test limit boundaries set_message ('err_bad_s2cid'); -- set an error message options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS end else -- when id format incorrect set_message ('err_bad_s2cid'); -- set an error message options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access}); return text; end --[[--------------------------< S B N >------------------------------------------------------------------------ 9-digit form of ISBN-10; uses same check-digit validation when SBN is prefixed with an additional '0' to make 10 digits sbn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx) or an identifier registered at info-uri.info (info:) ]] local function sbn (options) local id = options.id; local ignore_invalid = options.accept; local handler = options.handler; local function return_result (check, err_type) -- local function to handle the various returns local SBN = internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator}); if not ignore_invalid then -- if not ignoring SBN errors if not check then options.coins_list_t['SBN'] = nil; -- when error, unset so not included in COinS; not really necessary here because sbn not made part of COinS set_message ('err_bad_sbn', {err_type}); -- display an error message return SBN; end else set_message ('maint_isbn_ignore'); -- add a maint category even when there is no error (ToDo: Possibly switch to separate message for SBNs only) end return SBN; end if id:match ('[^%s-0-9X]') then return return_result (false, cfg.err_msg_supl.char); -- fail if SBN contains anything but digits, hyphens, or the uppercase X end local ident = id:gsub ('[%s-]', ''); -- remove hyphens and whitespace; they interfere with the rest of the tests if 9 ~= ident:len() then return return_result (false, cfg.err_msg_supl.length); -- fail if incorrect length end if ident:match ('^%d*X?$') == nil then return return_result (false, cfg.err_msg_supl.form); -- fail if SBN has 'X' anywhere but last position end return return_result (is_valid_isxn ('0' .. ident, 10), cfg.err_msg_supl.check); end --[[--------------------------< S S R N >---------------------------------------------------------------------- Format an SSRN, do simple error checking SSRNs are sequential numbers beginning at 100? and counting up. This code checks the SSRN to see that it is only digits and is greater than 99 and less than test_limit; the value in local variable test_limit will need to be updated periodically as more SSRNs are issued. ]] local function ssrn (options) local id = options.id; local handler = options.handler; local id_num; local text; id_num = id:match ('^%d+$'); -- id must be all digits if is_set (id_num) then -- id_num has a value so test it id_num = tonumber (id_num); -- convert id_num to a number for range testing if 100 > id_num or handler.id_limit < id_num then -- if SSRN is outside test limit boundaries set_message ('err_bad_ssrn'); -- set an error message options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS end else -- when id format incorrect set_message ('err_bad_ssrn'); -- set an error message options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS end text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = options.access}); return text; end --[[--------------------------< U S E N E T _ I D >------------------------------------------------------------ Validate and format a usenet message id. Simple error checking, looks for 'id-left@id-right' not enclosed in '<' and/or '>' angle brackets. ]] local function usenet_id (options) local id = options.id; local handler = options.handler; local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}) if not id:match('^.+@.+$') or not id:match('^[^<].*[^>]$') then -- doesn't have '@' or has one or first or last character is '< or '>' set_message ('err_bad_usenet_id') -- add an error message if the message id is invalid options.coins_list_t['USENETID'] = nil; -- when error, unset so not included in COinS end return text; end --[[--------------------------< Z B L >----------------------------------------------------------------------- A numerical identifier in the form nnnn.nnnnn - leading zeros in the first quartet optional format described here: http://emis.mi.sanu.ac.rs/ZMATH/zmath/en/help/search/ temporary format is apparently eight digits. Anything else is an error ]] local function zbl (options) local id = options.id; local handler = options.handler; if id:match('^%d%d%d%d%d%d%d%d$') then -- is this identifier using temporary format? set_message ('maint_zbl'); -- yes, add maint cat elseif not id:match('^%d?%d?%d?%d%.%d%d%d%d%d$') then -- not temporary, is it normal format? set_message ('err_bad_zbl'); -- no, set an error message options.coins_list_t['ZBL'] = nil; -- when error, unset so not included in COinS end return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode}); end --============================<< I N T E R F A C E F U N C T I O N S >>========================================== --[[--------------------------< E X T R A C T _ I D S >------------------------------------------------------------ Populates ID table from arguments using configuration settings. Loops through cfg.id_handlers and searches args for any of the parameters listed in each cfg.id_handlers['...'].parameters. If found, adds the parameter and value to the identifier list. Emits redundant error message if more than one alias exists in args ]] local function extract_ids (args) local id_list = {}; -- list of identifiers found in args for k, v in pairs (cfg.id_handlers) do -- k is uppercase identifier name as index to cfg.id_handlers; e.g. cfg.id_handlers['ISBN'], v is a table v = select_one (args, v.parameters, 'err_redundant_parameters' ); -- v.parameters is a table of aliases for k; here we pick one from args if present if is_set (v) then id_list[k] = v; end -- if found in args, add identifier to our list end return id_list; end --[[--------------------------< E X T R A C T _ I D _ A C C E S S _ L E V E L S >-------------------------------------- Fetches custom id access levels from arguments using configuration settings. Parameters which have a predefined access level (e.g. arxiv) do not use this function as they are directly rendered as free without using an additional parameter. returns a table of k/v pairs where k is same as the identifier's key in cfg.id_handlers and v is the assigned (valid) keyword access-level values must match the case used in cfg.keywords_lists['id-access'] (lowercase unless there is some special reason for something else) ]] local function extract_id_access_levels (args, id_list) local id_accesses_list = {}; for k, v in pairs (cfg.id_handlers) do local access_param = v.custom_access; -- name of identifier's access-level parameter if is_set (access_param) then local access_level = args[access_param]; -- get the assigned value if there is one if is_set (access_level) then if not in_array (access_level, cfg.keywords_lists['id-access']) then -- exact match required set_message ('err_invalid_param_val', {access_param, access_level}); access_level = nil; -- invalid so unset end if not is_set (id_list[k]) then -- identifier access-level must have a matching identifier set_message ('err_param_access_requires_param', {k:lower()}); -- parameter name is uppercase in cfg.id_handlers (k); lowercase for error message end id_accesses_list[k] = cfg.keywords_xlate[access_level]; -- get translated keyword end end end return id_accesses_list; end --[[--------------------------< B U I L D _ I D _ L I S T >---------------------------------------------------- render the identifiers into a sorted sequence table <ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value <options_t> is a table of various k/v option pairs provided in the call to new_build_id_list(); modified by this function and passed to all identifier rendering functions <access_levels_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value (if valid) returns a sequence table of sorted (by hkey - 'handler' key) rendered identifier strings ]] local function build_id_list (ID_list_coins_t, options_t, access_levels_t) local ID_list_t = {}; local accept; local func_map = { --function map points to functions associated with hkey identifier ['ARXIV'] = arxiv, ['ASIN'] = asin, ['BIBCODE'] = bibcode, ['BIORXIV'] = biorxiv, ['CITESEERX'] = citeseerx, ['DOI'] = doi, ['EISSN'] = issn, ['HDL'] = hdl, ['ISBN'] = isbn, ['ISMN'] = ismn, ['ISSN'] = issn, ['JFM'] = jfm, ['JSTOR'] = jstor, ['LCCN'] = lccn, ['MEDRXIV'] = medrxiv, ['MR'] = mr, ['OCLC'] = oclc, ['OL'] = openlibrary, ['OSTI'] = osti, ['PMC'] = pmc, ['PMID'] = pmid, ['RFC'] = rfc, ['S2CID'] = s2cid, ['SBN'] = sbn, ['SSRN'] = ssrn, ['USENETID'] = usenet_id, ['ZBL'] = zbl, } for hkey, v in pairs (ID_list_coins_t) do v, accept = has_accept_as_written (v); -- remove accept-as-written markup if present; accept is boolean true when markup removed; false else -- every function gets the options table with value v and accept boolean options_t.hkey = hkey; -- ~/Configuration handler key options_t.id = v; -- add that identifier value to the options table options_t.accept = accept; -- add the accept boolean flag options_t.access = access_levels_t[hkey]; -- add the access level for those that have an |<identifier-access= parameter options_t.handler = cfg.id_handlers[hkey]; options_t.coins_list_t = ID_list_coins_t; -- pointer to ID_list_coins_t; for |asin= and |ol=; also to keep erroneous values out of the citation's metadata options_t.coins_list_t[hkey] = v; -- id value without accept-as-written markup for metadata if options_t.handler.access and not in_array (options_t.handler.access, cfg.keywords_lists['id-access']) then error (cfg.messages['unknown_ID_access'] .. options_t.handler.access); -- here when handler access key set to a value not listed in list of allowed id access keywords end if func_map[hkey] then local id_text = func_map[hkey] (options_t); -- call the function to get identifier text and any error message table.insert (ID_list_t, {hkey, id_text}); -- add identifier text to the output sequence table else error (cfg.messages['unknown_ID_key'] .. hkey); -- here when func_map doesn't have a function for hkey end end local function comp (a, b) -- used by following table.sort() return a[1]:lower() < b[1]:lower(); -- sort by hkey end table.sort (ID_list_t, comp); -- sequence table of tables sort for k, v in ipairs (ID_list_t) do -- convert sequence table of tables to simple sequence table of strings ID_list_t[k] = v[2]; -- v[2] is the identifier rendering from the call to the various functions in func_map{} end return ID_list_t; end --[[--------------------------< O P T I O N S _ C H E C K >---------------------------------------------------- check that certain option parameters have their associated identifier parameters with values <ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value <ID_support_t> is a sequence table of tables created in citation0() where each subtable has four elements: [1] is the support parameter's assigned value; empty string if not set [2] is a text string same as key in cfg.id_handlers [3] is cfg.error_conditions key used to create error message [4] is original ID support parameter name used to create error message returns nothing; on error emits an appropriate error message ]] local function options_check (ID_list_coins_t, ID_support_t) for _, v in ipairs (ID_support_t) do if is_set (v[1]) and not ID_list_coins_t[v[2]] then -- when support parameter has a value but matching identifier parameter is missing or empty set_message (v[3], (v[4])); -- emit the appropriate error message end end end --[[--------------------------< I D E N T I F I E R _ L I S T S _ G E T >-------------------------------------- Creates two identifier lists: a k/v table of identifiers and their values to be used locally and for use in the COinS metadata, and a sequence table of the rendered identifier strings that will be included in the rendered citation. ]] local function identifier_lists_get (args_t, options_t, ID_support_t) local ID_list_coins_t = extract_ids (args_t); -- get a table of identifiers and their values for use locally and for use in COinS options_check (ID_list_coins_t, ID_support_t); -- ID support parameters must have matching identifier parameters local ID_access_levels_t = extract_id_access_levels (args_t, ID_list_coins_t); -- get a table of identifier access levels local ID_list_t = build_id_list (ID_list_coins_t, options_t, ID_access_levels_t); -- get a sequence table of rendered identifier strings return ID_list_t, ID_list_coins_t; -- return the tables end --[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >-------------------------------------- Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules. ]] local function set_selected_modules (cfg_table_ptr, utilities_page_ptr) cfg = cfg_table_ptr; has_accept_as_written = utilities_page_ptr.has_accept_as_written; -- import functions from select Module:Citation/CS1/Utilities module is_set = utilities_page_ptr.is_set; in_array = utilities_page_ptr.in_array; set_message = utilities_page_ptr.set_message; select_one = utilities_page_ptr.select_one; substitute = utilities_page_ptr.substitute; make_wikilink = utilities_page_ptr.make_wikilink; z = utilities_page_ptr.z; -- table of tables in Module:Citation/CS1/Utilities end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return { auto_link_urls = auto_link_urls, -- table of identifier URLs to be used when auto-linking |title= identifier_lists_get = identifier_lists_get, -- experiment to replace individual calls to build_id_list(), extract_ids, extract_id_access_levels is_embargoed = is_embargoed; set_selected_modules = set_selected_modules; } 6uzqpmnr4f7kbilmaopc20fiwrqbywt Ronney:Ruggyryn 'sy vlein 1720 14 30275 382124 348104 2026-06-05T00:27:22Z MacTire02 219 clowan noa 382124 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1729 14 30278 382120 348097 2026-06-05T00:26:26Z MacTire02 219 clowan noa 382120 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1876 14 30406 382220 381521 2026-06-05T01:31:40Z MacTire02 219 clowan noa 382220 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ibn Saud 0 30518 382351 326012 2026-06-05T02:58:18Z MacTire02 219 ++ 382351 wikitext text/x-wiki {{WD Kishtey Fys Dooinney | date_ruggyr = {{date_ruggyr|df=y|1875|1|15}} | boayl_ruggyr = [[Riyadh]], [[Emmiraid Nejd|Nejd]] | date_baaish = {{date as eash marroo|df=y|1953|11|9|1875|1|15}} | boayl_baaish = [[Plaase Shubra]], Ta'if, yn Araab Saudi }} '''Abdulaziz bin Abdul Rahman Al Saud''' ({{lang-ar|عبد العزيز بن عبد الرحمن آل سعود}} ''ʿAbd al-ʿAzīz bin ʿAbd ar-Raḥman Āl Suʿūd''; 15 Jerrey Geuree 1875{{efn|She bun arganeyssyn blein ruggyree Ibn Saud. Er y chooid smoo, ta sleih gra dy re ayns 1875 v'eh ruggit, agh ta farraneyn elley gra dy re ayns 1880 v'eh ruggit. Rere lioar yn ughtar Goaldagh [[Robert Lacey]], ''The Kingdom'', ren screeudeyr shennaghys Saudi feddyn magh recortyssyn ta taishbyney Ibn Saud ayns 1891 cur failt roish çhaghteraght eggyssagh scanshoil. Ren y screeudeyr shennaghys resooney nagh row paitçhey jeih bleeaney ny un vlein jeig d'eash (myr v'eh rere y date ruggyree ayns 1880) cho shen as dy ve lowit cur failt er çhaghteraght va cha scanshoil as v'eh, agh dy row jeigeyr 15 ny 16 bleeaney d'eash (myr v'eh rere y date ruggyree ayns 1875) lowit. Tra ren Lacey co-akin lesh nane jeh mec Ibn Sauid roish my ren eh soilshaghey magh e lioar, chooinnee yn mac dy ren e ayr gearey er lheid recortys shen va taishbyney e ghate ruggyree ayns 1880. Dreggyr Ibn Saud rish ny recortyssyn shen, rere recortyssyn, lesh yn abbyrt "Ren mee sluggey kiare bleeaney jeh my vea." dg. 561"}} – 9 Sauin 1953), ta enmyssit 'sy Theihll Heear myr '''Ibn Saud''' ({{lang-ar|ابن سعود}}; ''Ibn Suʿūd''),{{efn|She sorçh enmys va ''Ibn Saud'', meanal "mac Saud" (jeeagh er [[Ennym Arabagh#Nasab|ennym Arabagh]]), va ymmyrkit ec toshee elley jeh [[Reeraghtys Saud]], gollrish "Y Stanlagh". Tra t'eh ymmydit gyn traght, t'eh çheet er Abdulaziz bin Abdul Rahman er lheh. Ansherbee, roish goaill [[Riyadh]] ayns 1902 ren eh çheet er e ayr, [[Abdul Rahman bin Faisal]] {{harv|Lacey|1982|pp=15,65}}.}} she toshiagh politickagh as crauee Arabagh chur [[yn Araab Saudi]] er bun &ndash; y trass steat Saudi &ndash; as ren eh reirey yn reeriaght myr e chied [[Ree yn Araab Saudi|ree]] voish 23 Mean Fouyir 1932 derrey laa e vaaish ayns 1953. V'eh er ny reirey ayrnyn jeh'n reeriaght veih 1902, tra v'eh ny [[Emmiraid Riyadh|Emmir]], ny [[Sultanaght Nejd|Hultan]], as ny [[Ree Nejd|Ree er Nejd]], chammah as ny [[Ree Hejaz|Ree er Hejaz]].<ref>{{cite encyclopedia|title=Ibn Saud|author=John B. Glubb|author-link=John Bagot Glubb|url=https://www.britannica.com/biography/Ibn-Saud|date=2021-11-5|encyclopedia=[[Encyclopædia Britannica]]}}</ref> ==Noteyn== {{notelist}} ==Imraaghyn== ===Symnaghyn=== {{reflist}} ===Lioaryn=== {{refbegin}} * {{cite book |first=Robert |last=Lacey |title=The Kingdom |url=https://archive.org/details/kingdomlace00lace |url-access=registration |year=1982 |publisher=Harcourt Brace Jovanovich |isbn=978-0-15-147260-4 |location=New York}} {{refend}} ==Kianglaghyn magh== {{Wikiquote}} {{Commons|Ibn Saud}} * {{Cite EB1922|wstitle=Ibn Sa'ud |short=x}} * {{PM20|FID=pe/008447}} {{Gurneil eaghtyrys}} {{DEFAULTSORT:Saud}} [[Ronney:Reeghyn Saudi]] [[Ronney:Ruggyryn 'sy vlein 1875]] [[Ronney:Baaseyn 'sy vlein 1953]] [[Ronney:Ibn Saud| ]] [[Ronney:Arabee ass yn Impiraght Ottomanagh]] [[Ronney:Monarkyn bunnee]] [[Ronney:Feallee ass Riyadh]] [[Ronney:Moslymee Sunni ass yn Araab Saudi]] [[Ronney:Feallee hannee bio lurg soiagh atçhimagh]] [[Ronney:Toshee pholitickagh 'sy Nah Chaggey Dowanagh]] er6fegsth73uaax2tglnwuo3ibcagyy Ronney:Ruggyryn 'sy vlein 1875 14 30521 382219 381533 2026-06-05T01:31:30Z MacTire02 219 clowan noa 382219 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1897 14 30623 382239 380914 2026-06-05T01:41:37Z MacTire02 219 clowan noa 382239 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1738 14 30624 382115 348095 2026-06-05T00:22:15Z MacTire02 219 clowan noa 382115 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1797 14 30756 382151 348030 2026-06-05T01:05:34Z MacTire02 219 clowan noa 382151 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1834 14 30814 382183 347885 2026-06-05T01:23:05Z MacTire02 219 clowan noa 382183 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1769 14 31005 382099 348058 2026-06-05T00:10:06Z MacTire02 219 clowan noa 382099 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1847 14 31102 382193 347901 2026-06-05T01:24:47Z MacTire02 219 clowan noa 382193 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1785 14 31277 382145 348046 2026-06-05T01:01:51Z MacTire02 219 clowan noa 382145 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1763 14 31382 382102 348063 2026-06-05T00:10:48Z MacTire02 219 clowan noa 382102 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1777 14 31392 382141 348048 2026-06-05T01:01:17Z MacTire02 219 clowan noa 382141 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1710 14 31435 382137 348117 2026-06-05T00:52:53Z MacTire02 219 clowan noa 382137 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1825 14 31498 382176 347874 2026-06-05T01:21:35Z MacTire02 219 clowan noa 382176 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1715 14 31862 382134 348109 2026-06-05T00:51:58Z MacTire02 219 clowan noa 382134 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1755 14 31868 382107 348069 2026-06-05T00:17:21Z MacTire02 219 clowan noa 382107 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1914 14 31879 382256 347793 2026-06-05T01:45:18Z MacTire02 219 clowan noa 382256 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1871 14 31971 382214 381512 2026-06-05T01:30:27Z MacTire02 219 clowan noa 382214 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1736 14 32333 382116 348088 2026-06-05T00:22:26Z MacTire02 219 clowan noa 382116 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1806 14 32677 382158 347835 2026-06-05T01:10:14Z MacTire02 219 clowan noa 382158 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1717 14 33240 382133 348108 2026-06-05T00:51:35Z MacTire02 219 clowan noa 382133 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Levi Ruivivar 0 38496 382349 354063 2026-06-05T02:10:57Z MacTire02 219 -- 382349 wikitext text/x-wiki {{WD Kishtey Fys Dooinney | jalloo = Meet_and_Greet_with_the_Filipino_Paris_Olympians_2024_08_22_Levi_Ruivivar.jpg | fo-heidyl = Ruivivar ayns 2024 | ennym_ruggyr = Levi Jung Ruivivar | date_ruggyr = {{date_ruggit|df=y|2006|5|3}}<ref name="Paarys">{{Cite web|url=https://olympics.com/en/paris-2024/athlete/levi-ruivivar_3054235|title=RUIVIVAR Levi}}</ref> | boayl_ruggyr = [[Los Angeles, California]], ny Steatyn Unnaneysit<ref name="Paarys"/> | yrjid = {{yrjid|m=1.68}} }} She [[lheiltys ellynagh|lheiltagh ellynagh]] [[Americaanee Philippeenagh|Americaanagh-Philippeenagh]] ee '''Levi Jung Ruivivar''' (ruggit er 3 Boaldyn 2006). Ga dy row ee ruggit ayns ny Steatyn Unnaneysit, t'ee cloie er son ny h-Ellanyn Philippeenagh dy h-eddryashoonagh as chloie ee er son ny Steatyn Unnaneysit tra v'ee ny s'aa. Chossyn ee qualleeaght dy chloie er son [[ny h-Ellanyn Philippeenagh ayns Cloiaghyn Olympagh y Touree, 2024]] trooid [[Straih Chappan FIG y Dowan ayns Lheiltys Ellynagh, 2024#Qualleeaghtyn Olympagh|straih Chappan FIG y Dowan, 2024]]. Er 29 Luanistyn 2024, ren Jung-Ruivivar fo-screeu conaant marish [[Viva Artists Agency|Viva Artist Agency]] son craishtey as cloie choud's v'ee foast traenal son y lheiltys.<ref>{{Cite web |title=From the Olympics to showbiz: Gymnast Levi Jung-Ruivivar signs with Viva Artists Agency |url=https://www.onesports.ph/paris-2024/article/24069/from-the-olympics-to-showbiz-gymnast-levi-jung-ruivivar-signs-with-viva-artists-agency |access-date=2024-09-03 |website=onesports.ph |language=en}}</ref> ==Imraaghyn== {{reflist}} ==Kianglaghyn magh== * {{FIG|bio=75273|name=Levi Ruivivar}} * {{USA Gymnastics|559091}} {{Gurneil eaghtyrys}} {{DEFAULTSORT:Ruivivar, Levi}} [[Ronney:Ruggyryn 'sy vlein 2006]] [[Ronney:Feallee vio]] [[Ronney:Lheiltee ellynagh woirrin Philippeenagh]] [[Ronney:Lheiltee ellynagh woirrin Americaanagh]] [[Ronney:Lheiltee wirran ashoonagh mraane ny Steatyn Unnaneysit]] [[Ronney:Craishteyderyn bwoirrin Philippeenagh]] [[Ronney:Craishteyderyn bwoirrin Americaanagh]] [[Ronney:Craishteyderyn ass California]] [[Ronney:Viva Artists Agency]] [[Ronney:Philippeenee jeh sluight Americaanagh]] [[Ronney:Philippeenee jeh sluight Germaanagh]] [[Ronney:Philippeenee jeh sluight Yernagh]] [[Ronney:Americaanee jeh sluight Philippeenagh]] [[Ronney:Americaanee jeh sluight Germaanagh]] [[Ronney:Americaanee jeh sluight Yernagh]] [[Ronney:Lheiltee ec Cloiaghyn Olympagh y Touree, 2024]] [[Ronney:Lheiltee Olympagh ny h-Ellanyn Philippeenagh]] [[Ronney:Lheiltee ass California]] [[Ronney:Feallee ass Los Angeles]] gbc8exfx40m2a9ng52wiplkz7fvp60x Ronney:Ruggyryn 'sy vlein 1764 14 40821 382101 359365 2026-06-05T00:10:37Z MacTire02 219 clowan noa 382101 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a Ronney:Ruggyryn 'sy vlein 1845 14 43354 382192 365426 2026-06-05T01:24:37Z MacTire02 219 clowan noa 382192 wikitext text/x-wiki {{Ronney ruggyryn 'sy vlein YYYY}} rfjgiocca7j023ovqyxhra53rlhd95a