Wikipedia
iewiki
https://ie.wikipedia.org/wiki/Principal_p%C3%A1gine
MediaWiki 1.46.0-wmf.24
first-letter
Media
Special
Discussion
Usator
Usator Discussion
Wikipedia
Wikipedia Discussion
File
File Discussion
MediaWiki
MediaWiki Discussion
Avise
Avise Discussion
Auxilie
Auxilie Discussion
Categorie
Categorie Discussion
TimedText
TimedText talk
Module
Module talk
Event
Event talk
Wikipedia:Li Trincatoria
4
2399
167668
167444
2026-04-26T00:57:56Z
MediaWiki message delivery
5804
/* Request for comment (global AI policy) */ nov section
167668
wikitext
text/x-wiki
__NEWSECTIONLINK__
[[Categorie:Wikipedia]]
<div class="noprint" style="float:right; border:1px solid #aaaaaa; background-color:#f9f9f9; color:black; padding:3px; margin: .3em; margin-right:0;font-size:2em; width: 170px;">
[[File:Filing cabinet icon.svg|30px|Archiv]]
[[Wikipedia:Li Trincatoria/Archive|Archives]]
</div>
[[File:Pineapple Milkshake.JPG|thumb|upright=0.75|Benevenit in li Trincatoria. Ples haver un trinc de ananas, sin alcohol.]]
:'''''Abbreviation:''' [[WP:LT]].''
{| class="wikitable"
!English: ||Interlingue/Occidental:
|-
| Requests for the [[m:bot|bot]] flag should be made on this page. This wiki uses the [[m:bot policy|standard bot policy]], and allows [[m:bot policy#Global_bots|global bots]] and [[m:bot policy#Automatic_approval|automatic approval of certain types of bots]]. Other bots should apply below, and then [[m:Steward requests/Bot status|request access]] from a steward if there is no objection.
|Petitiones por li [[m:bot|bot-flag]] Vu posse scrir sur ti págine. Ti ci wiki usa li [[m:bot policy|standardic bot-policie]] e permisse [[m:bot policy#Global_bots|global bots]] e [[m:bot policy#Automatic_approval|automatic approba de cert types de bots]]. Altri bots mey scrir un petition in infra, e poy [[m:Steward requests/Bot status|petir accesse]] de un steward si ne existe un objection.
|-
|Questions, comments or propositions about this Wikipedia, or about the Interlingue/Occidental language? This is the page for such messages, feel free to write or add a section below.
|Questiones, comments o propositions pri ti Wikipedia o pri li lingue Interlingue/Occidental? To es li págine por tal missages, Ples scrir in o addir un section in infra.
|}
== Feminism and Folklore 2023 ==
<div style="border:8px maroon ridge;padding:6px;>
[[File:Feminism and Folklore 2023 logo.svg|centre|550px|frameless]]
::<div lang="en" dir="ltr" class="mw-content-ltr">
<center>''{{int:please-translate}}''</center>
Dear Wiki Community,
Christmas Greetings and a Happy New Year 2023,
You are humbly invited to organize the '''[[:m:Feminism and Folklore 2023|Feminism and Folklore 2023]]''' writing competition from February 1, 2023, to March 31, 2023 on your local Wikipedia. This year, Feminism and Folklore will focus on feminism, women's issues, and gender-focused topics for the project, with a [[:c:Commons:Wiki Loves Folklore 2023|Wiki Loves Folklore]] gender gap focus and a folk culture theme on Wikipedia.
You can help Wikipedia's coverage of folklore from your area by writing or improving articles about things like folk festivals, folk dances, folk music, women and queer folklore figures, folk game athletes, women in mythology, women warriors in folklore, witches and witch hunting, fairy tales, and more. Users can help create new articles, expand or translate from a [[:m:Feminism and Folklore 2023/List of Articles|list]] of suggested articles.
Organisers are requested to work on the following action items to sign up their communities for the project:
# Create a page for the contest on the local wiki.
# Set up a fountain tool or dashboard.
# Create the local list and mention the timeline and local and international prizes.
# Request local admins for site notice.
# Link the local page and the fountain/dashboard link on the [[:m:Feminism and Folklore 2023/Project Page|meta project page]].
This year we would be supporting the community's financial aid for Internet and childcare support. This would be provided for the local team including their jury and coordinator team. This support is opt-in and non mandatory. Kindly fill in [https://docs.google.com/forms/d/e/1FAIpQLSea81OO0lVgUBd551iIiENXht7BRCISYZlKyBQlemZu_j2OHQ/viewform this Google form] and mark a mail to [mailto:support@wikilovesfolklore.org support@wikilovesfolklore.org] with the subject line starting as [Stipend] Name or Username/Language. The last date to sign up for internet and childcare aid from our team is 20th of January 2023, We encourage the language coordinators to sign up their community on this link by the 25th of January 2023.
Learn more about the contest and prizes on our [[:m:Feminism and Folklore 2023|project page]]. Feel free to contact us on our [[:m:Talk:Feminism and Folklore 2023/Project Page|meta talk page]] or by email us if you need any assistance.
We look forward to your immense coordination.
Thank you and Best wishes,
[[:m:Feminism and Folklore 2023|Feminism and Folklore 2023 International Team]]
::::Stay connected [[File:B&W Facebook icon.png|link=https://www.facebook.com/feminismandfolklore/|30x30px]] [[File:B&W Twitter icon.png|link=https://twitter.com/wikifolklore|30x30px]]
</div></div>
--[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 10:23, 24 decembre 2022 (UTC)
<!-- Message sent by User:Tiven2240@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery/Wikipedia&oldid=23942484 -->
== Global ban for PlanespotterA320/RespectCE ==
Per the [[m:Global bans|Global bans]] policy, I'm informing the project of this request for comment: [[m:Requests for comment/Global ban for PlanespotterA320 (2) ]] about banning a member from your community. Thank you.--[[User:Lemonaka|Lemonaka]] ([[User talk:Lemonaka|talk]]) 21:40, 6 February 2023 (UTC)
<!-- Message sent by User:Zabe@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Lemonaka/Massmessagelist&oldid=24501599 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Your wiki will be in read only soon</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="server-switch"/><div class="plainlinks">
[[:m:Special:MyLanguage/Tech/Server switch|Read this message in another language]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Tech%2FServer+switch&language=&action=page&filter= {{int:please-translate}}]
The [[foundation:|Wikimedia Foundation]] tests the switch between its first and secondary data centers. This will make sure that Wikipedia and the other Wikimedia wikis can stay online even after a disaster. To make sure everything is working, the Wikimedia Technology department needs to do a planned test. This test will show if they can reliably switch from one data centre to the other. It requires many teams to prepare for the test and to be available to fix any unexpected problems.
All traffic will switch on '''{{#time:j xg|2023-03-01|en}}'''. The test will start at '''[https://zonestamp.toolforge.org/{{#time:U|2023-03-01T14:00|en}} {{#time:H:i e|2023-03-01T14:00}}]'''.
Unfortunately, because of some limitations in [[mw:Manual:What is MediaWiki?|MediaWiki]], all editing must stop while the switch is made. We apologize for this disruption, and we are working to minimize it in the future.
'''You will be able to read, but not edit, all wikis for a short period of time.'''
*You will not be able to edit for up to an hour on {{#time:l j xg Y|2023-03-01|en}}.
*If you try to edit or save during these times, you will see an error message. We hope that no edits will be lost during these minutes, but we can't guarantee it. If you see the error message, then please wait until everything is back to normal. Then you should be able to save your edit. But, we recommend that you make a copy of your changes first, just in case.
''Other effects'':
*Background jobs will be slower and some may be dropped. Red links might not be updated as quickly as normal. If you create an article that is already linked somewhere else, the link will stay red longer than usual. Some long-running scripts will have to be stopped.
* We expect the code deployments to happen as any other week. However, some case-by-case code freezes could punctually happen if the operation require them afterwards.
* [[mw:Special:MyLanguage/GitLab|GitLab]] will be unavailable for about 90 minutes.
This project may be postponed if necessary. You can [[wikitech:Switch_Datacenter|read the schedule at wikitech.wikimedia.org]]. Any changes will be announced in the schedule. There will be more notifications about this. A banner will be displayed on all wikis 30 minutes before this operation happens. '''Please share this information with your community.'''</div><section end="server-switch"/>
</div>
<span dir=ltr>[[m:User:Trizek (WMF)|Trizek (WMF)]] ([[m:User talk:Trizek (WMF)|{{int:talk}}]])</span> 21:20, 27 februar 2023 (UTC)
<!-- Message sent by User:Trizek (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=24390465 -->
== Ukraine's Cultural Diplomacy Month 2023: We are back! ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<div lang="en" dir="ltr" class="mw-content-ltr">
[[File:UCDM 2023 promo.png|180px|right]]
{{int:please-translate}}
Hello, dear Wikipedians!<br/>
[[m:Special:MyLanguage/Wikimedia Ukraine|Wikimedia Ukraine]], in cooperation with the [[:en:Ministry of Foreign Affairs of Ukraine|Ministry of Foreign Affairs of Ukraine]] and [[:en:Ukrainian Institute|Ukrainian Institute]], has launched the third edition of writing challenge "'''[[m:Special:MyLanguage/Ukraine's Cultural Diplomacy Month 2023|Ukraine's Cultural Diplomacy Month]]'''", which lasts from 1st until 31st March 2023. The campaign is dedicated to famous Ukrainian artists of cinema, music, literature, architecture, design and cultural phenomena of Ukraine that are now part of world heritage. We accept contribution in every language! The most active contesters will receive [[m:Special:MyLanguage/Ukraine's Cultural Diplomacy Month 2023/Prizes|prizes]].<br/>
We invite you to take part and help us improve the coverage of Ukrainian culture on Wikipedia in your language! Also, we plan to set up a [[m:CentralNotice/Request/UCDM 2023|banner]] to notify users of the possibility to participate in such a challenge!
</div>
[[m:User:ValentynNefedov (WMUA)|ValentynNefedov (WMUA)]] ([[m:User talk:ValentynNefedov (WMUA)|talk]]) 07:58, 1 March 2023 (UTC)
</div>
<!-- Message sent by User:ValentynNefedov (WMUA)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery/Wikipedia&oldid=23942484 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Wikimania 2023 Welcoming Program Submissions</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="wikimania-program-submissions"/>[[File:Wikimedia_Singapore_Logo.svg|right|frameless]]Do you want to host an in-person or virtual session at Wikimania 2023? Maybe a hands-on workshop, a lively discussion, a fun performance, a catchy poster, or a memorable lightning talk? [[wmania:Special:MyLanguage/2023:Program/Submissions|'''Submissions are open until March 28''']]. The event will have dedicated hybrid blocks, so virtual submissions and pre-recorded content are also welcome. If you have any questions, please join us at an upcoming conversation on March 12 or 19, or reach out by email at wikimania@wikimedia.org or on Telegram. More information on-wiki.<section end="wikimania-program-submissions"/>
</div>
<!-- Message sent by User:CKoerner (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=24390465 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Your wiki will be in read-only soon</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="server-switch"/><div class="plainlinks">
[[:m:Special:MyLanguage/Tech/Server switch|Read this message in another language]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Tech%2FServer+switch&language=&action=page&filter= {{int:please-translate}}]
The [[foundation:|Wikimedia Foundation]] tests the switch between its first and secondary data centers. This will make sure that Wikipedia and the other Wikimedia wikis can stay online even after a disaster. To make sure everything is working, the Wikimedia Technology department needs to do a planned test. This test will show if they can reliably switch from one data centre to the other. It requires many teams to prepare for the test and to be available to fix any unexpected problems.
All traffic will switch on '''{{#time:j xg|2023-04-26|en}}'''. The test will start at '''[https://zonestamp.toolforge.org/{{#time:U|2023-04-26T14:00|en}} {{#time:H:i e|2023-04-26T14:00}}]'''.
Unfortunately, because of some limitations in [[mw:Manual:What is MediaWiki?|MediaWiki]], all editing must stop while the switch is made. We apologize for this disruption, and we are working to minimize it in the future.
'''You will be able to read, but not edit, all wikis for a short period of time.'''
*You will not be able to edit for up to an hour on {{#time:l j xg Y|2023-04-26|en}}.
*If you try to edit or save during these times, you will see an error message. We hope that no edits will be lost during these minutes, but we can't guarantee it. If you see the error message, then please wait until everything is back to normal. Then you should be able to save your edit. But, we recommend that you make a copy of your changes first, just in case.
''Other effects'':
*Background jobs will be slower and some may be dropped. Red links might not be updated as quickly as normal. If you create an article that is already linked somewhere else, the link will stay red longer than usual. Some long-running scripts will have to be stopped.
* We expect the code deployments to happen as any other week. However, some case-by-case code freezes could punctually happen if the operation require them afterwards.
* [[mw:Special:MyLanguage/GitLab|GitLab]] will be unavailable for about 90 minutes.
This project may be postponed if necessary. You can [[wikitech:Switch_Datacenter|read the schedule at wikitech.wikimedia.org]]. Any changes will be announced in the schedule. There will be more notifications about this. A banner will be displayed on all wikis 30 minutes before this operation happens. '''Please share this information with your community.'''</div><section end="server-switch"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 00:41, 21 april 2023 (UTC)
<!-- Message sent by User:UOzurumba (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=24748237 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Seeking volunteers for the next step in the Universal Code of Conduct process</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''<div class="plainlinks">[[m:Special:MyLanguage/Universal Code of Conduct/U4C Building Committee/Nominations/Announcement|{{int:interlanguage-link-mul}}]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/U4C Building Committee/Nominations/Announcement}}&language=&action=page&filter= {{int:please-translate}}]</div>''
Hello,
As follow-up to [https://lists.wikimedia.org/hyperkitty/list/wikimedia-l@lists.wikimedia.org/message/IOMVS7W75ZYMABQGOQ2QH2JAURC3CHGH/ the message about the Universal Code of Conduct Enforcement Guidelines] by Wikimedia Foundation Board of Trustees Vice Chair, Shani Evenstein Sigalov, I am reaching out about the next steps. I want to bring your attention to the next stage of the Universal Code of Conduct process, which is forming a building committee for the Universal Code of Conduct Coordinating Committee (U4C). I invite community members with experience and deep interest in community health and governance to nominate themselves to be part of the U4C building committee, which needs people who are:
* Community members in good standing
* Knowledgeable about movement community processes, such as, but not limited to, policy drafting, participatory decision making, and application of existing rules and policies on Wikimedia projects
* Aware and appreciative of the diversity of the movement, such as, but not limited to, languages spoken, identity, geography, and project type
* Committed to participate for the entire U4C Building Committee period from mid-May - December 2023
* Comfortable with engaging in difficult, but productive conversations
* Confidently able to communicate in English
The Building Committee shall consist of volunteer community members, affiliate board or staff, and Wikimedia Foundation staff.
The Universal Code of Conduct has been a process strengthened by the skills and knowledge of the community and I look forward to what the U4C Building Committee creates. If you are interested in joining the Building Committee, please either [[m:Special:MyLanguage/Universal_Code_of_Conduct/U4C_Building_Committee/Nominations|sign up on the Meta-Wiki page]], or contact ucocproject[[File:At sign.svg|16x16px|link=|(_AT_)]]wikimedia.org by May 12, 2023. '''[[m:Special:MyLanguage/Universal_Code_of_Conduct/U4C_Building_Committee|Read more on Meta-Wiki]]'''.
Best regards,<br /><section end="announcement-content" />
</div>
[[User:Xeno (WMF)|Xeno (WMF)]] 19:00, 26 april 2023 (UTC)
<!-- Message sent by User:Xeno (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=24941045 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Selection of the U4C Building Committee</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
The next stage in the Universal Code of Conduct process is establishing a Building Committee to create the charter for the Universal Code of Conduct Coordinating Committee (U4C). The Building Committee has been selected. [[m:Special:MyLanguage/Universal_Code_of_Conduct/U4C_Building_Committee|Read about the members and the work ahead on Meta-wiki]].<section end="announcement-content" />
</div>
-- [[m:Special:MyLanguage/Universal_Code_of_Conduct/Project|UCoC Project Team]], 04:20, 27 may 2023 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=25018085 -->
== Votation por devenir sysop denov ==
Yer yo audit que noi have tro mult spam in nor Wikipedia e que it vell esser un bon idé devenir un sysop denov (li ultim vez yo esset sysop durant un annu, til decembre 2022 si yo memora bon). Por "resysopificar" me on deve monstrar les que li comunité aproba, dunc ples votar! [[Usator:Mithridates|Mithridates]] ([[Usator Discussion:Mithridates|discussion]]) 23:05, 27 junio 2023 (UTC)
'''Por'''
* --[[Usator:Caro de Segeda|Caro de Segeda]] ([[Usator Discussion:Caro de Segeda|discussion]]) 05:31, 28 junio 2023 (UTC)
* [[Usator:Dorlota|Dorlota]] ([[Usator Discussion:Dorlota|discussion]]) 22:44, 28 junio 2023 (UTC)
* [[Usator:SineLaude|SineLaude]] ([[Usator Discussion:SineLaude|discussion]]) 15:36, 29 junio 2023 (UTC)
* [[Usator:Pluntert|Pluntert]] ([[Usator Discussion:Pluntert|discussion]]) 17:20, 29 junio 2023 (UTC)
* '''Por''', <small>ma yo vell promoer Mithridates al rol de "Burócrate", por que li comunité posse facilmen crear nov administratores in li futur. Actualmen, per [[Special:Statistica]], hay nequant.</small>
** Redacte: Hant consultat li págine sur meta-wiki, yo ne pensa que li agentes del WMF vell adjuntar un burócrate por un tant litt Wikipedia, dunc yo retracta mi anteriori comenta al un simplic vota per Mithridates. [[Usator:Frzzl|Frzzl]] ([[Usator Discussion:Frzzl|discussion]]) 17:38, 29 junio 2023 (UTC)
'''Contra'''
== <span lang="en" dir="ltr" class="mw-content-ltr"> Announcing the new Elections Committee members</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Wikimedia Foundation elections committee/Nominatons/2023/Announcement - new members|You can find this message translated into additional languages on Meta-wiki.]]''
:''<div class="plainlinks">[[m:Special:MyLanguage/Wikimedia Foundation elections committee/Nominatons/2023/Announcement - new members|{{int:interlanguage-link-mul}}]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Wikimedia Foundation elections committee/Nominatons/2023/Announcement - new members}}&language=&action=page&filter= {{int:please-translate}}]</div>''
Hello there,
We are glad to announce [[listarchive:list/wikimedia-l@lists.wikimedia.org/message/4TALOUFPAP2VDBR27GKRVOP7IGQYU3DB/|the new members and advisors of the Elections Committee]]. The [[m:Special:MyLanguage/Wikimedia_Foundation_elections_committee|Elections Committee]] assists with the design and implementation of the process to select Community- and Affiliate-Selected trustees for the Wikimedia Foundation Board of Trustees. After an open nomination process, the strongest candidates spoke with the Board and four candidates were asked to join the Elections Committee. Four other candidates were asked to participate as advisors.
Thank you to all the community members who submitted their names for consideration. We look forward to working with the Elections Committee in the near future.
On behalf of the Wikimedia Foundation Board of Trustees,<br /><section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 18:00, 28 junio 2023 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=25018085 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Review the Charter for the Universal Code of Conduct Coordinating Committee</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''<div class="plainlinks">[[m:Special:MyLanguage/Universal Code of Conduct/U4C Building Committee/Announcement - Review|{{int:interlanguage-link-mul}}]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/U4C Building Committee/Announcement - Review}}&language=&action=page&filter= {{int:please-translate}}]</div>''
Hello all,
I am pleased to share the next step in the [[foundation:Special:MyLanguage/Policy:Universal Code of Conduct|Universal Code of Conduct]] work. The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|Universal Code of Conduct Coordinating Committee (U4C) draft charter]] is now ready for your review.
The [[foundation:Special:MyLanguage/Policy:Universal Code of Conduct/Enforcement guidelines|Enforcement Guidelines]] require a [[foundation:Special:MyLanguage/Policy:Universal_Code_of_Conduct/Enforcement_guidelines#4.5_U4C_Building_Committee|Building Committee]] form to draft a charter that outlines procedures and details for a global committee to be called the [[foundation:Special:MyLanguage/Policy:Universal_Code_of_Conduct/Enforcement_guidelines#4._UCoC_Coordinating_Committee_(U4C)|Universal Code of Conduct Coordinating Committee (U4C)]]. Over the past few months, the U4C Building Committee worked together as a group to discuss and draft the U4C charter. The U4C Building Committee welcomes feedback about the draft charter now through 22 September 2023. After that date, the U4C Building Committee will revise the charter as needed and a community vote will open shortly afterward.
Join the conversation during the [[m:Special:MyLanguage/Universal Code of Conduct/U4C Building Committee#Conversation hours|conversation hours]] or on [[m:Talk:Universal Code of Conduct/Coordinating Committee/Charter|Meta-wiki]].
Best,<br /><section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]], on behalf of the U4C Building Committee, 15:35, 28 august 2023 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=25392152 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Your wiki will be in read-only soon</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="server-switch"/><div class="plainlinks">
[[:m:Special:MyLanguage/Tech/Server switch|Read this message in another language]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Tech%2FServer+switch&language=&action=page&filter= {{int:please-translate}}]
The [[foundation:|Wikimedia Foundation]] will switch the traffic between its data centers. This will make sure that Wikipedia and the other Wikimedia wikis can stay online even after a disaster. To make sure everything is working, the Wikimedia Technology department needs to do a planned test. This test will show if they can reliably switch from one data centre to the other. It requires many teams to prepare for the test and to be available to fix any unexpected problems.
All traffic will switch on '''{{#time:j xg|2023-09-20|en}}'''. The test will start at '''[https://zonestamp.toolforge.org/{{#time:U|2023-09-20T14:00|en}} {{#time:H:i e|2023-09-20T14:00}}]'''.
Unfortunately, because of some limitations in [[mw:Special:MyLanguage/Manual:What is MediaWiki?|MediaWiki]], all editing must stop while the switch is made. We apologize for this disruption, and we are working to minimize it in the future.
'''You will be able to read, but not edit, all wikis for a short period of time.'''
*You will not be able to edit for up to an hour on {{#time:l j xg Y|2023-09-20|en}}.
*If you try to edit or save during these times, you will see an error message. We hope that no edits will be lost during these minutes, but we can't guarantee it. If you see the error message, then please wait until everything is back to normal. Then you should be able to save your edit. But, we recommend that you make a copy of your changes first, just in case.
''Other effects'':
*Background jobs will be slower and some may be dropped. Red links might not be updated as quickly as normal. If you create an article that is already linked somewhere else, the link will stay red longer than usual. Some long-running scripts will have to be stopped.
* We expect the code deployments to happen as any other week. However, some case-by-case code freezes could punctually happen if the operation require them afterwards.
* [[mw:Special:MyLanguage/GitLab|GitLab]] will be unavailable for about 90 minutes.
This project may be postponed if necessary. You can [[wikitech:Switch_Datacenter|read the schedule at wikitech.wikimedia.org]]. Any changes will be announced in the schedule. There will be more notifications about this. A banner will be displayed on all wikis 30 minutes before this operation happens. '''Please share this information with your community.'''</div><section end="server-switch"/>
</div>
[[User:Trizek (WMF)|Trizek_(WMF)]] ([[m:User talk:Trizek (WMF)|talk]]) 09:23, 15 septembre 2023 (UTC)
<!-- Message sent by User:Trizek (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=25018086 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">== Opportunities open for the Affiliations Committee, Ombuds commission, and the Case Review Committee ==</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
<div style="margin:.2em 0 .5em;margin-{{#switch:{{PAGELANGUAGE}}|ar|arc|ary|arz|azb|bcc|bgn|ckb|bqi|dv|fa|fa-af|glk|ha-arab|he|kk-arab|kk-cn|ks|ku-arab|ms-arab|mzn|pnb|prd|ps|sd|ug|ur|ydd|yi=right|left}}:3ex;">
[[m:Special:MyLanguage/Wikimedia Foundation Legal department/Committee appointments/Announcement/Short|''You can find this message translated into additional languages on Meta-wiki.'']]
''<span class="plainlinks">[[m:Special:MyLanguage/Wikimedia Foundation Legal department/Committee appointments/Announcement/Short|{{int:interlanguage-link-mul}}]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Wikimedia Foundation Legal department/Committee appointments/Announcement/Short}}&language=&action=page&filter= {{int:please-translate}}]</span>''</div>
Hi everyone! The [[m:Special:MyLanguage/Affiliations Committee|Affiliations Committee]] (AffCom), [[m:Special:MyLanguage/Ombuds_commission|Ombuds commission]] (OC), and the [[m:Special:MyLanguage/Trust_and_Safety/Case_Review_Committee|Case Review Committee]] (CRC) are looking for new members. These volunteer groups provide important structural and oversight support for the community and movement. People are encouraged to nominate themselves or encourage others they feel would contribute to these groups to apply. There is more information about the roles of the groups, the skills needed, and the opportunity to apply on the [[m:Special:MyLanguage/Wikimedia Foundation Legal department/Committee appointments|'''Meta-wiki page''']].
On behalf of the Committee Support team,<br /><section end="announcement-content" />
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
~ [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 16:41, 9 octobre 2023 (UTC) </div>
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=25570445 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Review and comment on the 2024 Wikimedia Foundation Board of Trustees selection rules package</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/wiki/Wikimedia Foundation elections/2024/Announcement/Rules package review - short| You can find this message translated into additional languages on Meta-wiki.]]''
:''<div class="plainlinks">[[m:Special:MyLanguage/wiki/Wikimedia Foundation elections/2024/Announcement/Rules package review - short|{{int:interlanguage-link-mul}}]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:wiki/Wikimedia Foundation elections/2024/Announcement/Rules package review - short}}&language=&action=page&filter= {{int:please-translate}}]</div>''
Dear all,
Please review and comment on the Wikimedia Foundation Board of Trustees selection rules package from now until 29 October 2023. The selection rules package was based on older versions by the Elections Committee and will be used in the 2024 Board of Trustees selection. Providing your comments now will help them provide a smoother, better Board selection process. [[m:Special:MyLanguage/Wikimedia Foundation elections/2024|More on the Meta-wiki page]].
Best,
Katie Chan <br>
Chair of the Elections Committee<br /><section end="announcement-content" />
</div>
01:12, 17 octobre 2023 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=25570445 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Coming soon: Reference Previews</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="ReferencePreviewsDefault"/>
[[File:Example_of_a_Reference_Preview.png|right|300px]]
A new feature is coming to your wiki soon: Reference Previews are popups for references. Such popups have existed on wikis as local gadgets for many years. Now there is a central solution, available on all wikis, and consistent with the [[mw:Special:MyLanguage/Page Previews|PagePreviews feature]].
Reference Previews will be visible to everyone, including readers. If you don’t want to see them, [[m:WMDE Technical Wishes/ReferencePreviews#Opt-out feature|you can opt out]]. If you are [[Special:Preferences#mw-prefsection-gadgets|using the gadgets]] Reference Tooltips or Navigation Popups, you won’t see Reference Previews unless you disable the gadget.
Reference Previews have been a beta feature on many wikis since 2019, and a default feature on some since 2021. Deployment is planned for November 22.
* [[mw:Special:MyLanguage/Help:Reference Previews|Help page]]
* [[m:WMDE Technical Wishes/ReferencePreviews|Project page with more information (in English)]].
* Feedback is welcome [[m:Talk:WMDE Technical Wishes/ReferencePreviews|on this talk page]].
-- For [[m:WMDE Technical Wishes|Wikimedia Deutschland’s Technical Wishes]] team,
<section end="ReferencePreviewsDefault"/>
</div>
[[m:User:Johanna Strodt (WMDE)|Johanna Strodt (WMDE)]], 13:11, 15 novembre 2023 (UTC)
<!-- Message sent by User:Johanna Strodt (WMDE)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=WMDE_Technical_Wishes/Technical_Wishes_News_list_all_village_pumps&oldid=25866958 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">(New) Feature on [[mw:Special:MyLanguage/Help:Extension:Kartographer|Kartographer]]: Adding geopoints via QID</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="Body"/>Since September 2022, it is possible to create geopoints using a QID. Many wiki contributors have asked for this feature, but it is not being used much. Therefore, we would like to remind you about it. More information can be found on the [[M:WMDE_Technical_Wishes/Geoinformation/Geopoints via QID|project page]]. If you have any comments, please let us know on the [[M:Talk:WMDE Technical Wishes/Geoinformation/Geopoints via QID|talk page]]. – Best regards, the team of Technical Wishes at Wikimedia Deutschland
<section end="Body"/>
</div>
[[M:User:Thereza Mengs (WMDE)|Thereza Mengs (WMDE)]] 12:31, 13 decembre 2023 (UTC)
<!-- Message sent by User:Thereza Mengs (WMDE)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=WMDE_Technical_Wishes/Technical_Wishes_News_list_all_village_pumps&oldid=25955829 -->
== Do you use Wikidata in Wikimedia sibling projects? Tell us about your experiences ==
<div lang="en" dir="ltr" class="mw-content-ltr">
''Note: Apologies for cross-posting and sending in English.''
Hello, the '''[[m:WD4WMP|Wikidata for Wikimedia Projects]]''' team at Wikimedia Deutschland would like to hear about your experiences using Wikidata in the sibling projects. If you are interested in sharing your opinion and insights, please consider signing up for an interview with us in this '''[https://wikimedia.sslsurvey.de/Wikidata-for-Wikimedia-Interviews Registration form]'''.<br>
''Currently, we are only able to conduct interviews in English.''
The front page of the form has more details about what the conversation will be like, including how we would '''compensate''' you for your time.
For more information, visit our ''[[m:WD4WMP/AddIssue|project issue page]]'' where you can also share your experiences in written form, without an interview.<br>We look forward to speaking with you, [[m:User:Danny Benjafield (WMDE)|Danny Benjafield (WMDE)]] ([[m:User talk:Danny Benjafield (WMDE)|talk]]) 08:53, 5 January 2024 (UTC)
</div>
<!-- Message sent by User:Danny Benjafield (WMDE)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/WD4WMP/ScreenerInvite&oldid=26027495 -->
== Reusing references: Can we look over your shoulder? ==
''Apologies for writing in English.''
The Technical Wishes team at Wikimedia Deutschland is planning to [[m:WMDE Technical Wishes/Reusing references|make reusing references easier]]. For our research, we are looking for wiki contributors willing to show us how they are interacting with references.
* The format will be a 1-hour video call, where you would share your screen. [https://wikimedia.sslsurvey.de/User-research-into-Reusing-References-Sign-up-Form-2024/en/ More information here].
* Interviews can be conducted in English, German or Dutch.
* [[mw:WMDE_Engineering/Participate_in_UX_Activities#Compensation|Compensation is available]].
* Sessions will be held in January and February.
* [https://wikimedia.sslsurvey.de/User-research-into-Reusing-References-Sign-up-Form-2024/en/ Sign up here if you are interested.]
* Please note that we probably won’t be able to have sessions with everyone who is interested. Our UX researcher will try to create a good balance of wiki contributors, e.g. in terms of wiki experience, tech experience, editing preferences, gender, disability and more. If you’re a fit, she will reach out to you to schedule an appointment.
We’re looking forward to seeing you, [[m:User:Thereza Mengs (WMDE)| Thereza Mengs (WMDE)]]
<!-- Message sent by User:Thereza Mengs (WMDE)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=WMDE_Technical_Wishes/Technical_Wishes_News_list_all_village_pumps&oldid=25956752 -->
== Feminism and Folklore 2024 ==
<div style="border:8px maroon ridge;padding:6px;>
[[File:Feminism and Folklore 2024 logo.svg|centre|550px|frameless]]
::<div lang="en" dir="ltr" class="mw-content-ltr">
<center>''{{int:please-translate}}''</center>
Dear Wiki Community,
You are humbly invited to organize the '''[[:m:Feminism and Folklore 2024|Feminism and Folklore 2024]]''' writing competition from February 1, 2023, to March 31, 2023 on your local Wikipedia. This year, Feminism and Folklore will focus on feminism, women's issues, and gender-focused topics for the project, with a [[:c:Commons:Wiki Loves Folklore 2024|Wiki Loves Folklore]] gender gap focus and a folk culture theme on Wikipedia.
You can help Wikipedia's coverage of folklore from your area by writing or improving articles about things like folk festivals, folk dances, folk music, women and queer folklore figures, folk game athletes, women in mythology, women warriors in folklore, witches and witch hunting, fairy tales, and more. Users can help create new articles, expand or translate from a generated list of suggested articles.
Organisers are requested to work on the following action items to sign up their communities for the project:
# Create a page for the contest on the local wiki.
# Set up a campaign on '''CampWiz''' tool.
# Create the local list and mention the timeline and local and international prizes.
# Request local admins for site notice.
# Link the local page and the CampWiz link on the [[:m:Feminism and Folklore 2024/Project Page|meta project page]].
This year, the Wiki Loves Folklore Tech Team has introduced two new tools to enhance support for the campaign. These tools include the '''Article List Generator by Topic''' and '''CampWiz'''. The Article List Generator by Topic enables users to identify articles on the English Wikipedia that are not present in their native language Wikipedia. Users can customize their selection criteria, and the tool will present a table showcasing the missing articles along with suggested titles. Additionally, users have the option to download the list in both CSV and wikitable formats. Notably, the CampWiz tool will be employed for the project for the first time, empowering users to effectively host the project with a jury. Both tools are now available for use in the campaign. [https://tools.wikilovesfolklore.org/ '''Click here to access these tools''']
Learn more about the contest and prizes on our [[:m:Feminism and Folklore 2024|project page]]. Feel free to contact us on our [[:m:Talk:Feminism and Folklore 2024/Project Page|meta talk page]] or by email us if you need any assistance.
We look forward to your immense coordination.
Thank you and Best wishes,
'''[[:m:Feminism and Folklore 2024|Feminism and Folklore 2024 International Team]]'''
::::Stay connected [[File:B&W Facebook icon.png|link=https://www.facebook.com/feminismandfolklore/|30x30px]] [[File:B&W Twitter icon.png|link=https://twitter.com/wikifolklore|30x30px]]
</div></div>
--[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 07:26, 18 januar 2024 (UTC)
== Wiki Loves Folklore is back! ==
<div lang="en" dir="ltr" class="mw-content-ltr">
{{int:please-translate}}
[[File:Wiki Loves Folklore Logo.svg|right|150px|frameless]]
Dear Wiki Community,
You are humbly invited to participate in the '''[[:c:Commons:Wiki Loves Folklore 2024|Wiki Loves Folklore 2024]]''' an international photography contest organized on Wikimedia Commons to document folklore and intangible cultural heritage from different regions, including, folk creative activities and many more. It is held every year from the '''1st till the 31st''' of March.
You can help in enriching the folklore documentation on Commons from your region by taking photos, audios, videos, and [https://commons.wikimedia.org/w/index.php?title=Special:UploadWizard&campaign=wlf_2024 submitting] them in this commons contest.
You can also [[:c:Commons:Wiki Loves Folklore 2024/Organize|organize a local contest]] in your country and support us in translating the [[:c:Commons:Wiki Loves Folklore 2024/Translations|project pages]] to help us spread the word in your native language.
Feel free to contact us on our [[:c:Commons talk:Wiki Loves Folklore 2024|project Talk page]] if you need any assistance.
'''Kind regards,'''
'''Wiki loves Folklore International Team'''
-- [[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 07:26, 18 januar 2024 (UTC)
</div></div>
<!-- Message sent by User:Tiven2240@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery/Wikipedia&oldid=23942484 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Vote on the Charter for the Universal Code of Conduct Coordinating Committee</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/wiki/Universal Code of Conduct/Coordinating Committee/Charter/Announcement - voting opens|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:wiki/Universal Code of Conduct/Coordinating Committee/Charter/Announcement - voting opens}}&language=&action=page&filter= {{int:please-translate}}]''
Hello all,
I am reaching out to you today to announce that the voting period for the [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee]] (U4C) Charter is now open. Community members may [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter/Voter_information|cast their vote and provide comments about the charter via SecurePoll]] now through '''2 February 2024'''. Those of you who voiced your opinions during the development of the [[foundation:Special:MyLanguage/Policy:Universal_Code_of_Conduct/Enforcement_guidelines|UCoC Enforcement Guidelines]] will find this process familiar.
The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|current version of the U4C Charter]] is on Meta-wiki with translations available.
Read the charter, go vote and share this note with others in your community. I can confidently say the U4C Building Committee looks forward to your participation.
On behalf of the UCoC Project team,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 18:08, 19 januar 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=25853527 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Last days to vote on the Charter for the Universal Code of Conduct Coordinating Committee</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/wiki/Universal Code of Conduct/Coordinating Committee/Charter/Announcement - voting reminder|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:wiki/Universal Code of Conduct/Coordinating Committee/Charter/Announcement - voting reminder}}&language=&action=page&filter= {{int:please-translate}}]''
Hello all,
I am reaching out to you today to remind you that the voting period for the [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee]] (U4C) charter will close on '''2 February 2024'''. Community members may [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter/Voter_information|cast their vote and provide comments about the charter via SecurePoll]]. Those of you who voiced your opinions during the development of the [[foundation:Special:MyLanguage/Policy:Universal_Code_of_Conduct/Enforcement_guidelines|UCoC Enforcement Guidelines]] will find this process familiar.
The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|current version of the U4C charter]] is on Meta-wiki with translations available.
Read the charter, go vote and share this note with others in your community. I can confidently say the U4C Building Committee looks forward to your participation.
On behalf of the UCoC Project team,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 17:00, 31 januar 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=25853527 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Announcing the results of the UCoC Coordinating Committee Charter ratification vote</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/wiki/Universal Code of Conduct/Coordinating Committee/Charter/Announcement - results|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:wiki/Universal Code of Conduct/Coordinating Committee/Charter/Announcement - results}}&language=&action=page&filter= {{int:please-translate}}]''
Dear all,
Thank you everyone for following the progress of the Universal Code of Conduct. I am writing to you today to announce the outcome of the [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter/Voter_information|ratification vote]] on the [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|Universal Code of Conduct Coordinating Committee Charter]]. 1746 contributors voted in this ratification vote with 1249 voters supporting the Charter and 420 voters not. The ratification vote process allowed for voters to provide comments about the Charter.
A report of voting statistics and a summary of voter comments will be published on Meta-wiki in the coming weeks.
Please look forward to hearing about the next steps soon.
On behalf of the UCoC Project team,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 18:23, 12 februar 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26160150 -->
== Ukraine's Cultural Diplomacy Month 2024: We are back! ==
<div lang="en" dir="ltr" class="mw-content-ltr">
[[File:UCDM 2024 general.jpg|180px|right]]
{{int:please-translate}}
Hello, dear Wikipedians!<br/>
[[:m:Special:MyLanguage/Wikimedia Ukraine|Wikimedia Ukraine]], in cooperation with the [[:en:Ministry of Foreign Affairs of Ukraine|MFA of Ukraine]] and [[:en:Ukrainian Institute|Ukrainian Institute]], has launched the forth edition of writing challenge "'''[[:m:Special:MyLanguage/Ukraine's Cultural Diplomacy Month 2024|Ukraine's Cultural Diplomacy Month]]'''", which lasts from 1st until 31st March 2024. The campaign is dedicated to famous Ukrainian artists of cinema, music, literature, architecture, design and cultural phenomena of Ukraine that are now part of world heritage. We accept contribution in every language! The most active contesters will receive prizes.<br/>
We invite you to take part and help us improve the coverage of Ukrainian culture on Wikipedia in your language! Also, we plan to set up a [[:m:CentralNotice/Request/UCDM 2024|banner]] to notify users of the possibility to participate in such a challenge! [[:m:User:ValentynNefedov (WMUA)|ValentynNefedov (WMUA)]] ([[:m:User talk:ValentynNefedov (WMUA)|talk]])
</div>
<!-- Message sent by User:ValentynNefedov (WMUA)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery/Wikipedia&oldid=26166467 -->
== <span lang="en" dir="ltr" class="mw-content-ltr"> Report of the U4C Charter ratification and U4C Call for Candidates now available</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024/Announcement – call for candidates| You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/Coordinating Committee/Election/2024/Announcement – call for candidates}}&language=&action=page&filter= {{int:please-translate}}]''
Hello all,
I am writing to you today with two important pieces of information. First, the [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter/Vote results|report of the comments from the Universal Code of Conduct Coordinating Committee (U4C) Charter ratification]] is now available. Secondly, the call for candidates for the U4C is open now through April 1, 2024.
The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. Community members are invited to submit their applications for the U4C. For more information and the responsibilities of the U4C, please [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|review the U4C Charter]].
Per the charter, there are 16 seats on the U4C: eight community-at-large seats and eight regional seats to ensure the U4C represents the diversity of the movement.
Read more and submit your application on [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024|Meta-wiki]].
On behalf of the UCoC project team,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 16:25, 5 marte 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26276337 -->
== <span lang="en" dir="ltr" class="mw-content-ltr"> Wikimedia Foundation Board of Trustees 2024 Selection</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
: ''[[m:Special:MyLanguage/Wikimedia Foundation elections/2024/Announcement/Selection announcement| You can find this message translated into additional languages on Meta-wiki.]]''
: ''<div class="plainlinks">[[m:Special:MyLanguage/Wikimedia Foundation elections/2024/Announcement/Selection announcement|{{int:interlanguage-link-mul}}]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Wikimedia Foundation elections/2024/Announcement/Selection announcement}}&language=&action=page&filter= {{int:please-translate}}]</div>''
Dear all,
This year, the term of 4 (four) Community- and Affiliate-selected Trustees on the Wikimedia Foundation Board of Trustees will come to an end [1]. The Board invites the whole movement to participate in this year’s selection process and vote to fill those seats.
The [[m:Special:MyLanguage/Wikimedia Foundation elections committee|Elections Committee]] will oversee this process with support from Foundation staff [2]. The Board Governance Committee created a Board Selection Working Group from Trustees who cannot be candidates in the 2024 community- and affiliate-selected trustee selection process composed of Dariusz Jemielniak, Nataliia Tymkiv, Esra'a Al Shafei, Kathy Collins, and Shani Evenstein Sigalov [3]. The group is tasked with providing Board oversight for the 2024 trustee selection process, and for keeping the Board informed. More details on the roles of the Elections Committee, Board, and staff are here [4].
Here are the key planned dates:
* May 2024: Call for candidates and call for questions
* June 2024: Affiliates vote to shortlist 12 candidates (no shortlisting if 15 or less candidates apply) [5]
* June-August 2024: Campaign period
* End of August / beginning of September 2024: Two-week community voting period
* October–November 2024: Background check of selected candidates
* Board's Meeting in December 2024: New trustees seated
Learn more about the 2024 selection process - including the detailed timeline, the candidacy process, the campaign rules, and the voter eligibility criteria - on [[m:Special:MyLanguage/Wikimedia Foundation elections/2024|this Meta-wiki page]], and make your plan.
'''Election Volunteers'''
Another way to be involved with the 2024 selection process is to be an Election Volunteer. Election Volunteers are a bridge between the Elections Committee and their respective community. They help ensure their community is represented and mobilize them to vote. Learn more about the program and how to join on this [[m:Special:MyLanguage/Wikimedia Foundation elections/2024/Election Volunteers|Meta-wiki page]].
Best regards,
[[m:Special:MyLanguage/User:Pundit|Dariusz Jemielniak]] (Governance Committee Chair, Board Selection Working Group)
[1] https://meta.wikimedia.org/wiki/Special:MyLanguage/Wikimedia_Foundation_elections/2021/Results#Elected
[2] https://foundation.wikimedia.org/wiki/Committee:Elections_Committee_Charter
[3] https://foundation.wikimedia.org/wiki/Minutes:2023-08-15#Governance_Committee
[4] https://meta.wikimedia.org/wiki/Wikimedia_Foundation_elections_committee/Roles
[5] Even though the ideal number is 12 candidates for 4 open seats, the shortlisting process will be triggered if there are more than 15 candidates because the 1-3 candidates that are removed might feel ostracized and it would be a lot of work for affiliates to carry out the shortlisting process to only eliminate 1-3 candidates from the candidate list.<section end="announcement-content" />
</div>
[[User:MPossoupe_(WMF)|MPossoupe_(WMF)]]19:57, 12 marte 2024 (UTC)
<!-- Message sent by User:MPossoupe (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26349432 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Your wiki will be in read-only soon</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="server-switch"/><div class="plainlinks">
[[:m:Special:MyLanguage/Tech/Server switch|Read this message in another language]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Tech%2FServer+switch&language=&action=page&filter= {{int:please-translate}}]
The [[foundation:|Wikimedia Foundation]] will switch the traffic between its data centers. This will make sure that Wikipedia and the other Wikimedia wikis can stay online even after a disaster.
All traffic will switch on '''{{#time:j xg|2024-03-20|en}}'''. The test will start at '''[https://zonestamp.toolforge.org/{{#time:U|2024-03-20T14:00|en}} {{#time:H:i e|2024-03-20T14:00}}]'''.
Unfortunately, because of some limitations in [[mw:Special:MyLanguage/Manual:What is MediaWiki?|MediaWiki]], all editing must stop while the switch is made. We apologize for this disruption, and we are working to minimize it in the future.
'''You will be able to read, but not edit, all wikis for a short period of time.'''
*You will not be able to edit for up to an hour on {{#time:l j xg Y|2024-03-20|en}}.
*If you try to edit or save during these times, you will see an error message. We hope that no edits will be lost during these minutes, but we can't guarantee it. If you see the error message, then please wait until everything is back to normal. Then you should be able to save your edit. But, we recommend that you make a copy of your changes first, just in case.
''Other effects'':
*Background jobs will be slower and some may be dropped. Red links might not be updated as quickly as normal. If you create an article that is already linked somewhere else, the link will stay red longer than usual. Some long-running scripts will have to be stopped.
* We expect the code deployments to happen as any other week. However, some case-by-case code freezes could punctually happen if the operation require them afterwards.
* [[mw:Special:MyLanguage/GitLab|GitLab]] will be unavailable for about 90 minutes.
This project may be postponed if necessary. You can [[wikitech:Switch_Datacenter|read the schedule at wikitech.wikimedia.org]]. Any changes will be announced in the schedule. There will be more notifications about this. A banner will be displayed on all wikis 30 minutes before this operation happens. '''Please share this information with your community.'''</div><section end="server-switch"/>
</div>
[[user:Trizek (WMF)|Trizek (WMF)]], 00:01, 15 marte 2024 (UTC)
<!-- Message sent by User:Trizek (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=25636619 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Vote now to select members of the first U4C</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024/Announcement – vote opens|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/Coordinating Committee/Election/2024/Announcement – vote opens}}&language=&action=page&filter= {{int:please-translate}}]''
Dear all,
I am writing to you to let you know the voting period for the Universal Code of Conduct Coordinating Committee (U4C) is open now through May 9, 2024. Read the information on the [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024|voting page on Meta-wiki]] to learn more about voting and voter eligibility.
The Universal Code of Conduct Coordinating Committee (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. Community members were invited to submit their applications for the U4C. For more information and the responsibilities of the U4C, please [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|review the U4C Charter]].
Please share this message with members of your community so they can participate as well.
On behalf of the UCoC project team,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 20:21, 25 april 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26390244 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Sign up for the language community meeting on May 31st, 16:00 UTC</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="message"/>Hello all,
The next language community meeting is scheduled in a few weeks - May 31st at 16:00 UTC. If you're interested, you can [https://www.mediawiki.org/w/index.php?title=Wikimedia_Language_engineering/Community_meetings#31_May_2024 sign up on this wiki page].
This is a participant-driven meeting, where we share language-specific updates related to various projects, collectively discuss technical issues related to language wikis, and work together to find possible solutions. For example, in the last meeting, the topics included the machine translation service (MinT) and the languages and models it currently supports, localization efforts from the Kiwix team, and technical challenges with numerical sorting in files used on Bengali Wikisource.
Do you have any ideas for topics to share technical updates related to your project? Any problems that you would like to bring for discussion during the meeting? Do you need interpretation support from English to another language? Please reach out to me at ssethi(__AT__)wikimedia.org and [[etherpad:p/language-community-meeting-may-2024|add agenda items to the document here]].
We look forward to your participation!
<section end="message"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 21:22, 14 may 2024 (UTC)
<!-- Message sent by User:SSethi (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26390244 -->
== <span lang="en" dir="ltr" class="mw-content-ltr"> Feedback invited on Procedure for Sibling Project Lifecycle</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Wikimedia Foundation Community Affairs Committee/Procedure for Sibling Project Lifecycle/Invitation for feedback (MM)|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Wikimedia Foundation Community Affairs Committee/Procedure for Sibling Project Lifecycle/Invitation for feedback (MM)}}&language=&action=page&filter= {{int:please-translate}}]''
[[File:Sibling Project Lifecycle Conversation 3.png|150px|right|link=:m:Special:MyLanguage/Wikimedia Foundation Community Affairs Committee/Procedure for Sibling Project Lifecycle]]
Dear community members,
The [[:m:Special:MyLanguage/Wikimedia Foundation Community Affairs Committee|Community Affairs Committee]] (CAC) of the [[:m:Special:MyLanguage/Wikimedia Foundation Board of Trustees|Wikimedia Foundation Board of Trustees]] invites you to give feedback on a '''[[:m:Special:MyLanguage/Wikimedia Foundation Community Affairs Committee/Procedure for Sibling Project Lifecycle|draft Procedure for Sibling Project Lifecycle]]'''. This draft Procedure outlines proposed steps and requirements for opening and closing Wikimedia Sibling Projects, and aims to ensure any newly approved projects are set up for success. This is separate from the procedures for opening or closing language versions of projects, which is handled by the [[:m:Special:MyLanguage/Language committee|Language Committee]] or [[m:Special:MyLanguage/Closing_projects_policy|closing projects policy]].
You can find the details on [[:m:Special:MyLanguage/Talk:Wikimedia Foundation Community Affairs Committee/Procedure for Sibling Project Lifecycle#Review|this page]], as well as the ways to give your feedback from today until the end of the day on '''June 23, 2024''', anywhere on Earth.
You can also share information about this with the interested project communities you work with or support, and you can also help us translate the procedure into more languages, so people can join the discussions in their own language.
On behalf of the CAC,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 02:25, 22 may 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26390244 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Announcing the first Universal Code of Conduct Coordinating Committee</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024/Announcement – results|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/Coordinating Committee/Election/2024/Announcement – results}}&language=&action=page&filter= {{int:please-translate}}]''
Hello,
The scrutineers have finished reviewing the vote results. We are following up with the results of the first [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024|Universal Code of Conduct Coordinating Committee (U4C) election]].
We are pleased to announce the following individuals as regional members of the U4C, who will fulfill a two-year term:
* North America (USA and Canada)
** –
* Northern and Western Europe
** [[m:Special:MyLanguage/User:Ghilt|Ghilt]]
* Latin America and Caribbean
** –
* Central and East Europe (CEE)
** —
* Sub-Saharan Africa
** –
* Middle East and North Africa
** [[m:Special:MyLanguage/User:Ibrahim.ID|Ibrahim.ID]]
* East, South East Asia and Pacific (ESEAP)
** [[m:Special:MyLanguage/User:0xDeadbeef|0xDeadbeef]]
* South Asia
** –
The following individuals are elected to be community-at-large members of the U4C, fulfilling a one-year term:
* [[m:Special:MyLanguage/User:Barkeep49|Barkeep49]]
* [[m:Special:MyLanguage/User:Superpes15|Superpes15]]
* [[m:Special:MyLanguage/User:Civvì|Civvì]]
* [[m:Special:MyLanguage/User:Luke081515|Luke081515]]
* –
* –
* –
* –
Thank you again to everyone who participated in this process and much appreciation to the candidates for your leadership and dedication to the Wikimedia movement and community.
Over the next few weeks, the U4C will begin meeting and planning the 2024-25 year in supporting the implementation and review of the UCoC and Enforcement Guidelines. Follow their work on [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Meta-wiki]].
On behalf of the UCoC project team,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 08:14, 3 junio 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26390244 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">The final text of the Wikimedia Movement Charter is now on Meta</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Movement Charter/Drafting Committee/Announcement - Final draft available|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Movement Charter/Drafting Committee/Announcement - Final draft available}}&language=&action=page&filter= {{int:please-translate}}]''
Hi everyone,
The final text of the [[m:Special:MyLanguage/Movement Charter|Wikimedia Movement Charter]] is now up on Meta in more than 20 languages for your reading.
'''What is the Wikimedia Movement Charter?'''
The Wikimedia Movement Charter is a proposed document to define roles and responsibilities for all the members and entities of the Wikimedia movement, including the creation of a new body – the Global Council – for movement governance.
'''Join the Wikimedia Movement Charter “Launch Party”'''
Join the [[m:Special:MyLanguage/Event:Movement Charter Launch Party|“Launch Party”]] on '''June 20, 2024''' at '''14.00-15.00 UTC''' ([https://zonestamp.toolforge.org/1718892000 your local time]). During this call, we will celebrate the release of the final Charter and present the content of the Charter. Join and learn about the Charter before casting your vote.
'''Movement Charter ratification vote'''
Voting will commence on SecurePoll on '''June 25, 2024''' at '''00:01 UTC''' and will conclude on '''July 9, 2024''' at '''23:59 UTC.''' You can read more about the [[m:Special:MyLanguage/Movement Charter/Ratification/Voting|voting process, eligibility criteria, and other details]] on Meta.
If you have any questions, please leave a comment on the [[m:Special:MyLanguage/Talk:Movement Charter|Meta talk page]] or email the MCDC at [mailto:mcdc@wikimedia.org mcdc@wikimedia.org].
On behalf of the MCDC,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 08:44, 11 junio 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26390244 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Voting to ratify the Wikimedia Movement Charter is now open – cast your vote</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Movement Charter/Drafting Committee/Announcement - Ratification vote opens|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Movement Charter/Drafting Committee/Announcement - Ratification vote opens}}&language=&action=page&filter= {{int:please-translate}}]''
Hello everyone,
The voting to ratify the [[m:Special:MyLanguage/Movement Charter|'''Wikimedia Movement Charter''']] is now open. The Wikimedia Movement Charter is a document to define roles and responsibilities for all the members and entities of the Wikimedia movement, including the creation of a new body – the Global Council – for movement governance.
The final version of the Wikimedia Movement Charter is [[m:Special:MyLanguage/Movement Charter|available on Meta in different languages]] and attached [https://commons.wikimedia.org/wiki/File:Wikimedia_Movement_Charter_(June_2024).pdf here in PDF format] for your reading.
Voting commenced on SecurePoll on '''June 25, 2024''' at '''00:01 UTC''' and will conclude on '''July 9, 2024''' at '''23:59 UTC'''. Please read more on the [[m:Special:MyLanguage/Movement Charter/Ratification/Voting|voter information and eligibility details]].
After reading the Charter, please [[Special:SecurePoll/vote/398|'''vote here''']] and share this note further.
If you have any questions about the ratification vote, please contact the Charter Electoral Commission at [mailto:cec@wikimedia.org '''cec@wikimedia.org'''].
On behalf of the CEC,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 10:51, 25 junio 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26989444 -->
== Plans to enable the Content and Section translation tool in your Wikipedia ==
{{Int:Hello}} Interlingue Wikipedians!
Apologies, as this message is not in your native language; {{Int:Please-translate}}.
The [[mediawikiwiki:Wikimedia_Language_engineering|WMF Language team]] proposes to enable the Section and Content translation tool by default to your Wikipedia if there are no objections from members of your community. The [[mediawikiwiki:Content_translation/Section_translation|Section Translation]] extends the capabilities of [[mediawikiwiki:Content_translation|Content Translation]] to support mobile devices. Below is background information about the tools and how to test the Section translation tool.
'''Background information'''
[[mediawikiwiki:Content_translation|Content Translation]] has been a successful tool for editors to create content in their language. More than one million articles have been created across all languages since the tool was released in 2015. However, the tool is not out of beta in Interlingue Wikipedia, limiting the discoverability of the tool and its use and blocking the enablement of the Section translation in your Wikipedia.
[[mediawikiwiki:Content_translation/Section_translation|Section Translation]] extends the capabilities of Content Translation to support mobile devices. On mobile, the tool will:
* Guide you to translate one section at a time to expand existing articles or create new ones
* Make it easy to transfer knowledge across languages anytime from your mobile device
So, we will enable the tools on Interlingue Wikipedia by July 11th, 2024, if there are no objections from your community.
'''Try the Section translation tool'''
Before the enablement, you can try the current implementation of the tool in [https://test.m.wikipedia.org/w/index.php?title=Special:ContentTranslation&from=en&to=ie&sx=true#/ our testing instance]. Once it is enabled in your Wikipedia, you’ll have access to https://ie.wikipedia.org/wiki/Special:ContentTranslation with your mobile device. You can select an article and translate it from scratch. Currently, there is no machine translation support for your Wikipedia. Often, this is due to the lack of parallel data to train translation models for your language. Considering that making translations of Wikipedia articles is [[mediawikiwiki:Content_translation/Published_translations#Parallel_corpora|a way to generate such parallel corpora]], we consider that enabling these tools by default for visibility and more use can benefit your language.
'''Request for feedback'''
Please provide feedback about the Section translation in this thread or on [[mediawikiwiki:Talk:Content_translation|this project talk page]]. We want to hear about your impressions on
* The section translation tool
* What do you think about our plans to enable it
* Your ideas for improving the tool
Thanks, and we look forward to your feedback and questions.
On behalf of the WMF Language team. [[Usator:UOzurumba (WMF)|UOzurumba (WMF)]] ([[Usator Discussion:UOzurumba (WMF)|discussion]]) 21:20, 27 junio 2024 (UTC)
== <span lang="en" dir="ltr" class="mw-content-ltr">Voting to ratify the Wikimedia Movement Charter is ending soon</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Movement Charter/Drafting Committee/Announcement - Final reminder|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Movement Charter/Drafting Committee/Announcement - Final reminder}}&language=&action=page&filter= {{int:please-translate}}]''
Hello everyone,
This is a kind reminder that the voting period to ratify the [[m:Special:MyLanguage/Movement Charter|Wikimedia Movement Charter]] will be closed on '''July 9, 2024''', at '''23:59 UTC'''.
If you have not voted yet, please vote [[m:Special:SecurePoll/vote/398|on SecurePoll]].
On behalf of the [[m:Special:MyLanguage/Movement_Charter/Ratification/Voting#Electoral_Commission|Charter Electoral Commission]],<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 03:45, 8 julí 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26989444 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">U4C Special Election - Call for Candidates</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election/Announcement – call for candidates|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election/Announcement – call for candidates}}&language=&action=page&filter= {{int:please-translate}}]''
Hello all,
A special election has been called to fill additional vacancies on the U4C. The call for candidates phase is open from now through July 19, 2024.
The [[:m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the [[:foundation:Wikimedia Foundation Universal Code of Conduct|UCoC]]. Community members are invited to submit their applications in the special election for the U4C. For more information and the responsibilities of the U4C, please review the [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|U4C Charter]].
In this special election, according to [[Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter#2. Elections and Terms|chapter 2 of the U4C charter]], there are 9 seats available on the U4C: '''four''' community-at-large seats and '''five''' regional seats to ensure the U4C represents the diversity of the movement. [[Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter#5. Glossary|No more than two members of the U4C can be elected from the same home wiki]]. Therefore, candidates must not have English Wikipedia, German Wikipedia, or Italian Wikipedia as their home wiki.
Read more and submit your application on [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election|Meta-wiki]].
In cooperation with the U4C,<section end="announcement-content" />
</div>
-- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 00:03, 10 julí 2024 (UTC)
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26989444 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Wikimedia Movement Charter ratification voting results</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Movement Charter/Drafting Committee/Announcement - Results of the ratification vote|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Movement Charter/Drafting Committee/Announcement - Results of the ratification vote}}&language=&action=page&filter= {{int:please-translate}}]''
Hello everyone,
After carefully tallying both individual and affiliate votes, the [[m:Special:MyLanguage/Movement Charter/Ratification/Voting#Electoral Commission|Charter Electoral Commission]] is pleased to announce the final results of the Wikimedia Movement Charter voting.
As [[m:Special:MyLanguage/Talk:Movement Charter#Thank you for your participation in the Movement Charter ratification vote!|communicated]] by the Charter Electoral Commission, we reached the quorum for both Affiliate and individual votes by the time the vote closed on '''July 9, 23:59 UTC'''. We thank all 2,451 individuals and 129 Affiliate representatives who voted in the ratification process. Your votes and comments are invaluable for the future steps in Movement Strategy.
The final results of the [[m:Special:MyLanguage/Movement Charter|Wikimedia Movement Charter]] ratification voting held between 25 June and 9 July 2024 are as follows:
'''Individual vote:'''
Out of 2,451 individuals who voted as of July 9 23:59 (UTC), 2,446 have been accepted as valid votes. Among these, '''1,710''' voted “yes”; '''623''' voted “no”; and '''113''' selected “–” (neutral). Because the neutral votes don’t count towards the total number of votes cast, 73.30% voted to approve the Charter (1710/2333), while 26.70% voted to reject the Charter (623/2333).
'''Affiliates vote:'''
Out of 129 Affiliates designated voters who voted as of July 9 23:59 (UTC), 129 votes are confirmed as valid votes. Among these, '''93''' voted “yes”; '''18''' voted “no”; and '''18''' selected “–” (neutral). Because the neutral votes don’t count towards the total number of votes cast, 83.78% voted to approve the Charter (93/111), while 16.22% voted to reject the Charter (18/111).
'''Board of Trustees of the Wikimedia Foundation:'''
The Wikimedia Foundation Board of Trustees voted '''not to ratify''' the proposed Charter during their special Board meeting on July 8, 2024. The Chair of the Wikimedia Foundation Board of Trustees, Nataliia Tymkiv, [[m:Special:MyLanguage/Wikimedia_Foundation_Board_noticeboard/Board_resolution_and_vote_on_the_proposed_Movement_Charter|shared the result of the vote, the resolution, meeting minutes and proposed next steps]].
With this, the Wikimedia Movement Charter in its current revision is '''not ratified'''.
We thank you for your participation in this important moment in our movement’s governance.
The Charter Electoral Commission,
[[m:User:Abhinav619|Abhinav619]], [[m:User:Borschts|Borschts]], [[m:User:Iwuala Lucy|Iwuala Lucy]], [[m:User:Tochiprecious|Tochiprecious]], [[m:User:Der-Wir-Ing|Der-Wir-Ing]]<section end="announcement-content" />
</div>
[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 17:52, 18 julí 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26989444 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Vote now to fill vacancies of the first U4C</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election/Announcement – voting opens|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election/Announcement – voting opens}}&language=&action=page&filter= {{int:please-translate}}]''
Dear all,
I am writing to you to let you know the voting period for the Universal Code of Conduct Coordinating Committee (U4C) is open now through '''August 10, 2024'''. Read the information on the [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election|voting page on Meta-wiki]] to learn more about voting and voter eligibility.
The Universal Code of Conduct Coordinating Committee (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. Community members were invited to submit their applications for the U4C. For more information and the responsibilities of the U4C, please [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|review the U4C Charter]].
Please share this message with members of your community so they can participate as well.
In cooperation with the U4C,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 02:46, 27 julí 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=26989444 -->
== <span lang="en" dir="ltr" class="mw-content-ltr">Reminder! Vote closing soon to fill vacancies of the first U4C</span> ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election/Announcement – reminder to vote|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election/Announcement – reminder to vote}}&language=&action=page&filter= {{int:please-translate}}]''
Dear all,
The voting period for the Universal Code of Conduct Coordinating Committee (U4C) is closing soon. It is open through 10 August 2024. Read the information on [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2024_Special_Election#Voting|the voting page on Meta-wiki to learn more about voting and voter eligibility]]. If you are eligible to vote and have not voted in this special election, it is important that you vote now.
'''Why should you vote?''' The U4C is a global group dedicated to providing an equitable and consistent implementation of the UCoC. Community input into the committee membership is critical to the success of the UCoC.
Please share this message with members of your community so they can participate as well.
In cooperation with the U4C,<section end="announcement-content" />
</div>
-- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 15:30, 6 august 2024 (UTC)
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=27183190 -->
== <span lang="en" dir="ltr">Coming soon: A new sub-referencing feature – try it!</span> ==
<div lang="en" dir="ltr">
<section begin="Sub-referencing"/>
[[File:Sub-referencing reuse visual.png|{{#ifeq:{{#dir}}|ltr|right|left}}|400px]]
Hello. For many years, community members have requested an easy way to re-use references with different details. Now, a MediaWiki solution is coming: The new sub-referencing feature will work for wikitext and Visual Editor and will enhance the existing reference system. You can continue to use different ways of referencing, but you will probably encounter sub-references in articles written by other users. More information on [[m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing|the project page]].
'''We want your feedback''' to make sure this feature works well for you:
* [[m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing#Test|Please try]] the current state of development on beta wiki and [[m:Talk:WMDE Technical Wishes/Sub-referencing|let us know what you think]].
* [[m:WMDE Technical Wishes/Sub-referencing/Sign-up|Sign up here]] to get updates and/or invites to participate in user research activities.
[[m:Special:MyLanguage/Wikimedia Deutschland|Wikimedia Deutschland]]’s [[m:Special:MyLanguage/WMDE Technical Wishes|Technical Wishes]] team is planning to bring this feature to Wikimedia wikis later this year. We will reach out to creators/maintainers of tools and templates related to references beforehand.
Please help us spread the message. --[[m:User:Johannes Richter (WMDE)|Johannes Richter (WMDE)]] ([[m:User talk:Johannes Richter (WMDE)|talk]]) 10:36, 19 August 2024 (UTC)
<section end="Sub-referencing"/>
</div>
<!-- Message sent by User:Johannes Richter (WMDE)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Johannes_Richter_(WMDE)/Sub-referencing/massmessage_list&oldid=27309345 -->
== Sign up for the language community meeting on August 30th, 15:00 UTC ==
Hi all,
The next language community meeting is scheduled in a few weeks—on August 30th at 15:00 UTC. If you're interested in joining, you can [https://www.mediawiki.org/wiki/Wikimedia_Language_and_Product_Localization/Community_meetings#30_August_2024 sign up on this wiki page].
This participant-driven meeting will focus on sharing language-specific updates related to various projects, discussing technical issues related to language wikis, and working together to find possible solutions. For example, in the last meeting, topics included the Language Converter, the state of language research, updates on the Incubator conversations, and technical challenges around external links not working with special characters on Bengali sites.
Do you have any ideas for topics to share technical updates or discuss challenges? Please add agenda items to the document [https://etherpad.wikimedia.org/p/language-community-meeting-aug-2024 here] and reach out to ssethi(__AT__)wikimedia.org. We look forward to your participation!
[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 23:19, 22 august 2024 (UTC)
<!-- Message sent by User:SSethi (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=27183190 -->
== <span lang="en" dir="ltr">Announcing the Universal Code of Conduct Coordinating Committee</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
:''[https://lists.wikimedia.org/hyperkitty/list/board-elections@lists.wikimedia.org/thread/OKCCN2CANIH2K7DXJOL2GPVDFWL27R7C/ Original message at wikimedia-l]. [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election/Announcement - results|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election/Announcement - results}}&language=&action=page&filter= {{int:please-translate}}]''
Hello all,
The scrutineers have finished reviewing the vote and the [[m:Special:MyLanguage/Elections Committee|Elections Committee]] have certified the [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election/Results|results]] for the [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024 Special Election|Universal Code of Conduct Coordinating Committee (U4C) special election]].
I am pleased to announce the following individual as regional members of the U4C, who will fulfill a term until 15 June 2026:
* North America (USA and Canada)
** Ajraddatz
The following seats were not filled during this special election:
* Latin America and Caribbean
* Central and East Europe (CEE)
* Sub-Saharan Africa
* South Asia
* The four remaining Community-At-Large seats
Thank you again to everyone who participated in this process and much appreciation to the candidates for your leadership and dedication to the Wikimedia movement and community.
Over the next few weeks, the U4C will begin meeting and planning the 2024-25 year in supporting the implementation and review of the UCoC and Enforcement Guidelines. You can follow their work on [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Meta-Wiki]].
On behalf of the U4C and the Elections Committee,<section end="announcement-content" />
</div>
[[m:User:RamzyM (WMF)|RamzyM (WMF)]] 14:05, 2 septembre 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=27183190 -->
== <span lang="en" dir="ltr">Have your say: Vote for the 2024 Board of Trustees!</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
Hello all,
The voting period for the [[m:Special:MyLanguage/Wikimedia Foundation elections/2024|2024 Board of Trustees election]] is now open. There are twelve (12) candidates running for four (4) seats on the Board.
Learn more about the candidates by [[m:Special:MyLanguage/Wikimedia Foundation elections/2024/Candidates|reading their statements]] and their [[m:Special:MyLanguage/Wikimedia_Foundation_elections/2024/Questions_for_candidates|answers to community questions]].
When you are ready, go to the [[Special:SecurePoll/vote/400|SecurePoll]] voting page to vote. '''The vote is open from September 3rd at 00:00 UTC to September 17th at 23:59 UTC'''.
To check your voter eligibility, please visit the [[m:Special:MyLanguage/Wikimedia_Foundation_elections/2024/Voter_eligibility_guidelines|voter eligibility page]].
Best regards,
The Elections Committee and Board Selection Working Group<section end="announcement-content" />
</div>
[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 12:14, 3 septembre 2024 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=27183190 -->
== <span lang="en" dir="ltr">Your wiki will be in read-only soon</span> ==
<div lang="en" dir="ltr">
<section begin="server-switch"/><div class="plainlinks">
[[:m:Special:MyLanguage/Tech/Server switch|Read this message in another language]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Tech%2FServer+switch&language=&action=page&filter= {{int:please-translate}}]
The [[foundation:|Wikimedia Foundation]] will switch the traffic between its data centers. This will make sure that Wikipedia and the other Wikimedia wikis can stay online even after a disaster.
All traffic will switch on '''{{#time:j xg|2024-09-25|en}}'''. The switch will start at '''[https://zonestamp.toolforge.org/{{#time:U|2024-09-25T15:00|en}} {{#time:H:i e|2024-09-25T15:00}}]'''.
Unfortunately, because of some limitations in [[mw:Special:MyLanguage/Manual:What is MediaWiki?|MediaWiki]], all editing must stop while the switch is made. We apologize for this disruption, and we are working to minimize it in the future.
A banner will be displayed on all wikis 30 minutes before this operation happens. This banner will remain visible until the end of the operation.
'''You will be able to read, but not edit, all wikis for a short period of time.'''
*You will not be able to edit for up to an hour on {{#time:l j xg Y|2024-09-25|en}}.
*If you try to edit or save during these times, you will see an error message. We hope that no edits will be lost during these minutes, but we can't guarantee it. If you see the error message, then please wait until everything is back to normal. Then you should be able to save your edit. But, we recommend that you make a copy of your changes first, just in case.
''Other effects'':
*Background jobs will be slower and some may be dropped. Red links might not be updated as quickly as normal. If you create an article that is already linked somewhere else, the link will stay red longer than usual. Some long-running scripts will have to be stopped.
* We expect the code deployments to happen as any other week. However, some case-by-case code freezes could punctually happen if the operation require them afterwards.
* [[mw:Special:MyLanguage/GitLab|GitLab]] will be unavailable for about 90 minutes.
This project may be postponed if necessary. You can [[wikitech:Switch_Datacenter|read the schedule at wikitech.wikimedia.org]]. Any changes will be announced in the schedule.
'''Please share this information with your community.'''</div><section end="server-switch"/>
</div>
[[User:Trizek_(WMF)|Trizek_(WMF)]], 09:37, 20 septembre 2024 (UTC)
<!-- Message sent by User:Trizek (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=27248326 -->
== 'Wikidata item' link is moving. Find out where... ==
<div lang="en" dir="ltr" class="mw-content-ltr"><i>Apologies for cross-posting in English. Please consider translating this message.</i>{{tracked|T66315}}
Hello everyone, a small change will soon be coming to the user-interface of your Wikimedia project.
The [[d:Q16222597|Wikidata item]] [[w:|sitelink]] currently found under the <span style="color: #54595d;"><u>''General''</u></span> section of the '''Tools''' sidebar menu will move into the <span style="color: #54595d;"><u>''In Other Projects''</u></span> section.
We would like the Wiki communities feedback so please let us know or ask questions on the [[m:Talk:Wikidata_For_Wikimedia_Projects/Projects/Move_Wikidata_item_link|Discussion page]] before we enable the change which can take place October 4 2024, circa 15:00 UTC+2.
More information can be found on [[m:Wikidata_For_Wikimedia_Projects/Projects/Move_Wikidata_item_link|the project page]].<br><br>We welcome your feedback and questions.<br> [[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 18:56, 27 septembre 2024 (UTC)
</div>
<!-- Message sent by User:Danny Benjafield (WMDE)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Danny_Benjafield_(WMDE)/MassMessage_Test_List&oldid=27524260 -->
== Invitation to Participate in Wiki Loves Ramadan Community Engagement Survey ==
Dear all,
Apologies for writing in English. Please help to translate in your language.
We are excited to announce the upcoming [[m:Wiki Loves Ramadan|Wiki Loves Ramadan]] event, a global initiative aimed at celebrating Ramadan by enriching Wikipedia and its sister projects with content related to this significant time of year. As we plan to organize this event globally, your insights and experiences are crucial in shaping the best possible participation experience for the community.
To ensure that Wiki Loves Ramadan is engaging, inclusive, and impactful, we kindly invite you to participate in our community engagement survey. Your feedback will help us understand the needs of the community, set the event's focus, and guide our strategies for organizing this global event.
Survey link: https://forms.gle/f66MuzjcPpwzVymu5
Please take a few minutes to share your thoughts. Your input will make a difference!
Thank you for being a part of our journey to make Wiki Loves Ramadan a success.
Warm regards,
User:ZI Jony 03:20, 6 octobre 2024 (UTC)
Wiki Loves Ramadan Organizing Team
<!-- Message sent by User:ZI Jony@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=27510935 -->
== Proposal to enable the "Contribute" entry point in Interlingue Wikipedia ==
{{Int:Hello}} Interlingue Wikipedians,
Apologies as this message is not in your language. {{Int:please-translate}}.
The [[mediawikiwiki:Wikimedia_Language_and_Product_Localization|WMF Language and Product Localization]] team proposes enabling an entry point called "Contribute" to your Wikipedia.
The [[:bn:বিশেষ:Contribute|Contribute]] entry point is based on collaborative work with other product teams in the Wikimedia Foundation on [[mediawikiwiki:Edit_Discovery|Edit discovery]], which validated the entry point as a persistent and constant path that contributors took to discover ways to contribute content in Wikipedia.
Therefore, enabling this entry point in your Wikipedia will help contributors quickly discover available tools and immediately click to start using them. This entry point is designed to be a central point for discovering contribution tools in Interlingue Wikipedia.
'''Who can access it'''
Once it is enabled in your Wikipedia, newcomers can access the entry point automatically by just logging into their account, click on the User drop-down menu and choose the "Contribute" icon, which takes you to another menu where you will find a self-guided description of what you can do to contribute content, as shown in the image below. An option to "view contributions" is also available to access the list of your contributions.
[[File:Mobile_Contribute_Page.png|Mobile Contribute Page]] [[File:Mobile_contribute_menu_(detailed).png|Mobile contribute menu (detailed)]]
For experienced contributors, the Contribute icon is not automatically shown in their User drop-down menu. They will still see the "Contributions" option unless they change it to the "Contribute" manually.
This feature is available in four Wikipedia (Albanian, Malayalam, Mongolian, and Tagalog). We have gotten valuable feedback that helped us improve its discoverability. Now, it is ready to be enabled in other Wikis. One major improvement was to [[phab:T369041|make the entry point optional for experienced contributors]] who still want to have the "Contributions" entry point as default.
We plan to enable it '''on mobile''' for Wikis, where the Section translation tool is enabled. In this way, we will provide a main entry point to the mobile translation dashboard, and the exposure can still be limited by targeting only the mobile platform for now. If there are no objections to having the entry point for mobile users from your community, we will enable it by 24th October 2024.
We welcome your feedback and questions in this thread on our proposal to enable it here. Suppose there are no objections, we will deploy the "Contribute" entry point in your Wikipedia.
We look forward to your response soon.
Thank you!
On behalf of the WMF Language and Product Localization team. [[Usator:UOzurumba (WMF)|UOzurumba (WMF)]] ([[Usator Discussion:UOzurumba (WMF)|discussion]]) 23:40, 10 octobre 2024 (UTC)
== <span lang="en" dir="ltr">Preliminary results of the 2024 Wikimedia Foundation Board of Trustees elections</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
Hello all,
Thank you to everyone who participated in the [[m:Special:MyLanguage/Wikimedia Foundation elections/2024|2024 Wikimedia Foundation Board of Trustees election]]. Close to 6000 community members from more than 180 wiki projects have voted.
The following four candidates were the most voted:
# [[User:Kritzolina|Christel Steigenberger]]
# [[User:Nadzik|Maciej Artur Nadzikiewicz]]
# [[User:Victoria|Victoria Doronina]]
# [[User:Laurentius|Lorenzo Losa]]
While these candidates have been ranked through the vote, they still need to be appointed to the Board of Trustees. They need to pass a successful background check and meet the qualifications outlined in the Bylaws. New trustees will be appointed at the next Board meeting in December 2024.
[[m:Special:MyLanguage/Wikimedia_Foundation_elections/2024/Results|Learn more about the results on Meta-Wiki.]]
Best regards,
The Elections Committee and Board Selection Working Group
<section end="announcement-content" />
</div>
[[User:MPossoupe_(WMF)|MPossoupe_(WMF)]] 08:25, 14 octobre 2024 (UTC)
<!-- Message sent by User:MPossoupe (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=27183190 -->
== <span lang="en" dir="ltr">Seeking volunteers to join several of the movement’s committees</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
Each year, typically from October through December, several of the movement’s committees seek new volunteers.
Read more about the committees on their Meta-wiki pages:
* [[m:Special:MyLanguage/Affiliations_Committee|Affiliations Committee (AffCom)]]
* [[m:Special:MyLanguage/Ombuds_commission|Ombuds commission (OC)]]
* [[m:Special:MyLanguage/Wikimedia Foundation/Legal/Community Resilience and Sustainability/Trust and Safety/Case Review Committee|Case Review Committee (CRC)]]
Applications for the committees open on 16 October 2024. Applications for the Affiliations Committee close on 18 November 2024, and applications for the Ombuds commission and the Case Review Committee close on 2 December 2024. Learn how to apply by [[m:Special:MyLanguage/Wikimedia_Foundation/Legal/Committee_appointments|visiting the appointment page on Meta-wiki]]. Post to the talk page or email [mailto:cst@wikimedia.org cst@wikimedia.org] with any questions you may have.
For the Committee Support team,
<section end="announcement-content" />
</div>
-- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 23:07, 16 octobre 2024 (UTC)
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=27601062 -->
== 'Wikidata item' link is moving, finally. ==
Hello everyone, I previously wrote on the 27th September to advise that the ''Wikidata item'' sitelink will change places in the sidebar menu, moving from the '''General''' section into the '''In Other Projects''' section. The scheduled rollout date of 04.10.2024 was delayed due to a necessary request for Mobile/MinervaNeue skin. I am happy to inform that the global rollout can now proceed and will occur later today, 22.10.2024 at 15:00 UTC-2. [[m:Talk:Wikidata_For_Wikimedia_Projects/Projects/Move_Wikidata_item_link|Please let us know]] if you notice any problems or bugs after this change. There should be no need for null-edits or purging cache for the changes to occur. Kind regards, -[[m:User:Danny Benjafield (WMDE)|Danny Benjafield (WMDE)]] 11:28, 22 octobre 2024 (UTC)
<!-- Message sent by User:Danny Benjafield (WMDE)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Danny_Benjafield_(WMDE)/MassMessage_Test_List&oldid=27535421 -->
== Final Reminder: Join us in Making Wiki Loves Ramadan Success ==
Dear all,
We’re thrilled to announce the Wiki Loves Ramadan event, a global initiative to celebrate Ramadan by enhancing Wikipedia and its sister projects with valuable content related to this special time of year. As we organize this event globally, we need your valuable input to make it a memorable experience for the community.
Last Call to Participate in Our Survey: To ensure that Wiki Loves Ramadan is inclusive and impactful, we kindly request you to complete our community engagement survey. Your feedback will shape the event’s focus and guide our organizing strategies to better meet community needs.
* Survey Link: [https://docs.google.com/forms/d/e/1FAIpQLSffN4prPtR5DRSq9nH-t1z8hG3jZFBbySrv32YoxV8KbTwxig/viewform?usp=sf_link Complete the Survey]
* Deadline: November 10, 2024
Please take a few minutes to share your thoughts. Your input will truly make a difference!
'''Volunteer Opportunity''': Join the Wiki Loves Ramadan Team! We’re seeking dedicated volunteers for key team roles essential to the success of this initiative. If you’re interested in volunteer roles, we invite you to apply.
* Application Link: [https://docs.google.com/forms/d/e/1FAIpQLSfXiox_eEDH4yJ0gxVBgtL7jPe41TINAWYtpNp1JHSk8zhdgw/viewform?usp=sf_link Apply Here]
* Application Deadline: October 31, 2024
Explore Open Positions: For a detailed list of roles and their responsibilities, please refer to the position descriptions here: [https://docs.google.com/document/d/1oy0_tilC6kow5GGf6cEuFvdFpekcubCqJlaxkxh-jT4/ Position Descriptions]
Thank you for being part of this journey. We look forward to working together to make Wiki Loves Ramadan a success!
Warm regards,<br>
The Wiki Loves Ramadan Organizing Team 05:11, 29 octobre 2024 (UTC)
<!-- Message sent by User:ZI Jony@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=27568454 -->
== Sign up for the language community meeting on November 29th, 16:00 UTC ==
Hello everyone,
The next language community meeting is coming up next week, on November 29th, at 16:00 UTC (Zonestamp! For your timezone <https://zonestamp.toolforge.org/1732896000>). If you're interested in joining, you can sign up on this wiki page: <https://www.mediawiki.org/wiki/Wikimedia_Language_and_Product_Localization/Community_meetings#29_November_2024>.
This participant-driven meeting will be organized by the Wikimedia Foundation’s Language Product Localization team and the Language Diversity Hub. There will be presentations on topics like developing language keyboards, the creation of the Moore Wikipedia, and the language support track at Wiki Indaba. We will also have members from the Wayuunaiki community joining us to share their experiences with the Incubator and as a new community within our movement. This meeting will have a Spanish interpretation.
Looking forward to seeing you at the language community meeting! Cheers, [[User:SSethi (WMF)|Srishti]] 19:54, 21 novembre 2024 (UTC)
<!-- Message sent by User:SSethi (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=27746256 -->
== Launching! Join Us for Wiki Loves Ramadan 2025! ==
Dear All,
We’re happy to announce the launch of [[m:Wiki Loves Ramadan 2025|Wiki Loves Ramadan 2025]], an annual international campaign dedicated to celebrating and preserving Islamic cultures and history through the power of Wikipedia. As an active contributor to the Local Wikipedia, you are specially invited to participate in the launch.
This year’s campaign will be launched for you to join us write, edit, and improve articles that showcase the richness and diversity of Islamic traditions, history, and culture.
* Topic: [[m:Event:Wiki Loves Ramadan 2025 Campaign Launch|Wiki Loves Ramadan 2025 Campaign Launch]]
* When: Jan 19, 2025
* Time: 16:00 Universal Time UTC and runs throughout Ramadan (starting February 25, 2025).
* Join Zoom Meeting: https://us02web.zoom.us/j/88420056597?pwd=NdrpqIhrwAVPeWB8FNb258n7qngqqo.1
* Zoom meeting hosted by [[m:Wikimedia Bangladesh|Wikimedia Bangladesh]]
To get started, visit the [[m:Wiki Loves Ramadan 2025|campaign page]] for details, resources, and guidelines: Wiki Loves Ramadan 2025.
Add [[m:Wiki Loves Ramadan 2025/Participant|your community here]], and organized Wiki Loves Ramadan 2025 in your local language.
Whether you’re a first-time editor or an experienced Wikipedian, your contributions matter. Together, we can ensure Islamic cultures and traditions are well-represented and accessible to all.
Feel free to invite your community and friends too. Kindly reach out if you have any questions or need support as you prepare to participate.
Let’s make Wiki Loves Ramadan 2025 a success!
For the [[m:Wiki Loves Ramadan 2025/Team|International Team]] 12:08, 16 januar 2025 (UTC)
<!-- Message sent by User:ZI Jony@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=27568454 -->
== Enabling Dark mode for logged-out users in this Wikipedia ==
<div lang="en" dir="ltr">
{{int:Hello}} Wikipedians,
Apologies, as this message is not written in your native language. {{Int:please-translate}}.
The [[mediawikiwiki:Reading/Web|Wikimedia Foundation Web team]] will be enabling [[mediawikiwiki:Special:MyLanguage/Reading/Web/Accessibility_for_reading|dark mode]] here on your Wikipedia by February 2025 now that pages on your wiki have passed our checks for accessibility and other quality checks. Congratulations!
The plan to enable is made possible by the diligent work of editors and other technical contributors in your community who ensured that templates, gadgets, and other parts of pages can be accessible in dark mode. Thank you all for making dark mode available for everybody!
For context, the Web team has concluded work on dark mode. If, on some wikis, the option is not yet available for logged-out users, this is likely because many pages do not yet display well in dark mode. As communities make progress on this work, we enable this feature on additional wikis once per month.
If you notice any issues after enabling dark mode, please create a page: <code>Reading/Web/Accessibility for reading/Reporting/xx.wikipedia.org</code> in MediaWiki ([[mediawikiwiki:Reading/Web/Accessibility_for_reading/Reporting|like these pages]]), and report the issue in the created page.
Thank you!
On behalf of the [[mediawikiwiki:Reading/Web|Wikimedia Foundation Web team]].
</div>
<bdi lang="en" dir="ltr">[[User:UOzurumba (WMF)|UOzurumba (WMF)]]</bdi> 22:15, 21 januar 2025 (UTC)
<!-- Message sent by User:UOzurumba (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:UOzurumba_(WMF)/sandbox_Dark_mode_deployment_list_(February_2025)&oldid=28153450 -->
== Universal Code of Conduct annual review: provide your comments on the UCoC and Enforcement Guidelines ==
<div lang="en" dir="ltr" class="mw-content-ltr">
My apologies for writing in English.
{{Int:Please-translate}}.
I am writing to you to let you know the annual review period for the Universal Code of Conduct and Enforcement Guidelines is open now. You can make suggestions for changes through 3 February 2025. This is the first step of several to be taken for the annual review.
[[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review|Read more information and find a conversation to join on the UCoC page on Meta]].
The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|you may review the U4C Charter]].
Please share this information with other members in your community wherever else might be appropriate.
-- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 01:11, 24 januar 2025 (UTC)
</div>
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=27746256 -->
== Feminism and Folklore 2025 starts soon ==
<div style="border:8px maroon ridge;padding:6px;>
[[File:Feminism and Folklore 2025 logo.svg|centre|550px|frameless]]
::<div lang="en" dir="ltr" class="mw-content-ltr">
<center>''{{int:please-translate}}''</center>
Dear Wiki Community,
You are humbly invited to organize the '''[[:m:Feminism and Folklore 2025|Feminism and Folklore 2025]]''' writing competition from February 1, 2025, to March 31, 2025 on your local Wikipedia. This year, Feminism and Folklore will focus on feminism, women's issues, and gender-focused topics for the project, with a [[:c:Commons:Wiki Loves Folklore 2025|Wiki Loves Folklore]] gender gap focus and a folk culture theme on Wikipedia.
You can help Wikipedia's coverage of folklore from your area by writing or improving articles about things like folk festivals, folk dances, folk music, women and queer folklore figures, folk game athletes, women in mythology, women warriors in folklore, witches and witch hunting, fairy tales, and more. Users can help create new articles, expand or translate from a generated list of suggested articles.
Organisers are requested to work on the following action items to sign up their communities for the project:
# Create a page for the contest on the local wiki.
# Set up a campaign on '''CampWiz''' tool.
# Create the local list and mention the timeline and local and international prizes.
# Request local admins for site notice.
# Link the local page and the CampWiz link on the [[:m:Feminism and Folklore 2025/Project Page|meta project page]].
This year, the Wiki Loves Folklore Tech Team has introduced two new tools to enhance support for the campaign. These tools include the '''Article List Generator by Topic''' and '''CampWiz'''. The Article List Generator by Topic enables users to identify articles on the English Wikipedia that are not present in their native language Wikipedia. Users can customize their selection criteria, and the tool will present a table showcasing the missing articles along with suggested titles. Additionally, users have the option to download the list in both CSV and wikitable formats. Notably, the CampWiz tool will be employed for the project for the first time, empowering users to effectively host the project with a jury. Both tools are now available for use in the campaign. [https://tools.wikilovesfolklore.org/ '''Click here to access these tools''']
Learn more about the contest and prizes on our [[:m:Feminism and Folklore 2025|project page]]. Feel free to contact us on our [[:m:Talk:Feminism and Folklore 2025/Project Page|meta talk page]] or by email us if you need any assistance.
We look forward to your immense coordination.
Thank you and Best wishes,
'''[[:m:Feminism and Folklore 2025|Feminism and Folklore 2025 International Team]]'''
::::Stay connected [[File:B&W Facebook icon.png|link=https://www.facebook.com/feminismandfolklore/|30x30px]] [[File:B&W Twitter icon.png|link=https://twitter.com/wikifolklore|30x30px]]
</div></div>
--[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 02:35, 29 januar 2025 (UTC)
== Wiki Loves Folklore is back! ==
<div lang="en" dir="ltr" class="mw-content-ltr">
{{int:please-translate}}
[[File:Wiki Loves Folklore Logo.svg|right|150px|frameless]]
Dear Wiki Community,
You are humbly invited to participate in the '''[[:c:Commons:Wiki Loves Folklore 2025|Wiki Loves Folklore 2025]]''' an international media contest organized on Wikimedia Commons to document folklore and intangible cultural heritage from different regions, including, folk creative activities and many more. It is held every year from the '''1st till the 31st''' of March.
You can help in enriching the folklore documentation on Commons from your region by taking photos, audios, videos, and [https://commons.wikimedia.org/w/index.php?title=Special:UploadWizard&campaign=wlf_2025 submitting] them in this commons contest.
You can also [[:c:Commons:Wiki Loves Folklore 2025/Organize|organize a local contest]] in your country and support us in translating the [[:c:Commons:Wiki Loves Folklore 2025/Translations|project pages]] to help us spread the word in your native language.
Feel free to contact us on our [[:c:Commons talk:Wiki Loves Folklore 2025|project Talk page]] if you need any assistance.
'''Kind regards,'''
'''Wiki loves Folklore International Team'''
--[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 02:35, 29 januar 2025 (UTC)
</div>
<!-- Message sent by User:Tiven2240@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery/Wikipedia&oldid=26503019 -->
== Reminder: first part of the annual UCoC review closes soon ==
<div lang="en" dir="ltr" class="mw-content-ltr">
My apologies for writing in English.
{{Int:Please-translate}}.
This is a reminder that the first phase of the annual review period for the Universal Code of Conduct and Enforcement Guidelines will be closing soon. You can make suggestions for changes through [[d:Q614092|the end of day]], 3 February 2025. This is the first step of several to be taken for the annual review.
[[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review|Read more information and find a conversation to join on the UCoC page on Meta]]. After review of the feedback, proposals for updated text will be published on Meta in March for another round of community review.
Please share this information with other members in your community wherever else might be appropriate.
-- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 00:48, 3 februar 2025 (UTC)
</div>
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28198931 -->
== <span lang="en" dir="ltr"> Upcoming Language Community Meeting (Feb 28th, 14:00 UTC) and Newsletter</span> ==
<div lang="en" dir="ltr">
<section begin="message"/>
Hello everyone!
[[File:WP20Symbols WIKI INCUBATOR.svg|right|frameless|150x150px|alt=An image symbolising multiple languages]]
We’re excited to announce that the next '''Language Community Meeting''' is happening soon, '''February 28th at 14:00 UTC'''! If you’d like to join, simply sign up on the '''[[mw:Wikimedia_Language_and_Product_Localization/Community_meetings#28_February_2025|wiki page]]'''.
This is a participant-driven meeting where we share updates on language-related projects, discuss technical challenges in language wikis, and collaborate on solutions. In our last meeting, we covered topics like developing language keyboards, creating the Moore Wikipedia, and updates from the language support track at Wiki Indaba.
'''Got a topic to share?''' Whether it’s a technical update from your project, a challenge you need help with, or a request for interpretation support, we’d love to hear from you! Feel free to '''reply to this message''' or add agenda items to the document '''[[etherpad:p/language-community-meeting-feb-2025|here]]'''.
Also, we wanted to highlight that the sixth edition of the Language & Internationalization newsletter (January 2025) is available here: [[:mw:Special:MyLanguage/Wikimedia Language and Product Localization/Newsletter/2025/January|Wikimedia Language and Product Localization/Newsletter/2025/January]]. This newsletter provides updates from the October–December 2024 quarter on new feature development, improvements in various language-related technical projects and support efforts, details about community meetings, and ideas for contributing to projects. To stay updated, you can subscribe to the newsletter on its wiki page: [[:mw:Wikimedia Language and Product Localization/Newsletter|Wikimedia Language and Product Localization/Newsletter]].
We look forward to your ideas and participation at the language community meeting, see you there!
<section end="message"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 08:29, 22 februar 2025 (UTC)
<!-- Message sent by User:SSethi (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28217779 -->
== Universal Code of Conduct annual review: proposed changes are available for comment ==
<div lang="en" dir="ltr" class="mw-content-ltr">
My apologies for writing in English.
{{Int:Please-translate}}.
I am writing to you to let you know that [[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review/Proposed_Changes|proposed changes]] to the [[foundation:Special:MyLanguage/Policy:Universal_Code_of_Conduct/Enforcement_guidelines|Universal Code of Conduct (UCoC) Enforcement Guidelines]] and [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|Universal Code of Conduct Coordinating Committee (U4C) Charter]] are open for review. '''[[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review/Proposed_Changes|You can provide feedback on suggested changes]]''' through the [[d:Q614092|end of day]] on Tuesday, 18 March 2025. This is the second step in the annual review process, the final step will be community voting on the proposed changes.
[[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review|Read more information and find relevant links about the process on the UCoC annual review page on Meta]].
The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|you may review the U4C Charter]].
Please share this information with other members in your community wherever else might be appropriate.
-- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] 18:51, 7 marte 2025 (UTC)
</div>
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28307738 -->
== An improved dashboard for the Content Translation tool ==
<div lang="en" dir="ltr">
{{Int:hello}} Wikipedians,
Apologies as this message is not in your language, {{Int:please-translate}}.
The [[mediawikiwiki:Special:MyLanguage/Wikimedia_Language_and_Product_Localization|Language and Product Localization team]] has improved the [https://test.wikipedia.org/w/index.php?title=Special:ContentTranslation&filter-type=automatic&filter-id=previous-edits&active-list=suggestions&from=en&to=es Content Translation dashboard] to create a consistent experience for all contributors using mobile and desktop devices. The improved translation dashboard allows all logged-in users of the tool to enjoy a consistent experience regardless of their type of device.
With a harmonized experience, logged-in desktop users now have access to the capabilities shown in the image below.
[[file:Content_Translation_new-dashboard.png|alt=|center|thumb|576x576px|Notice that in this screenshot, the new dashboard allows: Users to adjust suggestions with the "For you" and "...More" buttons to select general topics or community-created collections (like the example of Climate topic). Also, users can use translation to create new articles (as before) and expand existing articles section by section. You can see how suggestions are provided in the new dashboard in two groups ("Create new pages" and "Expand with new sections")-one for each activity.]]
[[File:Content_Translation_dashboard_on_desktop.png|alt=|center|thumb|577x577px|In the current dashboard, you will notice that you can't adjust suggestions to select topics or community-created collections. Also, you can't expand on existing articles by translating new sections.]]
We will implement [[mw:Special:MyLanguage/Content translation#Improved translation experience|this improvement]] on your wiki '''on Monday, March 17th, 2025''' and remove the current dashboard '''by May 2025'''.
Please reach out with any questions concerning the dashboard in this thread.
Thank you!
On behalf of the Language and Product Localization team.
</div>
<bdi lang="en" dir="ltr">[[User:UOzurumba (WMF)|UOzurumba (WMF)]]</bdi> 02:55, 13 marte 2025 (UTC)
<!-- Message sent by User:UOzurumba (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:UOzurumba_(WMF)/sandbox_CX_Unified_dashboard_announcement_list_1&oldid=28382282 -->
== <span lang="en" dir="ltr">Your wiki will be in read-only soon</span> ==
<div lang="en" dir="ltr">
<section begin="server-switch"/><div class="plainlinks">
[[:m:Special:MyLanguage/Tech/Server switch|Read this message in another language]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Tech%2FServer+switch&language=&action=page&filter= {{int:please-translate}}]
The [[foundation:|Wikimedia Foundation]] will switch the traffic between its data centers. This will make sure that Wikipedia and the other Wikimedia wikis can stay online even after a disaster.
All traffic will switch on '''{{#time:j xg|2025-03-19|en}}'''. The switch will start at '''[https://zonestamp.toolforge.org/{{#time:U|2025-03-19T14:00|en}} {{#time:H:i e|2025-03-19T14:00}}]'''.
Unfortunately, because of some limitations in [[mw:Special:MyLanguage/Manual:What is MediaWiki?|MediaWiki]], all editing must stop while the switch is made. We apologize for this disruption, and we are working to minimize it in the future.
A banner will be displayed on all wikis 30 minutes before this operation happens. This banner will remain visible until the end of the operation.
'''You will be able to read, but not edit, all wikis for a short period of time.'''
*You will not be able to edit for up to an hour on {{#time:l j xg Y|2025-03-19|en}}.
*If you try to edit or save during these times, you will see an error message. We hope that no edits will be lost during these minutes, but we can't guarantee it. If you see the error message, then please wait until everything is back to normal. Then you should be able to save your edit. But, we recommend that you make a copy of your changes first, just in case.
''Other effects'':
*Background jobs will be slower and some may be dropped. Red links might not be updated as quickly as normal. If you create an article that is already linked somewhere else, the link will stay red longer than usual. Some long-running scripts will have to be stopped.
* We expect the code deployments to happen as any other week. However, some case-by-case code freezes could punctually happen if the operation require them afterwards.
* [[mw:Special:MyLanguage/GitLab|GitLab]] will be unavailable for about 90 minutes.
This project may be postponed if necessary. You can [[wikitech:Switch_Datacenter|read the schedule at wikitech.wikimedia.org]]. Any changes will be announced in the schedule.
'''Please share this information with your community.'''</div><section end="server-switch"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 23:14, 14 marte 2025 (UTC)
<!-- Message sent by User:Quiddity (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=28307742 -->
== Final proposed modifications to the Universal Code of Conduct Enforcement Guidelines and U4C Charter now posted ==
<div lang="en" dir="ltr" class="mw-content-ltr">
The proposed modifications to the [[foundation:Special:MyLanguage/Policy:Universal_Code_of_Conduct/Enforcement_guidelines|Universal Code of Conduct Enforcement Guidelines]] and the U4C Charter [[m:Universal_Code_of_Conduct/Annual_review/2025/Proposed_Changes|are now on Meta-wiki for community notice]] in advance of the voting period. This final draft was developed from the previous two rounds of community review. Community members will be able to vote on these modifications starting on 17 April 2025. The vote will close on 1 May 2025, and results will be announced no later than 12 May 2025. The U4C election period, starting with a call for candidates, will open immediately following the announcement of the review results. More information will be posted on [[m:Special:MyLanguage//Universal_Code_of_Conduct/Coordinating_Committee/Election|the wiki page for the election]] soon.
Please be advised that this process will require more messages to be sent here over the next two months.
The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee (U4C)]] is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, you may [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|review the U4C Charter]].
Please share this message with members of your community so they can participate as well.
-- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User_talk:Keegan (WMF)|talk]]) 02:04, 4 april 2025 (UTC)
</div>
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28469465 -->
== Ukraine's Cultural Diplomacy Month 2025: Invitation ==
<div lang="en" dir="ltr">
[[File:UCDM 2025 general.png|180px|right]]
{{int:please-translate}}
Hello, dear Wikipedians!<br/>
[[:m:Special:MyLanguage/Wikimedia Ukraine|Wikimedia Ukraine]], in cooperation with the [[:en:Ministry of Foreign Affairs of Ukraine|MFA of Ukraine]] and [[:en:Ukrainian Institute|Ukrainian Institute]], has launched the fifth edition of writing challenge "'''[[:m:Special:MyLanguage/Ukraine's Cultural Diplomacy Month 2025|Ukraine's Cultural Diplomacy Month]]'''", which lasts from '''14th April''' until '''16th May 2025'''. The campaign is dedicated to famous Ukrainian artists of cinema, music, literature, architecture, design, and cultural phenomena of Ukraine that are now part of world heritage. We accept contributions in every language!
The most active contesters will receive prizes.
If you are interested in coordinating long-term community engagement for the campaign and becoming a local ambassador, we would love to hear from you! Please let us know your interest.
<br/>
We invite you to take part and help us improve the coverage of Ukrainian culture on Wikipedia in your language! Also, we plan to set up a [[:m:CentralNotice/Request/Ukraine's Cultural Diplomacy Month 2025|banner]] to notify users of the possibility to participate in such a challenge! [[:m:User:OlesiaLukaniuk (WMUA)|OlesiaLukaniuk (WMUA)]] ([[:m:User talk:OlesiaLukaniuk (WMUA)|talk]])
</div>
16:11, 16 april 2025 (UTC)
<!-- Message sent by User:Hide on Rosé@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:OlesiaLukaniuk_(WMUA)/list_of_wikis&oldid=28552112 -->
== Vote now on the revised UCoC Enforcement Guidelines and U4C Charter ==
<div lang="en" dir="ltr" class="mw-content-ltr">
The voting period for the revisions to the Universal Code of Conduct Enforcement Guidelines ("UCoC EG") and the UCoC's Coordinating Committee Charter is open now through the end of 1 May (UTC) ([https://zonestamp.toolforge.org/1746162000 find in your time zone]). [[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review/2025/Voter_information|Read the information on how to participate and read over the proposal before voting]] on the UCoC page on Meta-wiki.
The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee (U4C)]] is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review of the EG and Charter was planned and implemented by the U4C. Further information will be provided in the coming months about the review of the UCoC itself. For more information and the responsibilities of the U4C, you may [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|review the U4C Charter]].
Please share this message with members of your community so they can participate as well.
In cooperation with the U4C -- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User_talk:Keegan (WMF)|talk]]) 00:34, 17 april 2025 (UTC)
</div>
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28469465 -->
== Sub-referencing: User testing ==
<div lang="en" dir="ltr">
[[File:Sub-referencing reuse visual.png|400px|right]]
<small>''Apologies for writing in English, please help us by providing a translation below''</small>
Hi I’m Johannes from [[:m:Wikimedia Deutschland|Wikimedia Deutschland]]'s [[:m:WMDE Technical Wishes|Technical Wishes team]]. We are making great strides with the new [[:m:WMDE Technical Wishes/Sub-referencing|sub-referencing feature]] and we’d love to invite you to take part in two activities to help us move this work further:
#'''Try it out and share your feedback'''
#:[[:m:WMDE Technical Wishes/Sub-referencing# Test the prototype|Please try]] the updated ''wikitext'' feature [https://en.wikipedia.beta.wmflabs.org/wiki/Sub-referencing on the beta wiki] and let us know what you think, either [[:m:Talk:WMDE Technical Wishes/Sub-referencing|on our talk page]] or by [https://greatquestion.co/wikimediadeutschland/talktotechwish booking a call] with our UX researcher.
#'''Get a sneak peak and help shape the ''Visual Editor'' user designs'''
#:Help us test the new design prototypes by participating in user sessions – [https://greatquestion.co/wikimediadeutschland/gxk0taud/apply sign up here to receive an invite]. We're especially hoping to speak with people from underrepresented and diverse groups. If that's you, please consider signing up! No prior or extensive editing experience is required. User sessions will start ''May 14th''.
We plan to bring this feature to Wikimedia wikis later this year. We’ll reach out to wikis for piloting in time for deployments. Creators and maintainers of reference-related tools and templates will be contacted beforehand as well.
Thank you very much for your support and encouragement so far in helping bring this feature to life! </div> <bdi lang="en" dir="ltr">[[User:Johannes Richter (WMDE)|Johannes Richter (WMDE)]] ([[User talk:Johannes Richter (WMDE)|talk]])</bdi> 15:03, 28 april 2025 (UTC)
<!-- Message sent by User:Johannes Richter (WMDE)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Johannes_Richter_(WMDE)/Sub-referencing/massmessage_list&oldid=28628657 -->
== <span lang="en" dir="ltr">Vote on proposed modifications to the UCoC Enforcement Guidelines and U4C Charter</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
The voting period for the revisions to the Universal Code of Conduct Enforcement Guidelines and U4C Charter closes on 1 May 2025 at 23:59 UTC ([https://zonestamp.toolforge.org/1746162000 find in your time zone]). [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2025/Voter information|Read the information on how to participate and read over the proposal before voting]] on the UCoC page on Meta-wiki.
The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee (U4C)]] is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, you may [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|review the U4C Charter]].
Please share this message with members of your community in your language, as appropriate, so they can participate as well.
In cooperation with the U4C -- <section end="announcement-content" />
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
[[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 03:41, 29 april 2025 (UTC)</div>
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28618011 -->
== We will be enabling the new Charts extension on your wiki soon! ==
''(Apologies for posting in English)''
Hi all! We have good news to share regarding the ongoing problem with graphs and charts affecting all wikis that use them.
As you probably know, the [[:mw:Special:MyLanguage/Extension:Graph|old Graph extension]] was disabled in 2023 [[listarchive:list/wikitech-l@lists.wikimedia.org/thread/EWL4AGBEZEDMNNFTM4FRD4MHOU3CVESO/|due to security reasons]]. We’ve worked in these two years to find a solution that could replace the old extension, and provide a safer and better solution to users who wanted to showcase graphs and charts in their articles. We therefore developed the [[:mw:Special:MyLanguage/Extension:Chart|Charts extension]], which will be replacing the old Graph extension and potentially also the [[:mw:Extension:EasyTimeline|EasyTimeline extension]].
After successfully deploying the extension on Italian, Swedish, and Hebrew Wikipedia, as well as on MediaWiki.org, as part of a pilot phase, we are now happy to announce that we are moving forward with the next phase of deployment, which will also include your wiki.
The deployment will happen in batches, and will start from '''May 6'''. Please, consult [[:mw:Special:MyLanguage/Extension:Chart/Project#Deployment Timeline|our page on MediaWiki.org]] to discover when the new Charts extension will be deployed on your wiki. You can also [[:mw:Special:MyLanguage/Extension:Chart|consult the documentation]] about the extension on MediaWiki.org.
If you have questions, need clarifications, or just want to express your opinion about it, please refer to the [[:mw:Special:MyLanguage/Extension_talk:Chart/Project|project’s talk page on Mediawiki.org]], or ping me directly under this thread. If you encounter issues using Charts once it gets enabled on your wiki, please report it on the [[:mw:Extension_talk:Chart/Project|talk page]] or at [[phab:tag/charts|Phabricator]].
Thank you in advance! -- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) 15:07, 6 may 2025 (UTC)
<!-- Message sent by User:Sannita (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Sannita_(WMF)/Mass_sending_test&oldid=28663781 -->
== <span lang="en" dir="ltr">Call for Candidates for the Universal Code of Conduct Coordinating Committee (U4C)</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
The results of voting on the Universal Code of Conduct Enforcement Guidelines and Universal Code of Conduct Coordinating Committee (U4C) Charter is [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2025#Results|available on Meta-wiki]].
You may now [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2025/Candidates|submit your candidacy to serve on the U4C]] through 29 May 2025 at 12:00 UTC. Information about [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2025|eligibility, process, and the timeline are on Meta-wiki]]. Voting on candidates will open on 1 June 2025 and run for two weeks, closing on 15 June 2025 at 12:00 UTC.
If you have any questions, you can ask on [[m:Talk:Universal Code of Conduct/Coordinating Committee/Election/2025|the discussion page for the election]]. -- in cooperation with the U4C, </div><section end="announcement-content" />
</div>
<bdi lang="en" dir="ltr">[[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User_talk:Keegan (WMF)|discussion]])</bdi> 22:07, 15 may 2025 (UTC)
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28618011 -->
== RfC ongoing regarding Abstract Wikipedia (and your project) ==
<div lang="en" dir="ltr" class="mw-content-ltr">
''(Apologies for posting in English, if this is not your first language)''
Hello all! We opened a discussion on Meta about a very delicate issue for the development of [[:m:Special:MyLanguage/Abstract Wikipedia|Abstract Wikipedia]]: where to store the abstract content that will be developed through functions from Wikifunctions and data from Wikidata. Since some of the hypothesis involve your project, we wanted to hear your thoughts too.
We want to make the decision process clear: we do not yet know which option we want to use, which is why we are consulting here. We will take the arguments from the Wikimedia communities into account, and we want to consult with the different communities and hear arguments that will help us with the decision. The decision will be made and communicated after the consultation period by the Foundation.
You can read the various hypothesis and have your say at [[:m:Abstract Wikipedia/Location of Abstract Content|Abstract Wikipedia/Location of Abstract Content]]. Thank you in advance! -- [[User:Sannita (WMF)|Sannita (WMF)]] ([[User talk:Sannita (WMF)|<span class="signature-talk">{{int:Talkpagelinktext}}</span>]]) 15:26, 22 may 2025 (UTC)
</div>
<!-- Message sent by User:Sannita (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Sannita_(WMF)/Mass_sending_test&oldid=28768453 -->
== <span lang="en" dir="ltr">Wikimedia Foundation Board of Trustees 2025 Selection & Call for Questions</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
:''[[m:Special:MyLanguage/Wikimedia Foundation elections/2025/Announcement/Selection announcement|{{int:interlanguage-link-mul}}]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Wikimedia Foundation elections/2025/Announcement/Selection announcement}}&language=&action=page&filter= {{int:please-translate}}]''
Dear all,
This year, the term of 2 (two) Community- and Affiliate-selected Trustees on the Wikimedia Foundation Board of Trustees will come to an end [1]. The Board invites the whole movement to participate in this year’s selection process and vote to fill those seats.
The Elections Committee will oversee this process with support from Foundation staff [2]. The Governance Committee, composed of trustees who are not candidates in the 2025 community-and-affiliate-selected trustee selection process (Raju Narisetti, Shani Evenstein Sigalov, Lorenzo Losa, Kathy Collins, Victoria Doronina and Esra’a Al Shafei) [3], is tasked with providing Board oversight for the 2025 trustee selection process and for keeping the Board informed. More details on the roles of the Elections Committee, Board, and staff are here [4].
Here are the key planned dates:
* May 22 – June 5: Announcement (this communication) and call for questions period [6]
* June 17 – July 1, 2025: Call for candidates
* July 2025: If needed, affiliates vote to shortlist candidates if more than 10 apply [5]
* August 2025: Campaign period
* August – September 2025: Two-week community voting period
* October – November 2025: Background check of selected candidates
* Board’s Meeting in December 2025: New trustees seated
Learn more about the 2025 selection process - including the detailed timeline, the candidacy process, the campaign rules, and the voter eligibility criteria - on this Meta-wiki page [[m:Special:MyLanguage/Wikimedia_Foundation_elections/2025|[link]]].
'''Call for Questions'''
In each selection process, the community has the opportunity to submit questions for the Board of Trustees candidates to answer. The Election Committee selects questions from the list developed by the community for the candidates to answer. Candidates must answer all the required questions in the application in order to be eligible; otherwise their application will be disqualified. This year, the Election Committee will select 5 questions for the candidates to answer. The selected questions may be a combination of what’s been submitted from the community, if they’re alike or related. [[m:Special:MyLanguage/Wikimedia_Foundation_elections/2025/Questions_for_candidates|[link]]]
'''Election Volunteers'''
Another way to be involved with the 2025 selection process is to be an Election Volunteer. Election Volunteers are a bridge between the Elections Committee and their respective community. They help ensure their community is represented and mobilize them to vote. Learn more about the program and how to join on this Meta-wiki page [[m:Wikimedia_Foundation_elections/2025/Election_volunteers|[link].]]
Thank you!
[1] https://meta.wikimedia.org/wiki/Wikimedia_Foundation_elections/2022/Results
[2] https://foundation.wikimedia.org/wiki/Committee:Elections_Committee_Charter
[3] https://foundation.wikimedia.org/wiki/Resolution:Committee_Membership,_December_2024
[4] https://meta.wikimedia.org/wiki/Wikimedia_Foundation_elections_committee/Roles
[5] https://meta.wikimedia.org/wiki/Wikimedia_Foundation_elections/2025/FAQ
[6] https://meta.wikimedia.org/wiki/Wikimedia_Foundation_elections/2025/Questions_for_candidates
Best regards,
Victoria Doronina
Board Liaison to the Elections Committee
Governance Committee<section end="announcement-content" />
</div>
[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 03:07, 28 may 2025 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28618011 -->
== <span lang="en" dir="ltr"> Upcoming Deployment of the CampaignEvents Extension</span> ==
<div lang="en" dir="ltr">
<section begin="message"/>
Hello everyone,
''(Apologies for posting in English if English is not your first language. Please help translate to your language.)''
The Campaigns Product Team is planning a global deployment of the '''[[:mw:Help:Extension:CampaignEvents|CampaignEvents extension]]''' to all Wikipedias, including this wiki, during the '''week of June 23rd'''.
This extension is designed to help organizers plan and manage events, WikiProjects, and other on-wiki collaborations - and to make these efforts more discoverable.
The three main features of this extension are:
* '''[[:m:Event_Center/Registration|Event Registration]]''': A simple way to sign up for events on the wiki.
* '''[[:m:CampaignEvents/Collaboration_list|Collaboration List]]''': A global list of events and a local list of WikiProjects, accessible at '''[[:m:Special:AllEvents|Special:AllEvents]]'''.
* '''[[:m:Campaigns/Foundation_Product_Team/Invitation_list|Invitation Lists]]''': A tool to help organizers find editors who might want to join, based on their past contributions.
'''Note''': The extension comes with a new user right called '''"Event Organizer"''', which will be managed by administrators on this wiki. Organizer tools like Event Registration and Invitation Lists will only work if someone is granted this right. The Collaboration List is available to everyone immediately after deployment.
The extension is already live on several wikis, including '''Meta, Wikidata, English Wikipedia''', and more ( [[m:CampaignEvents/Deployment_status#Current_Deployment_Status_for_CampaignEvents_extension| See the full deployment list]])
If you have any questions, concerns, or feedback, please feel free to share them on the [[m:Talk:CampaignEvents| extension talkpage]]. We’d love to hear from you before the rollout.
Thank you! <section end="message"/>
</div>
<bdi lang="en" dir="ltr">[[User:Udehb-WMF|Udehb-WMF]] ([[User talk:Udehb-WMF|discussion]]) 16:47, 29 may 2025 (UTC)</bdi>
<!-- Message sent by User:Udehb-WMF@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Udehb-WMF/sandbox/deployment_audience&oldid=28803829 -->
== Vote now in the 2025 U4C Election ==
<div lang="en" dir="ltr" class="mw-content-ltr">
Apologies for writing in English.
{{Int:Please-translate}}
Eligible voters are asked to participate in the 2025 [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee]] election. More information–including an eligibility check, voting process information, candidate information, and a link to the vote–are available on Meta at the [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2025|2025 Election information page]]. The vote closes on 17 June 2025 at [https://zonestamp.toolforge.org/1750161600 12:00 UTC].
Please vote if your account is eligible. Results will be available by 1 July 2025. -- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 23:00, 13 junio 2025 (UTC) </div>
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28848819 -->
== <span lang="en" dir="ltr">Wikimedia Foundation Board of Trustees 2025 - Call for Candidates</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
:''<div class="plainlinks">[[m:Special:MyLanguage/Wikimedia Foundation elections/2025/Announcement/Call for candidates|{{int:interlanguage-link-mul}}]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Wikimedia Foundation elections/2025/Announcement/Call for candidates}}&language=&action=page&filter= {{int:please-translate}}]</div>
Hello all,
The [[m:Special:MyLanguage/Wikimedia Foundation elections/2025|call for candidates for the 2025 Wikimedia Foundation Board of Trustees selection is now open]] from June 17, 2025 – July 2, 2025 at 11:59 UTC [1]. The Board of Trustees oversees the Wikimedia Foundation's work, and each Trustee serves a three-year term [2]. This is a volunteer position.
This year, the Wikimedia community will vote in late August through September 2025 to fill two (2) seats on the Foundation Board. Could you – or someone you know – be a good fit to join the Wikimedia Foundation's Board of Trustees? [3]
Learn more about what it takes to stand for these leadership positions and how to submit your candidacy on [[m:Special:MyLanguage/Wikimedia Foundation elections/2025/Candidate application|this Meta-wiki page]] or encourage someone else to run in this year's election.
Best regards,
Abhishek Suryawanshi<br />
Chair of the Elections Committee
On behalf of the Elections Committee and Governance Committee
[1] https://meta.wikimedia.org/wiki/Special:MyLanguage/Wikimedia_Foundation_elections/2025/Call_for_candidates
[2] https://foundation.wikimedia.org/wiki/Legal:Bylaws#(B)_Term.
[3] https://meta.wikimedia.org/wiki/Special:MyLanguage/Wikimedia_Foundation_elections/2025/Resources_for_candidates<section end="announcement-content" />
</div>
[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 17:43, 17 junio 2025 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28866958 -->
== <span lang="en" dir="ltr">Sister Projects Task Force reviews Wikispore and Wikinews</span> ==
<div lang="en" dir="ltr">
<section begin="message"/>
Dear Wikimedia Community,
The [[m:Wikimedia Foundation Community Affairs Committee|Community Affairs Committee (CAC)]] of the Wikimedia Foundation Board of Trustees assigned [[m:Wikimedia Foundation Community Affairs Committee/Sister Projects Task Force|the Sister Projects Task Force (SPTF)]] to update and implement a procedure for assessing the lifecycle of Sister Projects – wiki [[m:Wikimedia projects|projects supported by Wikimedia Foundation (WMF)]].
A vision of relevant, accessible, and impactful free knowledge has always guided the Wikimedia Movement. As the ecosystem of Wikimedia projects continues to evolve, it is crucial that we periodically review existing projects to ensure they still align with our goals and community capacity.
Despite their noble intent, some projects may no longer effectively serve their original purpose. '''Reviewing such projects is not about giving up – it's about responsible stewardship of shared resources'''. Volunteer time, staff support, infrastructure, and community attention are finite, and the non-technical costs tend to grow significantly as our ecosystem has entered a different age of the internet than the one we were founded in. Supporting inactive projects or projects that didn't meet our ambitions can unintentionally divert these resources from areas with more potential impact.
Moreover, maintaining projects that no longer reflect the quality and reliability of the Wikimedia name stands for, involves a reputational risk. An abandoned or less reliable project affects trust in the Wikimedia movement.
Lastly, '''failing to sunset or reimagine projects that are no longer working can make it much harder to start new ones'''. When the community feels bound to every past decision – no matter how outdated – we risk stagnation. A healthy ecosystem must allow for evolution, adaptation, and, when necessary, letting go. If we create the expectation that every project must exist indefinitely, we limit our ability to experiment and innovate.
Because of this, SPTF reviewed two requests concerning the lifecycle of the Sister Projects to work through and demonstrate the review process. We chose Wikispore as a case study for a possible new Sister Project opening and Wikinews as a case study for a review of an existing project. Preliminary findings were discussed with the CAC, and a community consultation on both proposals was recommended.
=== Wikispore ===
The [[m:Wikispore|application to consider Wikispore]] was submitted in 2019. SPTF decided to review this request in more depth because rather than being concentrated on a specific topic, as most of the proposals for the new Sister Projects are, Wikispore has the potential to nurture multiple start-up Sister Projects.
After careful consideration, the SPTF has decided '''not to recommend''' Wikispore as a Wikimedia Sister Project. Considering the current activity level, the current arrangement allows '''better flexibility''' and experimentation while WMF provides core infrastructural support.
We acknowledge the initiative's potential and seek community input on what would constitute a sufficient level of activity and engagement to reconsider its status in the future.
As part of the process, we shared the decision with the Wikispore community and invited one of its leaders, Pharos, to an SPTF meeting.
Currently, we especially invite feedback on measurable criteria indicating the project's readiness, such as contributor numbers, content volume, and sustained community support. This would clarify the criteria sufficient for opening a new Sister Project, including possible future Wikispore re-application. However, the numbers will always be a guide because any number can be gamed.
=== Wikinews ===
We chose to review Wikinews among existing Sister Projects because it is the one for which we have observed the highest level of concern in multiple ways.
Since the SPTF was convened in 2023, its members have asked for the community's opinions during conferences and community calls about Sister Projects that did not fulfil their promise in the Wikimedia movement.[https://commons.wikimedia.org/wiki/File:WCNA_2024._Sister_Projects_-_opening%3F_closing%3F_merging%3F_splitting%3F.pdf <nowiki>[1]</nowiki>][https://meta.wikimedia.org/wiki/Wikimedia_Foundation_Community_Affairs_Committee/Sister_Projects_Task_Force#Wikimania_2023_session_%22Sister_Projects:_past,_present_and_the_glorious_future%22 <nowiki>[2]</nowiki>][https://meta.wikimedia.org/wiki/WikiConvention_francophone/2024/Programme/Quelle_proc%C3%A9dure_pour_ouvrir_ou_fermer_un_projet_%3F <nowiki>[3]</nowiki>] Wikinews was the leading candidate for an evaluation because people from multiple language communities proposed it. Additionally, by most measures, it is the least active Sister Project, with the greatest drop in activity over the years.
While the Language Committee routinely opens and closes language versions of the Sister Projects in small languages, there has never been a valid proposal to close Wikipedia in major languages or any project in English. This is not true for Wikinews, where there was a proposal to close English Wikinews, which gained some traction but did not result in any action[https://meta.wikimedia.org/wiki/Proposals_for_closing_projects/Closure_of_English_Wikinews <nowiki>[4]</nowiki>][https://meta.wikimedia.org/wiki/WikiConvention_francophone/2024/Programme/Quelle_proc%C3%A9dure_pour_ouvrir_ou_fermer_un_projet_%3F <nowiki>[5]</nowiki>, see section 5] as well as a draft proposal to close all languages of Wikinews[https://meta.wikimedia.org/wiki/Talk:Proposals_for_closing_projects/Archive_2#Close_Wikinews_completely,_all_languages? <nowiki>[6]</nowiki>].
[[:c:File:Sister Projects Taskforce Wikinews review 2024.pdf|Initial metrics]] compiled by WMF staff also support the community's concerns about Wikinews.
Based on this report, SPTF recommends a community reevaluation of Wikinews. We conclude that its current structure and activity levels are the lowest among the existing sister projects. SPTF also recommends pausing the opening of new language editions while the consultation runs.
SPTF brings this analysis to a discussion and welcomes discussions of alternative outcomes, including potential restructuring efforts or integration with other Wikimedia initiatives.
'''Options''' mentioned so far (which might be applied to just low-activity languages or all languages) include but are not limited to:
*Restructure how Wikinews works and is linked to other current events efforts on the projects,
*Merge the content of Wikinews into the relevant language Wikipedias, possibly in a new namespace,
*Merge content into compatibly licensed external projects,
*Archive Wikinews projects.
Your insights and perspectives are invaluable in shaping the future of these projects. We encourage all interested community members to share their thoughts on the relevant discussion pages or through other designated feedback channels.
=== Feedback and next steps ===
We'd be grateful if you want to take part in a conversation on the future of these projects and the review process. We are setting up two different project pages: [[m:Public consultation about Wikispore|Public consultation about Wikispore]] and [[m:Public consultation about Wikinews|Public consultation about Wikinews]]. Please participate between 27 June 2025 and 27 July 2025, after which we will summarize the discussion to move forward. You can write in your own language.
I will also host a community conversation 16th July Wednesday 11.00 UTC and 17th July Thursday 17.00 UTC (call links to follow shortly) and will be around at Wikimania for more discussions.
<section end="message"/>
</div>
-- [[User:Victoria|Victoria]] on behalf of the Sister Project Task Force, 20:56, 27 junio 2025 (UTC)
<!-- Message sent by User:Johan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Johan_(WMF)/Sister_project_MassMassage_on_behalf_of_Victoria/Target_list&oldid=28911188 -->
== Wikidata Item and Property labels soon displayed in Wiki Watchlist/Recent Changes ==
''(Apologies for posting in English, you can help by translating into your language)''
Hello everyone, the [[m:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Resolve_Labels|Wikidata For Wikimedia Projects]] team is excited to announce an upcoming change in how Wikidata edit changelogs are displayed in your [[Special:Watchlist|Watchlists]] and [[Special:RecentChanges|Recent Changes]] lists. If an edit is made on Wikidata that affects a page in another Wikimedia Project, the changelog will contain some information about the nature of the edit. This can include a QID (or Q-number), a PID (or P-number) and a value (which can be text, numbers, dates, or also QID or PID’s). Confused by these terms? See the [[d:Special:MyLanguage/Wikidata:Glossary|Wikidata:Glossary]] for further explanations.
The upcoming change is scheduled for '''17.07.2025''', between '''1300 - 1500 UTC'''.
The change will display the label (item name) alongside any QID or PIDs, as seen in the image below:
[[File:Apr10 edit summary on Wikidata.png|An edit sum entry on Wikidata, labels display alongside their P- and Q-no.'s]]
These changes will only be visible if you have Wikidata edits enabled in your User Preferences for Watchlists and Recent Changes, or have the active filter ‘Wikidata edits’ checkbox toggled on, directly on the Watchlist and Recent Changes pages.
Your bot and gadget may be affected! There are thousands of bots, gadgets and user-scripts and whilst we have researched potential effects to many of them, we cannot guarantee there won’t be some that are broken or affected by this change.
Further information and context about this change, including how your bot may be affected can be found on this [[m:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Resolve_Labels|project task page]]. We welcome your questions and feedback, please write to us on this dedicated [[m:Talk:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Resolve_Labels|Talk page]].
Thank you, - [[m:User:Danny_Benjafield_(WMDE)|Danny Benjafield (WMDE)]] on behalf of the Wikidata For Wikimedia Projects Team. [[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 12:45, 14 julí 2025 (UTC)
<!-- Message sent by User:Danny Benjafield (WMDE)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Danny_Benjafield_(WMDE)/MassMessage_Test_List&oldid=28981877 -->
== <span lang="en" dir="ltr">Temporary accounts will be rolled out soon</span> ==
<div lang="en" dir="ltr">
<section begin="body"/>
Hello, we are the Wikimedia Foundation [[mw:Special:MyLanguage/Product Safety and Integrity|Product Safety and Integrity]] team. We would like to announce that '''we plan to enable [[mw:Special:MyLanguage/Trust and Safety Product/Temporary Accounts|temporary accounts]] for this wiki in the week of September 1'''.
Temporary accounts are successfully live on 30 wikis, including many large ones like German, Japanese, and French. The change they bring is especially relevant to logged-out editors, who this feature is designed to protect. But it is also relevant to community members like mentors, patrollers, and admins – anyone who reverts edits, blocks users, or otherwise interacts with logged-out editors as part of keeping the wikis safe and accurate.
'''Why we are building temporary accounts'''
Our wikis should be safer to edit by default for logged-out editors. Temporary accounts allow people to continue editing the wikis without creating an account, while avoiding publicly tying their edits to their IP address. We believe this is in the best interest of our logged-out editors, who make valuable contributions to the wikis and who may later create accounts and grow our community of editors, admins, and other roles. Even though the wikis do warn logged-out editors that their IP address will be associated with their edit, many people may not understand what an IP address is, or that it could be used to connect them to other information about them in ways they might not expect.
Additionally, our moderation software and tools rely too heavily on network origin (IP addresses) to identify users and patterns of activity, especially as IP addresses themselves are becoming less stable as identifiers. Temporary accounts allow for more precise interactions with logged-out editors, including more precise blocks, and can help limit how often we unintentionally end up blocking good-faith users who use the same IP addresses as bad-faith users.
'''How temporary accounts work'''
[[File:Temporary account banner and empty talk page.png|thumb]]
Any time a logged-out user publishes an edit on this wiki, a cookie will be set in this user's browser, and a temporary account tied with this cookie will be automatically created. This account's name will follow the pattern: <code dir=ltr>~2025-12345-67</code> (a tilde, current year, a number). On pages like Recent Changes or page history, this name will be displayed. The cookie will expire 90 days after its creation. As long as it exists, all edits made from this device will be attributed to this temporary account. It will be the same account even if the IP address changes, unless the user clears their cookies or uses a different device or web browser. A record of the IP address used at the time of each edit will be stored for 90 days after the edit. However, only some logged-in users will be able to see it.
'''What does this mean for different groups of users?'''
'''For logged-out editors'''
* This increases privacy: currently, if you do not use a registered account to edit, then everybody can see the IP address for the edits you made, even after 90 days. That will no longer be possible on this wiki.
* If you use a temporary account to edit from different locations in the last 90 days (for example at home and at a coffee shop), the edit history and the IP addresses for all those locations will now be recorded together, for the same temporary account. Users who [[foundation:Special:MyLanguage/Policy:Access_to_temporary_account_IP_addresses|meet the relevant requirements]] will be able to view this data. If this creates any personal security concerns for you, please contact talktohumanrights at wikimedia.org for advice.
'''For community members interacting with logged-out editors'''
* A temporary account is uniquely linked to a device. In comparison, an IP address can be shared with different devices and people (for example, different people at school or at work might have the same IP address).
* Compared to the current situation, it will be safer to assume that a temporary user's talk page belongs to only one person, and messages left there will be read by them. As you can see in the screenshot, temporary account users will receive notifications. It will also be possible to thank them for their edits, ping them in discussions, and invite them to get more involved in the community.
'''For users who use IP address data to moderate and maintain the wiki'''
* '''For patrollers''' who track persistent abusers, investigate violations of policies, etc.: Users who [[foundation:Special:MyLanguage/Policy:Access_to_temporary_account_IP_addresses|meet the requirements]] will be able to reveal temporary users' IP addresses and all contributions made by temporary accounts from a specific IP address or range ([[Special:IPContributions]]). They will also have access to useful information about the IP addresses thanks to the [[mw:Special:MyLanguage/Trust and Safety Product/IP Info|IP Info]] feature. Many other pieces of software have been built or adjusted to work with temporary accounts, including AbuseFilter, global blocks, Global User Contributions, and more. (For information for volunteer developers on how to update the code of your tools – see the last part of the message.)
* '''For admins blocking logged-out editors''':
** It will be possible to block many abusers by just blocking their temporary accounts. A blocked person won't be able to create new temporary accounts quickly if the admin selects the [[mw:Special:MyLanguage/Autoblock|autoblock]] option.
** It will still be possible to block an IP address or IP range.
* Temporary accounts will not be retroactively applied to contributions made before the deployment. On Special:Contributions, you will be able to see existing IP user contributions, but not new contributions made by temporary accounts on that IP address. Instead, you should use Special:IPContributions for this.
'''Our requests for you, and next steps'''
* If you know of any tools, bots, gadgets etc. using data about IP addresses or being available for logged-out users, you may want to test if they work on [[testwiki:Main_Page|testwiki]] or [[test2wiki:Main_Page|test2wiki]]. If you are a volunteer developer, [[mw:Special:MyLanguage/Trust and Safety Product/Temporary Accounts/For developers|read our documentation for developers]], and in particular, the section on [[mw:Special:MyLanguage/Trust and Safety Product/Temporary Accounts/For developers#How should I update my code?|how your code might need to be updated]].
* If you want to test the temporary account experience, for example just to check what it feels like, go to testwiki or test2wiki and edit without logging in.
* Tell us if you know of any difficulties that need to be addressed. We will try to help, and if we are not able, we will consider the available options.
* Look at our [[m:Meta:Babel#Temporary_Accounts:_access_to_IP_addresses_and_next_steps|previous message]] about requirements for users without extended rights who may need access to IP addresses.
To learn more about the project, check out [[mw:Special:MyLanguage/Trust and Safety Product/Temporary Accounts/FAQ|our FAQ]] – you will find many useful answers there. You may also [[mw:Special:MyLanguage/Trust and Safety Product/Temporary Accounts/Updates|look at the updates]] (we have just posted one) and [[mw:Newsletter:Product Safety and Integrity|subscribe to our new newsletter]]. If you'd like to talk to me (Szymon) off-wiki, you will find me on Discord and Telegram. Thank you!<section end="body" />
</div>
<bdi lang="en" dir="ltr">[[m:user:NKohli (WMF)|NKohli (WMF)]], [[m:user:SGrabarczuk (WMF)|SGrabarczuk (WMF)]]</bdi> 21:36, 26 august 2025 (UTC)
<!-- Message sent by User:Quiddity (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Quiddity_(WMF)/sandbox6&oldid=29181713 -->
== <span lang="en" dir="ltr">Server switch - Your wiki will be read-only for a short time soon</span> ==
<div lang="en" dir="ltr">
<section begin="server-switch"/><div class="plainlinks">
[[:m:Special:MyLanguage/Tech/Server switch|Read this message in another language]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Tech%2FServer+switch&language=&action=page&filter= {{int:please-translate}}]
The [[foundation:|Wikimedia Foundation]] will switch the traffic between its data centers. This will make sure that Wikipedia and the other Wikimedia wikis can stay online even after a disaster.
All traffic will switch on '''{{#time:j xg|2025-09-24|en}}'''. The switch will start at '''[https://zonestamp.toolforge.org/{{#time:U|2025-09-24T15:00|en}} {{#time:H:i e|2025-09-24T15:00}}]'''.
Unfortunately, because of some limitations in [[mw:Special:MyLanguage/Manual:What is MediaWiki?|MediaWiki]], all editing must stop while the switch is made. We apologize for this disruption, and we are working to minimize it in the future.
A banner will be displayed on all wikis 30 minutes before this operation happens. This banner will remain visible until the end of the operation.
You can contribute to the [https://meta.wikimedia.org/w/index.php?title=Special%3ATranslate&group=Centralnotice-tgroup-read_only_banner&task=view&language=&filter=&action=translate translation or proofreading] of this banner text.
'''You will be able to read, but not edit, all wikis for a short period of time.'''
*You will not be able to edit for up to an hour on {{#time:l j xg Y|2025-09-24|en}}.
*If you try to edit or save during these times, you will see an error message. We hope that no edits will be lost during these minutes, but we can't guarantee it. If you see the error message, then please wait until everything is back to normal. Then you should be able to save your edit. But, we recommend that you make a copy of your changes first, just in case.
''Other effects'':
*Background jobs will be slower and some may be dropped. Red links might not be updated as quickly as normal. If you create an article that is already linked somewhere else, the link will stay red longer than usual. Some long-running scripts will have to be stopped.
* We expect the code deployments to happen as any other week. However, some case-by-case code freezes could punctually happen if the operation require them afterwards.
* [[mw:Special:MyLanguage/GitLab|GitLab]] will be unavailable for about 90 minutes.
This project may be postponed if necessary. You can [[wikitech:Switch_Datacenter|read the schedule at wikitech.wikimedia.org]]. Any changes will be announced in the schedule.
'''Please share this information with your community.'''</div><section end="server-switch"/>
</div>
<span dir=ltr>[[m:User:Trizek (WMF)|Trizek (WMF)]] ([[m:User talk:Trizek (WMF)|{{int:talk}}]])</span> 15:41, 18 septembre 2025 (UTC)
<!-- Message sent by User:Trizek (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29170715 -->
== <span lang="en" dir="ltr">Migration to Parsoid</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
<em>[[m:Special:MyLanguage/Wikimedia Foundation/Product and Technology/Parsoid Read Views/Read View Announcement|Read this in another language]]</em>
Hello everyone! I am glad to inform you that as the next step in the [[mw:Special:MyLanguage/Parsoid/Parser Unification|Parser Unification]] project, Parsoid will soon be turned on as the default article renderer on your wiki. We are gradually increasing the number of wikis using Parsoid, with the intention of making it the default wikitext parser for MediaWiki's next long-term support release. This will make our wikis more reliable and consistent for editors, readers, and tools to use, as well as making the development of future wikitext features easier.
If this disrupts your workflow, don’t worry! You can still opt out through a user preference or turn Parsoid off on the current page using the Tools submenu, as described in the [[mw:Special:MyLanguage/Help:Extension:ParserMigration|Extension:ParserMigration]] documentation.
There is [[mw:Special:MyLanguage/Parsoid/Parser_Unification/Confidence_Framework|more information about our roll-out strategy]] available, including the testing done before we turn on Parsoid for a new wiki.
To report bugs and issues, please look at our [[mw:Special:MyLanguage/Parsoid/Parser Unification/Known Issues|known issues]] documentation and if you found a new bug please create a phab ticket and tag the [[phab:project/view/5846|Content Transform Team in Phabricator]].
<section end="announcement-content" />
</div>
<bdi lang="en" dir="ltr">[[mw:User:ABreault (WMF)|Content Transform Team]]</bdi> 23:03, 18 septembre 2025 (UTC)
<!-- Message sent by User:ABreault (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Wikimedia_Foundation/Product_and_Technology/Parsoid_Read_Views/2025-09-22_Wikipedias&oldid=29294855 -->
== <span lang="en" dir="ltr">Have your say: vote for the 2025 Board of Trustees</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
Hello all,
The voting period for the [[m:Special:MyLanguage/Wikimedia Foundation elections/2025|2025 Board of Trustees election]] is now open. Candidates are running for two (2) seats on the Board.
To check your voter eligibility, please visit the [[m:Special:MyLanguage/Wikimedia Foundation elections/2025/Voter eligibility guidelines|voter eligibility page]].
Learn more about them by [[m:Special:MyLanguage/Wikimedia Foundation elections/2025/Candidates|reading their application statements and watch their candidacy videos]].
When you are ready, go to the [[m:Special:SecurePoll/vote/405|SecurePoll voting page to vote]].
'''The vote is open from October 8 at 00:00 UTC to October 22 at 23:59 UTC.'''
Best regards,
Abhishek Suryawanshi<br />Chair, Elections Committee<section end="announcement-content" />
</div>
[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 04:48, 9 octobre 2025 (UTC)
<!-- Message sent by User:RamzyM (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29360896 -->
== <span lang="en" dir="ltr">Help us decide the name of the new Abstract Wikipedia project</span> ==
<div lang="en" dir="ltr">
<section begin="function1"/>
{{int:Hello}}. Please help pick a name for the new Abstract Wikipedia wiki project. This project will be a wiki that will enable users to combine functions from [[:f:|Wikifunctions]] and data from Wikidata in order to generate natural language sentences in any supported languages. These sentences can then be used by any Wikipedia (or elsewhere).
There will be two rounds of voting, each followed by legal review of candidates, with votes beginning on 20 October and 17 November 2025. Our goal is to have a final project name selected on mid-December 2025. If you would like to participate, then '''[[m:Special:MyLanguage/Abstract Wikipedia/Abstract Wikipedia naming contest|please learn more and vote now]]''' at meta-wiki.
{{Int:Feedback-thanks-title}}
<section end="function1"/>
</div>
-- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) 11:43, 20 octobre 2025 (UTC)
<!-- Message sent by User:Sannita (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29432175 -->
== Qualmen on vell far «petitiones pri deletion»? ==
Yo ha quelcs curiositás pri qualmen on vell far un petition pri deletion. In li Wikipedia anglesi on fa to secun [[:en:Wikipedia:Deletion_process|ti-ci processu]] , e págines deveni deletet pro - por exemple - esser pri un tema ínnotabil. Quo es li processu quel on deve sequer por proposir que un págine deve esser deletet? [[Usator:Ellenor2000|Ellenor2000]] ([[Usator Discussion:Ellenor2000|discussion]]) 01:20, 25 octobre 2025 (UTC)
:On posse ci [[https://ie.wikipedia.org/wiki/Categorie:Candidates_for_speedy_deletion]] far un proposition o directmen questionar un gobalsysop [[Usator:Dorlota|Dorlota]] ([[Usator Discussion:Dorlota|discussion]]) 12:09, 25 octobre 2025 (UTC)
::Hay un processu por deletiones queles ne posse esser rápid, e queles exige un discussion por obtener li consentiment del comunité? Ti categorie es solmen por deletiones rápid (quel es descrit [[:en:Wikipedia:Speedy_deletion|ci]] in anglés). De un altri tema: Vu vole dir que ne hay administratores local ci? [[Usator:Ellenor2000|Ellenor2000]] ([[Usator Discussion:Ellenor2000|discussion]]) 12:45, 27 octobre 2025 (UTC)
:Yo pensa que hay es activ local administratores ci in ti momente. It sembla a me que noi es nu plu activ persones e noi posse electet denov les. On posse in chascun articul comensa un discussion. [[Usator:FiliadeInterlingue|FiliadeInterlingue]] ([[Usator Discussion:FiliadeInterlingue|discussion]]) 20:42, 27 octobre 2025 (UTC)
:Yo ja esset temporari administrator e yo es pront candidar denov. Li problema esset que mancat li comunitá por votar, ma noi es nu circa quin usatores, qui vota to es bon. Fórsan altri person anc have interesse devenir administrator con me. [[Usator:Dorlota|Dorlota]] ([[Usator Discussion:Dorlota|discussion]]) 10:19, 28 octobre 2025 (UTC)
== <span lang="en" dir="ltr">Seeking volunteers to join several of the movement’s committees</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
Each year, typically from October through December, several of the movement’s committees seek new volunteers.
Read more about the committees on their Meta-wiki pages:
* [[m:Special:MyLanguage/Affiliations Committee|Affiliations Committee (AffCom)]]
* [[m:Special:MyLanguage/Ombuds commission|Ombuds commission (OC)]]
* [[m:Special:MyLanguage/Wikimedia Foundation/Legal/Community Resilience and Sustainability/Trust and Safety/Case Review Committee|Case Review Committee (CRC)]]
Applications for the committees open on October 30, 2025. Applications for the Affiliations Committee, Ombuds commission and the Case Review Committee close on December 11, 2025. Learn how to apply by [[m:Special:MyLanguage/Wikimedia Foundation/Legal/Committee appointments|visiting the appointment page on Meta-wiki]]. Post to the talk page or email cst[[File:At sign.svg|16x16px|link=|(_AT_)]]wikimedia.org with any questions you may have.
For the Committee Support team,
<section end="announcement-content" />
</div>
-[[m:User:MKaur (WMF)| MKaur (WMF)]] 14:12, 30 octobre 2025 (UTC)
<!-- Message sent by User:MKaur (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29517125 -->
== <span lang="en" dir="ltr">Reminder: Help us decide the name of the new Abstract Wikipedia project</span> ==
<div lang="en" dir="ltr">
<section begin="function2"/>
{{int:Hello}}. Reminder: Please help to choose name for the new Abstract Wikipedia wiki project. The finalist vote starts today. The finalists for the name are: <span lang="en" dir="ltr" class="mw-content-ltr">Abstract Wikipedia, Multilingual Wikipedia, Wikiabstracts, Wikigenerator, Proto-Wiki</span>. If you would like to participate, then '''[[m:Special:MyLanguage/Abstract Wikipedia/Abstract Wikipedia naming contest|please learn more and vote now]]''' at meta-wiki.
{{Int:Feedback-thanks-title}}
<section end="function2"/>
</div>
-- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) 14:22, 20 novembre 2025 (UTC)
<!-- Message sent by User:Sannita (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29583860 -->
== Thank You for Last Year – Join Wiki Loves Ramadan 2026 ==
Dear Wikimedia communities,
We hope you are doing well, and we wish you a happy New Year.
''Last year, we captured light. This year, we’ll capture legacy.''
In 2025, communities around the world shared the glow of Ramadan nights and the warmth of collective iftars. In 2026, ''Wiki Loves Ramadan'' is expanding, bringing more stories, more cultures, and deeper global connections across Wikimedia projects.
We invite you to explore the ''Wiki Loves Ramadan 2026'' [[m:Special:MyLanguage/Wiki Loves Ramadan 2026|Meta page]] to learn how you can participate and [[m:Special:MyLanguage/Wiki Loves Ramadan 2026/Participating communities|sign up]] your community.
📷 ''Photo campaign on '' [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan 2026|Wikimedia Commons]]
If you have questions about the project, please refer to the FAQs:
* [[m:Special:MyLanguage/Wiki Loves Ramadan/FAQ/|Meta-Wiki]]
* [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan/FAQ|Wikimedia Commons]]
''Early registration for updates is now open via the '''[[m:Special:RegisterForEvent/2710|Event page]]'''''
''Stay connected and receive updates:''
* [https://t.me/WikiLovesRamadan Telegram channel]
* [https://lists.wikimedia.org/postorius/lists/wikilovesramadan.lists.wikimedia.org/ Mailing list]
We look forward to collaborating with you and your community.
'''The Wiki Loves Ramadan 2026 Organizing Team''' 19:45, 16 januar 2026 (UTC)
<!-- Message sent by User:ZI Jony@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29879549 -->
== Feminism and Folklore 2026 starts soon ==
<div style="border:8px maroon ridge;padding:6px;">
[[File:Feminism and Folklore 2026 logo.svg|centre|550px|frameless]]
::<div lang="en" dir="ltr" class="mw-content-ltr">
<div style="text-align: center; width: 100%;">''{{int:please-translate}}''</div>
;Invitation to Organize Feminism and Folklore 2026
Dear Wiki Community,
We are pleased to invite Wikimedia communities, affiliates, and independent contributors to organize the '''[[:m:Feminism and Folklore 2026|Feminism and Folklore 2026]]''' writing competition on your local Wikipedia.
The international campaign will run from '''1 February to 31 March 2026''' and aims to improve coverage of feminism, women’s histories, gender-related topics, and folk culture across Wikipedia projects.
;About the Campaign
'''Feminism and Folklore''' is a global writing initiative that complements the '''[[:c:Commons:Wiki Loves Folklore 2026|Wiki Loves Folklore]]''' photography competition. While Wiki Loves Folklore focuses on visual documentation, this writing campaign addresses the '''gender gap on Wikipedia''' by improving encyclopedic content related to folk culture and marginalized voices.
;What Can Participants Write About?
Communities can contribute by creating, expanding, or translating articles related to:
* Folk festivals, rituals, and celebrations
* Folk dances, music, and traditional performances
* Women and queer figures in folklore
* Women in mythology and oral traditions
* Women warriors, witches, and witch-hunting narratives
* Fairy tales, folk stories, and legends
* Folk games, sports, and cultural practices
Participants may work from curated article lists or generate new article suggestions using campaign tools.
;How to Sign Up as an Organizer
Organizers are requested to complete the following steps to register their community:
# Create a local project page on your wiki [[:m:Feminism and Folklore/Sample|(see sample)]]
# Set up the campaign using the '''CampWiz''' tool
# Prepare a local article list and clearly mention:
#* Campaign timeline
#* Local and international prizes
# Request a site notice from local administrators [[:mr:Template:SN-FNF|(see sample)]]
# Add your local project page and CampWiz link to the '''[[:m:Feminism and Folklore 2026/Project Page|Meta project page]]'''
;Campaign Tools
The Wiki Loves Folklore Tech Team has introduced tools to support organizers and participants:
* '''Article List Generator by Topic''' – Helps identify articles available on English Wikipedia but missing in your local language Wikipedia. The tool allows customized filters and provides downloadable article lists in CSV and wikitable formats.
* '''CampWiz''' – Enables communities to manage writing campaigns effectively, including jury-based evaluation. This will be the third year CampWiz is officially used for Feminism and Folklore.
Both tools are now available for use in the campaign. '''[https://tools.wikilovesfolklore.org/ Click here to access the tools]'''
;Learn More & Get Support
For detailed information about rules, timelines, and prizes, please visit the
'''[[:m:Feminism and Folklore 2026|Feminism and Folklore 2026 project page]]'''.
If you have any questions or need assistance, feel free to reach out via:
* '''[[:m:Talk:Feminism and Folklore 2026/Project Page|Meta talk page]]'''
* Email us using details on the contact page.
;Join Us
We look forward to your collaboration and coordination in making Feminism and Folklore 2026 a meaningful and impactful campaign for closing gender gaps and enriching folk culture content on Wikipedia.
Thank you and best wishes,
'''[[:m:Feminism and Folklore 2026|Feminism and Folklore 2026 International Team]]'''
----
''Stay connected:''
[[File:B&W Facebook icon.png|link=https://www.facebook.com/feminismandfolklore/|30x30px]]
[[File:B&W Twitter icon.png|link=https://twitter.com/wikifolklore|30x30px]]
</div></div>
== Invitation to Host Wiki Loves Folklore 2026 in Your Country ==
<div lang="en" dir="ltr" class="mw-content-ltr">
<div style="text-align: center; width: 100%;">''{{int:please-translate}}''</div>
[[File:Wiki Loves Folklore Logo.svg|right|150px|frameless]]
Hello everyone,
We are delighted to invite Wikimedia affiliates, user groups, and community organizations worldwide to participate in '''Wiki Loves Folklore 2026''', an international initiative dedicated to documenting and celebrating folk culture across the globe.
;About Wiki Loves Folklore
'''Wiki Loves Folklore''' is an annual international photography competition hosted on Wikimedia Commons. The campaign runs from '''1 February to 31 March 2026''' and encourages photographers, cultural enthusiasts, and community members to contribute photographs that highlight:
* Folk traditions and rituals
* Cultural festivals and celebrations
* Traditional attire and crafts
* Performing arts, music, and dance
* Everyday practices rooted in folk heritage
Through this campaign, we aim to preserve and promote diverse folk cultures and make them freely accessible to the world.
[[:c:Commons:Wiki_Loves_Folklore_2026|Project page on Wikimedia Commons]]
; Host a Local Edition
As we celebrate the '''eight edition''' of Wiki Loves Folklore, we warmly invite communities to organize a local edition in their country or region. Hosting a local campaign is a great opportunity to:
* Increase visibility of your region’s folk culture
* Engage new contributors in your community
* Enrich Wikimedia Commons with high-quality cultural content
'''[[:c:Commons:Wiki_Loves_Folklore_2026/Organize|Sign up to organize]]:'''
If your team prefers to organize the competition in ''either February or March only'', please feel free to let us know.
If you are unable to organize, we encourage you to share this opportunity with other interested groups or organizations in your region.
;Get in Touch
If you have any questions, need support, or would like to explore collaboration opportunities, please feel free to contact us via:
* The project Talk pages
* Email: '''support@wikilovesfolklore.org'''
We are also happy to connect via an online meeting if your team would like to discuss planning or coordination in more detail.
Warm regards,
'''The Wiki Loves Folklore International Team'''
</div>
[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 13:21, 18 januar 2026 (UTC)
<!-- Message sent by User:Tiven2240@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery/Wikipedia&oldid=29228188 -->
== <span lang="en" dir="ltr">Annual review of the Universal Code of Conduct and Enforcement Guidelines</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
I am writing to you to let you know the annual review period for the Universal Code of Conduct and Enforcement Guidelines is open now. You can make suggestions for changes through 9 February 2026. This is the first step of several to be taken for the annual review. [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2026|Read more information and find a conversation to join on the UCoC page on Meta]].
The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|you may review the U4C Charter]].
Please share this information with other members in your community wherever else might be appropriate.
-- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]])<section end="announcement-content" />
</div>
21:01, 19 januar 2026 (UTC)
<!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29905753 -->
== Join the sixth Ukraine’s Cultural Diplomacy Month on Wikipedia! ==
<div lang="en" dir="ltr">
[[File:Ukraine’s Cultural Diplomacy Month on Wikipedia 2026.png|right|250px|thumb|link=https://meta.wikimedia.org/wiki/Ukraine%27s_Cultural_Diplomacy_Month_2026|Join our campaign!]]
{{int:please-translate}}
Dear Wikipedians!
[[:m:Special:MyLanguage/Wikimedia Ukraine|Wikimedia Ukraine]], in cooperation with the [[:en:Ministry of Foreign Affairs of Ukraine|MFA of Ukraine]] and [[:en:Ukrainian Institute|Ukrainian Institute]], has launched the sixth edition of writing challenge "'''[[:m:Special:MyLanguage/Ukraine's Cultural Diplomacy Month 2026|Ukraine's Cultural Diplomacy Month]]'''", which lasts from '''1st April''' until '''30th April 2026'''.
The initiative aims to promote knowledge about Ukrainian culture abroad by creating and improving Wikipedia articles in multiple languages. This year marks the sixth edition of the campaign, which will focus on contemporary culture, making today’s artistic voices and practices more visible to international audiences.
🧩'''How to participate?'''
Choose an article from the suggested list → Write an article in your language, or improve an existing one according to the rules → Add your contribution to the contest page and calculate your points → Win prizes and receive a certificate of participation → Become a promoter of truthful knowledge about Ukraine.
🧩'''[[m:Special:MyLanguage/Ukraine's Cultural Diplomacy Month 2026|Check our main page for more information]]'''.
'''If you are interested in coordinating long-term community engagement for the campaign and becoming a local ambassador, we would love to hear from you! Please let us know your interest.'''
If not, then we encourage you to translate the [[m:Special:MyLanguage/Ukraine's Cultural Diplomacy Month 2026|landing page of the contest]] and [https://meta.wikimedia.org/wiki/Special:MessageGroupStats?group=Centralnotice-tgroup-UCDM2026banner&messages=&language=en&x=D banner] into your own language.
Also, we set up a [[:m:CentralNotice/Request/Ukraine's Cultural Diplomacy Month 2026|banner]] to notify users of the possibility to participate in this challenge!
[[:m:User:OlesiaLukaniuk (WMUA)|OlesiaLukaniuk (WMUA)]] ([[:m:User talk:OlesiaLukaniuk (WMUA)|talk]]) 04:35, 1 April 2026 (UTC)
</div>
<!-- Message sent by User:OlesiaLukaniuk (WMUA)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:OlesiaLukaniuk_(WMUA)/list_of_wikis&oldid=28552112 -->
== Action Required: Update templates/modules for electoral maps (Migrating from P1846 to P14226) ==
Hello everyone,
This is a notice regarding an ongoing data migration on Wikidata that may affect your election-related templates and Lua modules (such as <code>Module:Itemgroup/list</code>).
'''The Change:'''<br />
Currently, many templates pull electoral maps from Wikidata using the property [[:d:Property:P1846|P1846]], combined with the qualifier [[:d:Property:P180|P180]]: [[:d:Q19571328|Q19571328]].
We are migrating this data (across roughly 4,000 items) to a newly created, dedicated property: '''[[:d:Property:P14226|P14226]]'''.
'''What You Need To Do:'''<br />
To ensure your templates and infoboxes do not break or lose their maps, please update your local code to fetch data from [[:d:Property:P14226|P14226]] instead of the old [[:d:Property:P1846|P1846]] + [[:d:Property:P180|P180]] structure. A [[m:Wikidata/Property Migration: P1846 to P14226/List|list of pages]] was generated using Wikimedia Global Search.
'''Deadline:'''<br />
We are temporarily retaining the old data on [[:d:Property:P1846|P1846]] to allow for a smooth transition. However, to complete the data cleanup on Wikidata, the old [[:d:Property:P1846|P1846]] statements will be removed after '''May 1, 2026'''. Please update your modules and templates before this date to prevent any disruption to your wiki's election articles.
Let us know if you have any questions or need assistance with the query logic. Thank you for your help! [[User:ZI Jony|ZI Jony]] using [[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 17:11, 3 april 2026 (UTC)
<!-- Message sent by User:ZI Jony@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29941252 -->
== Request for comment (global AI policy) ==
<bdi lang="en" dir="ltr" class="mw-content-ltr">
Apologies for writing in English. {{int:Please-translate}}
A [[:m:Requests for comment/Artificial intelligence policy|request for comment]] is currently being held to decide on a global AI policy. {{int:Feedback-thanks-title}}
[[Usator:MediaWiki message delivery|MediaWiki message delivery]] ([[Usator Discussion:MediaWiki message delivery|discussion]]) 00:57, 26 april 2026 (UTC)
</bdi>
<!-- Message sent by User:Codename Noreste@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30424282 -->
rzddfxmlh5iqy9vie0p03glfy3s4xfi
Robert Schumann
0
4514
167662
136298
2026-04-25T20:53:43Z
Dorlota
13847
167662
wikitext
text/x-wiki
{{Biografie
|nómine = Robert Schumann
|foto = Robert_Schumann.jpg|thumb|upright=1.3
|land = {{DEU}}
|nascentie = 8-im de junio 1810
|nasc_loc = Zwickau
|morte = 29-im de julí 1856
|mort_loc = Bonn
|ocupation = Musico, Compositor
}}
'''Robert Schumann''' esset un famosi german compositor e pianist de musica classic.
''Robert Schumann'' nascet ye li 8-im de junio 1810 in [[Zwickau]] (Germania) e morit li 29-im de julí 1856 in [[Endenich]] (hodie un parte del cité [[Bonn]]) (Germania).
Il esset maritat con [[Clara Schumann]].
{{DEFAULTSORT:Schumann, Robert}}
[[Categorie:Germania]]
[[Categorie:Compositores]]
ijl0flv3h4dslrdw131gb14e01mdz1m
Giuseppe Verdi
0
4751
167633
159273
2026-04-25T20:24:09Z
Dorlota
13847
167633
wikitext
text/x-wiki
{{Biografie
|nómine = Giuseppe Verdi
|foto = Portrait of Giuseppe Verdi by Bice Lombardini.jpg
|land = {{ITA}}
|nascentie = 10-im de octobre 1813
|nasc_loc = Le Roncole, Italia
|morte = 27-im de januar 1901
|mort_loc = Milano, Italia
|ocupation = Musico, Compositor
}}
'''Giuseppe Verdi''' esset un framos [[Italia|italian]] [[compositor]] del [[ópera]]s in li epoca del [[romantie]].
Il nascet li 10 de octobre 1813 in [[Le Roncole]] ([[Italia]]) e morit li 27 de januar 1901 in [[Milano]] ([[Italia]]).
== Famos óperas de Verdi ==
* [[Nabucco]] (1842)
* [[Rigoletto]] (1851)
* [[La traviata]] (1853)
* [[Aida]] (1871)
* [[Otello]] (1887)
{{DEFAULTSORT: Verdi, Giuseppe}}
[[Categorie:Italianes]]
[[Categorie:Compositores]]
apwhvkyznaq9xt2kwzamvj73wy7qsjc
167634
167633
2026-04-25T20:25:46Z
Dorlota
13847
167634
wikitext
text/x-wiki
{{Biografie
|nómine = Giuseppe Verdi
|foto = Portrait of Giuseppe Verdi by Bice Lombardini.jpg
|land = {{ITA}}
|nascentie = 10-im de octobre 1813
|nasc_loc = Le Roncole, Italia
|morte = 27-im de januar 1901
|mort_loc = Milano, Italia
|ocupation = Musico, Compositor
}}
'''Giuseppe Verdi''' esset un famosi [[Italia|italian]] [[compositor]] del [[ópera]]s in li epoca del [[romantie]].
Il nascet li 10 de octobre 1813 in [[Le Roncole]] ([[Italia]]) e morit li 27 de januar 1901 in [[Milano]] ([[Italia]]).
== Famos óperas de Verdi ==
* [[Nabucco]] (1842)
* [[Rigoletto]] (1851)
* [[La traviata]] (1853)
* [[Aida]] (1871)
* [[Otello]] (1887)
{{DEFAULTSORT: Verdi, Giuseppe}}
[[Categorie:Italianes]]
[[Categorie:Compositores]]
toyeif6uskfl0bbyjdqy5227gj2ao7x
167636
167634
2026-04-25T20:30:04Z
Dorlota
13847
167636
wikitext
text/x-wiki
{{Biografie
|nómine = Giuseppe Verdi
|foto = Portrait of Giuseppe Verdi by Bice Lombardini.jpg
|land = {{ITA}}
|nascentie = 10-im de octobre 1813
|nasc_loc = Le Roncole, Italia
|morte = 27-im de januar 1901
|mort_loc = Milano, Italia
|ocupation = Musico, Compositor
}}
'''Giuseppe Verdi''' esset un famosi [[Italia|italian]] [[compositor]] del [[ópera]]s in li epoca del [[romantie]].
Il nascet li 10-im de octobre 1813 in [[Le Roncole]] ([[Italia]]) e morit li 27-im januar 1901 in [[Milano]] ([[Italia]]).
== Famos óperas de Verdi ==
* [[Nabucco]] (1842)
* [[Rigoletto]] (1851)
* [[La traviata]] (1853)
* [[Aida]] (1871)
* [[Otello]] (1887)
{{DEFAULTSORT: Verdi, Giuseppe}}
[[Categorie:Italianes]]
[[Categorie:Compositores]]
3hhoe0a7a888hrub4ui6et5tbizknb5
Felix Mendelssohn Bartholdy
0
6084
167648
165618
2026-04-25T20:44:31Z
Dorlota
13847
167648
wikitext
text/x-wiki
{{Biografie
|nómine = Felix Mendelssohn Bartholdy
|foto = Felix Mendelssohn Bartholdy by Eduard Magnus (1833).jpg
|land = {{GER}}
|nascentie = 3-im de februar 1809
|nasc_loc = Hamburg, Germania
|morte = 4-im de novembre 1847
|mort_loc = Venezia, Italia
|ocupation = Musico, Compositor, Pianist, Dirigente
}}
'''Felix Mendelssohn Bartholdy''' esset un [[Germania|german]] [[compositor]], [[pianist]]. [[chef del orchestre]] e [[organist]].
Il nascet li 3 februar 1809 in [[Hamburg]] e morit li 4 novembre 1847 in [[Leipzig]].
Mendelssohn Bartholdy creat simfonies, concertes, oratorios, piano musica e chambre-musica.
Il nascet in un judeic familia, ma esset cristanmen baptisat.
{{DEFAULTSORT:Mendelssohn Bartholdy, Felix}}
[[Categorie:Germania]]
[[Categorie:Compositores]]
6vy9x8gpjd5ovl7dzgaa917x2s3jt7u
Johann Sebastian Bach
0
6924
167663
163478
2026-04-25T20:55:53Z
Dorlota
13847
167663
wikitext
text/x-wiki
{{Biografie
|nómine = Johann Sebastian Bach
|foto = Bach.jpg|thumb|upright=1.3
|land = {{DEU}}
|nascentie = 21-im de marte 1685
|nasc_loc = Eisenach
|morte = 26-im de julí 1750
|mort_loc = Leipzig
|ocupation = Musico, Compositor
}}
'''Johann Sebastian Bach''' esset un tre famos german compositor de música classic. Il nascet ye li 21-im de marte [[1685]] in [[Eisenach]] ([[Germania]]) e morit li 26-im de julio [[1750]] in [[Leipzig]] ([[Germania]]).
{{DEFAULTSORT:Bach, Johann Sebastian}}
[[Categorie:Germanes]]
[[Categorie:Compositores]]
net9i9gekb77vv2rcjnw14y6w39o0kp
167664
167663
2026-04-25T20:56:06Z
Dorlota
13847
167664
wikitext
text/x-wiki
{{Biografie
|nómine = Johann Sebastian Bach
|foto = Bach.jpg|thumb|upright=1.3
|land = {{DEU}}
|nascentie = 21-im de marte 1685
|nasc_loc = Eisenach
|morte = 26-im de julí 1750
|mort_loc = Leipzig
|ocupation = Musico, Compositor
}}
'''Johann Sebastian Bach''' esset un tre famos german compositor de musica classic. Il nascet ye li 21-im de marte [[1685]] in [[Eisenach]] ([[Germania]]) e morit li 26-im de julio [[1750]] in [[Leipzig]] ([[Germania]]).
{{DEFAULTSORT:Bach, Johann Sebastian}}
[[Categorie:Germanes]]
[[Categorie:Compositores]]
kg9ljqrrakxfdddijhh6vn42dedo31l
167665
167664
2026-04-25T20:56:25Z
Dorlota
13847
167665
wikitext
text/x-wiki
{{Biografie
|nómine = Johann Sebastian Bach
|foto = Bach.jpg|thumb|upright=1.3
|land = {{DEU}}
|nascentie = 21-im de marte 1685
|nasc_loc = Eisenach
|morte = 26-im de julí 1750
|mort_loc = Leipzig
|ocupation = Musico, Compositor
}}
'''Johann Sebastian Bach''' esset un tre famosi german compositor de musica classic. Il nascet ye li 21-im de marte [[1685]] in [[Eisenach]] ([[Germania]]) e morit li 26-im de julio [[1750]] in [[Leipzig]] ([[Germania]]).
{{DEFAULTSORT:Bach, Johann Sebastian}}
[[Categorie:Germanes]]
[[Categorie:Compositores]]
3z2ovx81ibe09x53cdmcdlpc7xubkao
167666
167665
2026-04-25T21:00:23Z
Dorlota
13847
167666
wikitext
text/x-wiki
{{Biografie
|nómine = Johann Sebastian Bach
|foto = Bach.jpg|thumb|upright=1.3
|land = {{DEU}}
|nascentie = 21-im de marte 1685
|nasc_loc = Eisenach
|morte = 26-im de julí 1750
|mort_loc = Leipzig
|ocupation = Musico, Compositor
}}
'''Johann Sebastian Bach''' esset un tre famosi german compositor de musica classic in li epoca de [[baroc]]. Il nascet ye li 21-im de marte [[1685]] in [[Eisenach]] ([[Germania]]) e morit li 26-im de julio [[1750]] in [[Leipzig]] ([[Germania]]).
Johann Sebastian Bach ludet li [[organ]], [[cemballo]] e [[violine]]. Il esset li director del [[Thomas-Cor]] e director de musica in [[Leipzig]].
==Ovres==
Li max famosi ovre de Johann Sebastian Bach es li [[Concertes de Brandenburgia]].
{{DEFAULTSORT:Bach, Johann Sebastian}}
[[Categorie:Germanes]]
[[Categorie:Compositores]]
pw53dv96b2xm8aahzaby3ydw0e1bnc0
Georg Friedrich Händel
0
10495
167644
124110
2026-04-25T20:43:17Z
Dorlota
13847
167644
wikitext
text/x-wiki
{{Biografie
|nómine = Georg Friedrich Händel
|foto = Haendel.jpg
|land = {{GER}}
|nascentie = 23-im de februar 1685
|nasc_loc = Halle (Saale)
|morte = 14-im de april 1759
|mort_loc = London
|ocupation = Musico
}}
'''Georg Friedrich Händel''' ([[anglesi]]: George Frideric Handel) esset un famosi [[Germania|german]] compositor de classic [[musica]] in li epoca de [[baroc]]. Il nascet li 23-im de februar 1685 in [[Halle (Saale)]] e morit li 14-im de april 1759 in [[London]] ([[Reyatu Unit]]). Händel es egardat quam un del max important musicos del historie.
In li annu 1710 Händel comensat laborar quam musico in [[Reyatu Unit]] e mem devenit cive del [[Reyatu Unit]].
==Ovre==
Li principal ovre de Händel consistet in 42 [[ópera]]s e 25 [[oratorie]]s.
{{DEFAULTSORT: Händel, Georg Friedrich}}
[[Categorie: Germania]]
[[Categorie: Compositores]]
[[Categorie: Musica]]
4ng015hekj9e64jgk3yw2bsl4aizat2
Clara Schumann
0
10497
167655
124118
2026-04-25T20:46:17Z
Dorlota
13847
167655
wikitext
text/x-wiki
{{Biografie
|nómine = Clara Josephine Schumann
|foto = Franz_Hanfstaengl_-_Clara_Schumann_(1857).jpg
|land = {{GER}}
|nascentie = 13-im de septembre 1819
|nasc_loc = Leipzig
|morte = 20-im de may 1896
|mort_loc = Frankfurt
|ocupation = Musico, Pianista
}}
'''Clara Josephine Schumann''', nascet quam ''Clara Josephine Wieck'' esset un famosi [[Germania|german]] compositora de classic [[musica]] e pianista. Ella nascet li 13-im de septembre 1819 in [[Leipzig]] e morit li 20-im de may 1896 in [[Frankfurt]]. Ella esset maritat con li compositor [[Robert Schumann]] desde li annu 1840.
Ja in li etá de nin annus Clara Wieck havet public concertes quam pianista. Clara Schumann anc laborat quam docente de [[piano]].
{{DEFAULTSORT: Schumann, Clara}}
[[Categorie: Germania]]
[[Categorie: Compositores]]
[[Categorie: Musica]]
49a3lcfogsd1yrm7obktavnpiaqrtc4
Ennio Morricone
0
10566
167649
144961
2026-04-25T20:44:44Z
Dorlota
13847
167649
wikitext
text/x-wiki
{{Biografie
|nómine = Ennio Morricone
|foto = Ennio Morricone Cannes 2007.jpg
|land = {{ITA}}
|nascentie = 10-im de novembre 1928
|nasc_loc = Roma
|morte = 6-im de julí 2020
|mort_loc = Roma
|ocupation = compositor, dirigent, musico
}}
'''Ennio Morricone''' esset un [[Italia|italian]] compositor, dirigent e musico. Il nascet li 10-im de novembre 1928 in [[Roma]] e morit 6-im de julí 2020in [[Roma]].
Ennio Morricone devenit famosi pro su musico por filmes. Il composit li musico por plu quam 500 filmes. Li max famosi ovres es li musico por li italian western-filmes.
Ennio Morricone recivet li [[Oscar-premie]] in li annu 2016 por li musica por li film ''The Hateful Eight'' e un [[Oscar-premie]] por honorar li tot ovre de su vive in li annu 2007.
{{DEFAULTSORT: Morricone, Ennio}}
[[Categorie:Compositores]]
[[Categorie:Italianes]]
n19kipzu3pk29j82eelpv45ghtivtxo
Maurice Ravel
0
10706
167654
127374
2026-04-25T20:46:06Z
Dorlota
13847
167654
wikitext
text/x-wiki
{{Biografie
|nómine = Maurice Ravel
|foto = Maurice_Ravel_1925.jpg
|land = {{FRA}}
|nascentie = 7-im de marte 1875
|nasc_loc = Ciboure
|morte = 28-im de decembre 1937
|mort_loc = Paris
|ocupation = Musico, Compositor
}}
'''Maurice Ravel''', nascet quam ''Joseph-Maurice Ravel '' esset un famosi [[Francia|francesi]] compositor de classic [[musica]]. Il nascet li 7-im de marte 1875 in [[Ciboure]] e morit li 28-im de decembre 1937 in [[Paris]].
Il es egardat quam un del max important representantes del [[impressionisme]] in li musica. Su max famosi ovre es li pezze por orchestre [[Bólero]] quel es creat quam musica por [[ballette]].
{{DEFAULTSORT: Ravel, Maurice}}
[[Categorie:Franceses]]
[[Categorie: Compositores]]
[[Categorie: Musica]]
sddbyjv4g87ewgx3fh1z1h4gq14emnf
Jacques Offenbach
0
11621
167650
131968
2026-04-25T20:45:08Z
Dorlota
13847
167650
wikitext
text/x-wiki
{{Biografie
|nómine = Jacques Offenbach
|foto = Jacques Offenbach (Brustbild nach halbrechts).jpg
|land = {{DEU}} {{FRA}}
|nascentie = 20-im de junio 1819
|nasc_loc = Köln
|morte = 5-im de octobre 1880
|mort_loc = Paris
|ocupation = Musico, Compositor
}}
'''Jakob "Jacques" Offenbach''' esset un [[Germania|german]]-[[Francia|frances]] compositor de classic [[musica]] e musico. Il nascet li 20-im de junio 1875 in [[Köln]] ([[Germania]])e morit li 5-im de octobre 1880 in [[Paris]].
Ye li annu 1836 Offenbach translocat de [[Germania]] a [[Paris]]. Il esset maritat con Hermine d'Alcain e li cuple havet quin infantes. Jacques Offenbach recivet in li annu 1860 li civitá de [[Francia]], ma pos li german-frances guerre ye 1870/1871 il esset egardat in [[Francia]] quam german spion e in [[Germania]] quam trahitor.
==Ovre==
Il es egardat quam li fundator del modern [[operette]] quam propri e aconosset pezze del musica del [[music-teatre]]. Jacques Offenbach ludet li [[violoncello]].
Li max famosi pezzes de musica de Jacques Offenbach es li danse-pezze [[Cancan]] ex [[Orpheus in li inferne]] e [[Bacarole]] ex li [[Narrationes de Hoffmann]].
Jacques Offenbach composit 75 pezzes por li [[violoncello]] e 102 ovres por li [[music-teatre]].
{{DEFAULTSORT: Offenbach, Jacques}}
[[Categorie: Compositores]]
[[Categorie: Musica]]
a5fg8d4bkqyypi8uylilf984ew19z3z
Modest Mussorgsky
0
11648
167639
155300
2026-04-25T20:41:33Z
Dorlota
13847
167639
wikitext
text/x-wiki
{{Biografie
|nómine = Modest Mussorgsky
|foto = Modest_Musorgskiy,_1870.jpg
|land = {{RUS}}
|nascentie = 21-im de marte 1839
|nasc_loc = Karevo
|morte = 28-im de marte 1881
|mort_loc = [[Moscva]]
|ocupation = Musico, Compositor
}}
'''Modest Petrovich Mussorgsky''' ([[russ]]: Модест Петрович Мусоргский) esset un famosi [[Russia|russ]] compositor de classic [[musica]] in li 19-im secul. Il nascet li 21-im de marte 1839 in [[Karevo]] in li guvernia [[Pskov]] e morit li 28-im de marte 1881 in [[Moscva]]). Mussorgsky es egardat quam un del max índependent compositores de [[Russia]]. e esset membre del [[Gruppe de Quin]].
==Ovre==
Modest Mussorgsky devenit famosi per su [[ópera]]s quam [[Boris Gordunov (Ópera)|Boris Gordunov]] e li cicle por [[piano]] [[Pictureas de un exposition]]. Pro su tost morte in li etá de 42 annus mult de su ovres restat íncomplet.
{{DEFAULTSORT: Mussorgsky, Modest}}
[[Categorie:Russes]]
[[Categorie:Compositores]]
jpx81ndno4twmjmcb25toyc0mt2ftei
Mikis Theodorakis
0
14666
167658
162834
2026-04-25T20:47:03Z
Dorlota
13847
167658
wikitext
text/x-wiki
{{Biografie
|nómine = Mikis Theodorakis
|foto = Mikis Theodorakis Fabrik 070004.jpg
|land = {{GRE}}
|nascentie = 29-im de julí 1925
|nasc_loc = Chios
|morte = 2-im de septembre 2021
|mort_loc = Athina
|ocupation = Compositor, Autor, Politico
}}
'''Michael Mikis Theodorakis''' ([[grec]]: Μιχαήλ Μίκης Θεοδωράκης) nascet esset un famosi [[Grecia|grec]] compositor, autor e politico. Il nascet li 29-im de julí 1925 sur li insul [[Chios]] e morit li 2-im de septembre 2021 in [[Athina]].
Mikis Theodorakis devenit famosi per composir li musica por li filmes [[Zorba the Greek]] in li annu 1964, Z e [[Serpico]]. Il es egardat quam max important compositor de [[Grecia]] in li 20-im secul.
Mikis Theodorakis anc esset activ quam politico. Il esset membre del parlament de [[Grecia]] inter 1989 e 1993. Mikis Theodorakis esset activ longmen por li [[Comunist Partise de Grecia]], ma in li annu 1990 il changeat al conservativ partise [[Nov Democratie (Grecia)|Nov Democratie]].
{{DEFAULTSORT:Theodorakis, Mikis}}
[[Categorie:Compositores]]
[[Categorie:Politicos de Grecia]]
0qyfh884q3aaw2hacn2aafo0aszznhn
Claude Debussy
0
15021
167641
146515
2026-04-25T20:42:26Z
Dorlota
13847
167641
wikitext
text/x-wiki
{{Biografie
|nómine = Claude Debussy
|foto = Claude_Debussy_ca_1908,_foto_av_Félix_Nadar.jpg
|land = {{FRA}}
|nascentie =22-im de august 1862
|nasc_loc = Saint-Germain-en-Laye
|morte = 25-im de marte 1918
|mort_loc = Paris
|ocupation = Musico, Compositor
}}
'''Achille-Claude Debussy ''' esset un famosi [[Francia|francesi]] compositor del [[impressionisme]]. Il nascet li 22-im de august 1862 in [[Saint-Germain-en-Laye]] e morit li 25-im de marte 1918 in [[Paris]]. Su musica es egardat quam ligament inter [[Romantica (arte)|romantica]] e [[impressionisme]].
Claude Debussy studiat 13 annus musica in [[Paris]].
==Ovres==
Su max famosi ovres por orchestres es ''Prélude à l'après-midi d'un faune'' (1894), ''Nocturnes'' (1897–1899) e ''Images'' (1905–1912) e li piano-ovre ''Suite bergamasque'' quel include quam triesim movement ''Clair de lune''.
{{DEFAULTSORT: Debussy, Claude}}
[[Categorie:Franceses]]
[[Categorie: Compositores]]
[[Categorie: Musica]]
pquie0uo9grm9147vbkc8fiwwvtbv10
Module:Citation/CS1
828
15539
167623
147621
2026-04-25T18:33:47Z
Ellenor2000
20768
Tonde li node Gordian: yo copia li págine de Wikipedia in anglés: https://en.wikipedia.org/w/index.php?title=Module:Citation/CS1&action=edit
167623
Scribunto
text/plain
require ('strict');
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
each of these counts against the Lua upvalue limit
]]
local validation; -- functions in Module:Citation/CS1/Date_validation
local utilities; -- functions in Module:Citation/CS1/Utilities
local z = {}; -- table of tables in Module:Citation/CS1/Utilities
local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers
local metadata; -- functions in Module:Citation/CS1/COinS
local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist
--[[------------------< P A G E S C O P E V A R I A B L E S >---------------
declare variables here that have page-wide scope that are not brought in from
other modules; that are created here and used here
]]
local added_deprecated_cat; -- boolean flag so that the category is added only once
local added_vanc_errs; -- boolean flag so we only emit one Vancouver error / category
local added_generic_name_errs; -- boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered
local added_numeric_name_errs; -- boolean flag so we only emit one numeric name error / category and stop testing names once an error is encountered
local added_numeric_name_maint; -- boolean flag so we only emit one numeric name maint category and stop testing names once a category has been emitted
local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module)
local is_sandbox; -- true when using sandbox modules to render citation
local url_was_archive_today; -- boolean flag set to true when has_archive_today_url() has unset |url= because it held a deprecated archive.today url
--[[--------------------------< F I R S T _ S E T >------------------------------------------------------------
Locates and returns the first set value in a table of values where the order established in the table,
left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set.
This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs
version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate
the for-loop before it reached the actual end of the list.
]]
local function first_set (list, count)
local i = 1;
while i <= count do -- loop through all items in list
if utilities.is_set( list[i] ) then
return list[i]; -- return the first set list member
end
i = i + 1; -- point to next
end
end
--[[--------------------------< A D D _ V A N C _ E R R O R >----------------------------------------------------
Adds a single Vancouver system error message to the template's output regardless of how many error actually exist.
To prevent duplication, added_vanc_errs is nil until an error message is emitted.
added_vanc_errs is a Boolean declared in page scope variables above
]]
local function add_vanc_error (source, position)
if added_vanc_errs then return end
added_vanc_errs = true; -- note that we've added this category
utilities.set_message ('err_vancouver', {source, position});
end
--[[--------------------------< I S _ S C H E M E >------------------------------------------------------------
does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it
is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says:
Scheme names consist of a sequence of characters beginning with a
letter and followed by any combination of letters, digits, plus
("+"), period ("."), or hyphen ("-").
returns true if it does, else false
]]
local function is_scheme (scheme)
return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern
end
--[=[-------------------------< I S _ D O M A I N _ N A M E >--------------------------------------------------
Does this thing that purports to be a domain name seem to be a valid domain name?
Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5
BNF defined here: https://tools.ietf.org/html/rfc4234
Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15;
see also [[Single-letter second-level domain]]
list of TLDs: https://www.iana.org/domains/root/db
RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit. Between
the first and last characters the name may use letters, digits, and the hyphen.
Also allowed are IPv4 addresses. IPv6 not supported
domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld
is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped
here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal.
There are several tests:
the first character of the whole domain name including subdomains must be a letter or a digit
internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490
single-letter/digit second-level domains in the .org, .cash, and .today TLDs
q, x, and z SL domains in the .com TLD
i and q SL domains in the .net TLD
single-letter SL domains in the ccTLDs (where the ccTLD is two letters)
two-character SL domains in gTLDs (where the gTLD is two or more letters)
three-plus-character SL domains in gTLDs (where the gTLD is two or more letters)
IPv4 dot-decimal address format; TLD not allowed
returns true if domain appears to be a proper name and TLD or IPv4 address, else false
]=]
local function is_domain_name (domain)
if not domain then
return false; -- if not set, abandon
end
domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once
if not domain:match ('^[%w]') then -- first character must be letter or digit
return false;
end
if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource
return false;
end
local patterns = { -- patterns that look like URLs
'%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld
'%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix
'%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10)
'%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10)
'%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars)
'%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD
'^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address
'[%a%d]+%:?' -- IPv6 address
}
for _, pattern in ipairs (patterns) do -- loop through the patterns list
if domain:match (pattern) then
return true; -- if a match then we think that this thing that purports to be a URL is a URL
end
end
for _, d in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- look for single letter second level domain names for these top level domains
if domain:match ('%f[%w][%w]%.' .. d) then
return true
end
end
return false; -- no matches, we don't know what this thing is
end
--[[--------------------------< I S _ U R L >------------------------------------------------------------------
returns true if the scheme and domain parts of a URL appear to be a valid URL; else false.
This function is the last step in the validation process. This function is separate because there are cases that
are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external
wikilinks.
]]
local function is_url (scheme, domain)
if utilities.is_set (scheme) then -- if scheme is set check it and domain
return is_scheme (scheme) and is_domain_name (domain);
else
return is_domain_name (domain); -- scheme not set when URL is protocol-relative
end
end
--[[--------------------------< S P L I T _ U R L >------------------------------------------------------------
Split a URL into a scheme, authority indicator, and domain.
First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#).
If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain.
When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one
or more '/' characters immediately following the scheme's colon), make sure that there are only 2.
Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes
like news: that don't use authority indicator?
Strip off any port and path;
]]
local function split_url (url_str)
local scheme, authority, domain;
url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//')
if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL
domain = url_str:match ('^//(%S*)')
elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name
scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions
if utilities.is_set (authority) then
authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing;
if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then
return scheme; -- return scheme only making domain nil which will cause an error message
end
else
if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test?
return scheme; -- return scheme only making domain nil which will cause an error message
end
end
domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present
end
return scheme, domain;
end
--[[--------------------------< L I N K _ P A R A M _ O K >---------------------------------------------------
checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs
Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed:
# < > [ ] | { } _
except the underscore which is used as a space in wiki URLs and # which is used for section links
returns false when the value contains any of these characters.
When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the
|<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok).
]]
local function link_param_ok (value)
local scheme, domain;
if value:find ('[<>%[%]|{}]') then -- if any prohibited characters
return false;
end
scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL;
return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL
end
--[[--------------------------< L I N K _ T I T L E _ O K >---------------------------------------------------
Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value.
|<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when
that condition exists
check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language
code and must begin with a colon.
]]
local function link_title_ok (link, lorig, title, torig)
local orig;
if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value
if not link_param_ok (link) then -- check |<param>-link= markup
orig = lorig; -- identify the failing link parameter
elseif title:find ('%[%[') then -- check |title= for wikilink markup
orig = torig; -- identify the failing |title= parameter
elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki
local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix
if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon
orig = lorig; -- flag as error
end
end
end
if utilities.is_set (orig) then
link = ''; -- unset
utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=;
end
return link; -- link if ok, empty string else
end
--[[--------------------------< C H E C K _ U R L >------------------------------------------------------------
Determines whether a URL string appears to be valid.
First we test for space characters. If any are found, return false. Then split the URL into scheme and domain
portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two
portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false.
Because it is different from a standard URL, and because this module used external_link() to make external links
that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name
is at https://tools.ietf.org/html/rfc5536#section-3.1.4
]]
local function check_url( url_str )
if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL
return false;
end
local scheme, domain;
scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL;
if 'news:' == scheme then -- special case for newsgroups
return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$');
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >----------------------------
Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first
non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks
that use protocol-relative URLs. Also finds bare URLs.
The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that
find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=,
and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]]
is possible as might be [[en://Hus]].
]=]
local function is_parameter_ext_wikilink (value)
local scheme, domain;
if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]'));
elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]'));
elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(%a%S*:%S+)'));
elseif value:match ('^//%S+') or value:match ('%s//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; authority indicator (//) must be be preceded nothing or by whitespace
scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain
else
return false; -- didn't find anything that is obviously a URL
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[[--------------------------< I S _ A R C H I V E _ T O D A Y _ U R L >--------------------------------------
archive.today (and .ph, .is, .md, .li, .fo, .vn) are deprecated. See Wikipedia:Requests_for_comment/Archive.is_RFC_5
(Special:Permalink/1339352976)
<val> is a string that may or may not be a url
]]
local function is_archive_today_url (val)
if is_parameter_ext_wikilink (val) then -- is <val> a url?
local tld = val:match ('archive%.(%l+)'); -- get the tld
return tld and cfg.archive_today_tlds_t[tld]; -- return true if <tld> is one of the archive.today tlds; nil else
end
end
--[[--------------------------< H A S _ A R C H I V E _ T O D A Y _ U R L >------------------------------------
blank any parameter that holds one of the archive.today tlds (.today, .ph, .is, .md, .li, .fo, .vn) and also
blank parameters that are dependent on the offending parameter.
input <cite_args_t> is a table of all of this template's parameters This function modifies <cite_args_t>
when |url= or its alias |URL= hold an archive.today url, this function sets the flag <url_was_archive_today>
which is used later to suppress the missing url error message from {{citation}} when it has |website=<summat>
or from the templates {{cite web}}, {{cite podcast}}, {{cite mailing list}} which all require a url.
returns nothing
]]
local function has_archive_today_url (cite_args_t)
local unset_params_t = {}; -- to hold a sequence of parameters to unset from cite_args_t
for p, v in pairs (cite_args_t) do -- look at each parameter in the template
if is_archive_today_url (v:lower()) then -- if it has a parameter with an archive.today url
table.insert (unset_params_t, p); -- add the url-holding parameter name to our list of parameters to unset (may or may not be a legitimate url parameter)
if 'url' == p:lower() then -- if this parameter is |url= or |URL=
url_was_archive_today = true; -- set a flag so that cite web / podcast / mailinglist don't emit a missing url error message
end
if cfg.dependencies_t[p] then -- if this url-holding parameter (<p>) has dependencies
for _, dependent in ipairs (cfg.dependencies_t[p]) do -- loop through the url-holding parameter's dependency sequence
table.insert (unset_params_t, dependent); -- add dependent parameter to the list to be unset
end
end
end
end
if 0 < #unset_params_t then -- when there are parameters to unset
if not is_preview_mode then -- when in preview mode do not suppress any parameters
for _, unset_param in ipairs (unset_params_t) do -- loop through the sequence
cite_args_t[unset_param] = nil; -- and unset the url-holding parameter and its dependent parameters to avoid parameter-requires-other-parameter errors
end
end
utilities.set_message ('maint_deprecated_archive'); -- add a maintenance message
end
end
--[[-------------------------< C H E C K _ F O R _ U R L >-----------------------------------------------------
loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message.
]]
local function check_for_url (parameter_list, error_list)
for k, v in pairs (parameter_list) do -- for each parameter in the list
if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message
table.insert (error_list, utilities.wrap_style ('parameter', k));
end
end
end
--[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------
Escape sequences for content that will be used for URL descriptions
]]
local function safe_for_url( str )
if str:match( "%[%[.-%]%]" ) ~= nil then
utilities.set_message ('err_wikilink_in_url', {});
end
return str:gsub( '[%[%]\n]', {
['['] = '[',
[']'] = ']',
['\n'] = ' ' } );
end
--[[--------------------------< E X T E R N A L _ L I N K >----------------------------------------------------
Format an external link with error checking
]]
local function external_link (URL, label, source, access)
local err_msg = '';
local domain;
local path;
local base_url;
if not utilities.is_set (label) then
label = URL;
if utilities.is_set (source) then
utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)});
else
error (cfg.messages["bare_url_no_origin"]); -- programmer error; valid parameter name does not have matching meta-parameter
end
end
if not check_url (URL) then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)});
end
domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path
if path then -- if there is a path portion
path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values
URL = table.concat ({domain, path}); -- and reassemble
end
base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL
if utilities.is_set (access) then -- access level (subscription, registration, limited)
base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon
end
return base_url;
end
--[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >--------------------------------------
Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the
offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated
parameters in the citation.
added_deprecated_cat is a Boolean declared in page scope variables above
]]
local function deprecated_parameter(name)
if not added_deprecated_cat then
added_deprecated_cat = true; -- note that we've added this category
utilities.set_message ('err_deprecated_params', {name}); -- add error message
end
end
--[=[-------------------------< K E R N _ Q U O T E S >--------------------------------------------------------
Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote
mark contained in a |title= or |chapter= parameter's value.
This function will positive kern either single or double quotes:
"'Unkerned title with leading and trailing single quote marks'"
" 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example)
Double single quotes (italic or bold wiki-markup) are not kerned.
Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter
quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks.
Call this function for chapter titles, for website titles, etc.; not for book titles.
]=]
local function kern_quotes (str)
local cap = '';
local wl_type, label, link;
wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks
if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
str = utilities.substitute (cfg.presentation['kern-right'], str);
elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks
str = utilities.substitute (cfg.presentation['kern-right'], str);
end
else -- plain text or [[L|D]]; text in label variable
label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark)
label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark)
cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-left'], cap);
end
cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-right'], cap);
end
if 2 == wl_type then
str = utilities.make_wikilink (link, label); -- reassemble the wikilink
else
str = label;
end
end
return str;
end
--[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >----------------------------------------
|script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should
not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped
in italic markup.
Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right.
|script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon:
|script-title=ja:*** *** (where * represents a Japanese character)
Spaces between the two-character code and the colon and the colon and the first script character are allowed:
|script-title=ja : *** ***
|script-title=ja: *** ***
|script-title=ja :*** ***
Spaces preceding the prefix are allowed: |script-title = ja:*** ***
The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can
know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute
is not added. At this time there is no error message for this condition.
Supports |script-title=, |script-chapter=, |script-<periodical>=
]]
local function format_script_value (script_value, script_param)
local lang=''; -- initialize to empty string
local name;
if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix
lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script
if not utilities.is_set (lang) then
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message
return ''; -- script_value was just the prefix so return empty string
end
-- if we get this far we have prefix and script
name = cfg.lang_tag_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize
if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code?
script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script
-- is prefix one of these language codes?
if utilities.in_array (lang, cfg.script_lang_codes) then
utilities.add_prop_cat ('script', {name, lang})
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message
end
lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message
lang = ''; -- invalid so set lang to empty string
end
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message
end
script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL
return script_value;
end
--[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------
Initially for |title= and |script-title=, this function concatenates those two parameter values after the script
value has been wrapped in <bdi> tags.
]]
local function script_concatenate (title, script, script_param)
if utilities.is_set (script) then
script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error
if utilities.is_set (script) then
title = title .. ' ' .. script; -- concatenate title and script title
end
end
return title;
end
--[[--------------------------< W R A P _ M S G >--------------------------------------------------------------
Applies additional message text to various parameter values. Supplied string is wrapped using a message_list
configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken
from citation_config.messages - the reason this function is similar to but separate from wrap_style().
]]
local function wrap_msg (key, str, lower)
if not utilities.is_set ( str ) then
return "";
end
if true == lower then
local msg;
msg = cfg.messages[key]:lower(); -- set the message to lower case before
return utilities.substitute ( msg, str ); -- including template text
else
return utilities.substitute ( cfg.messages[key], str );
end
end
--[[----------------< W I K I S O U R C E _ U R L _ M A K E >-------------------
Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate
label; nil else.
str is the value assigned to |chapter= (or aliases) or |title= or |title-link=
]]
local function wikisource_url_make (str)
local wl_type, D, L;
local ws_url, ws_label;
local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'});
wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink)
if 0 == wl_type then -- not a wikilink; might be from |title-link=
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]]
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]])
str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_label = D; -- get ws article name from display portion of interwiki link
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title without namespace from link portion of wikilink
});
end
end
if ws_url then
ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL
ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker
end
return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil
end
--[[----------------< F O R M A T _ P E R I O D I C A L >-----------------------
Format the three periodical parameters: |script-<periodical>=, |<periodical>=,
and |trans-<periodical>= into a single Periodical meta-parameter.
]]
local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical)
if not utilities.is_set (periodical) then
periodical = ''; -- to be safe for concatenation
else
periodical = utilities.wrap_style ('italic-title', periodical); -- style
end
periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (trans_periodical) then
trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical);
if utilities.is_set (periodical) then
periodical = periodical .. ' ' .. trans_periodical;
else -- here when trans-periodical without periodical or script-periodical
periodical = trans_periodical;
utilities.set_message ('err_trans_missing_title', {'periodical'});
end
end
return periodical;
end
--[[------------------< F O R M A T _ C H A P T E R _ T I T L E >---------------
Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=,
and |chapter-url= into a single chapter meta- parameter (chapter_url_source used
for error messages).
]]
local function format_chapter_title (script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access)
local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link
if ws_url then
ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters
chapter = ws_label;
end
if not utilities.is_set (chapter) then
chapter = ''; -- to be safe for concatenation
else
if false == no_quotes then
chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks
chapter = utilities.wrap_style ('quoted-title', chapter);
end
end
chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (chapter_url) then
chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate
elseif ws_url then
chapter = external_link (ws_url, chapter .. ' ', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this?
chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter});
end
if utilities.is_set (trans_chapter) then
trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter);
if utilities.is_set (chapter) then
chapter = chapter .. ' ' .. trans_chapter;
else -- here when trans_chapter without chapter or script-chapter
chapter = trans_chapter;
chapter_source = trans_chapter_source:match ('trans%-?(.+)'); -- when no chapter, get matching name from trans-<param>
utilities.set_message ('err_trans_missing_title', {chapter_source});
end
end
return chapter;
end
--[[----------------< H A S _ I N V I S I B L E _ C H A R S >-------------------
This function searches a parameter's value for non-printable or invisible characters.
The search stops at the first match.
This function will detect the visible replacement character when it is part of the Wikisource.
Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers
(gallery, math, pre, ref) and identifies them with a slightly different error message.
See also coins_cleanup().
Output of this function is an error message that identifies the character or the
Unicode group, or the stripmarker that was detected along with its position (or,
for multi-byte characters, the position of its first byte) in the parameter value.
]]
local function has_invisible_chars (param, v)
local position = ''; -- position of invisible char or starting position of stripmarker
local capture; -- used by stripmarker detection to hold name of the stripmarker
local stripmarker; -- boolean set true when a stripmarker is found
capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true
if capture == v then -- if same there are no Unicode characters
return;
end
for _, invisible_char in ipairs (cfg.invisible_chars) do
local char_name = invisible_char[1]; -- the character or group name
local pattern = invisible_char[2]; -- the pattern used to find it
position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern
if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character
if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts
position = nil; -- unset position
elseif cfg.emoji_t[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}?
position = nil; -- unset position
end
end
if position then
if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition)
('templatestyles' == capture and utilities.in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters
stripmarker = true; -- set a flag
elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker
position = nil; -- unset
else
local err_msg;
if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then
err_msg = utilities.substitute (cfg.messages.invisible_1, {capture, char_name}); -- <capture> here is stripmarker name
else
err_msg = utilities.substitute (cfg.messages.invisible_2, char_name);
end
utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message
return; -- and done with this parameter
end
end
end
end
--[[-------------------< A R G U M E N T _ W R A P P E R >----------------------
Argument wrapper. This function provides support for argument mapping defined
in the configuration file so that multiple names can be transparently aliased to
single internal variable.
]]
local function argument_wrapper ( args )
local origin = {};
return setmetatable({
ORIGIN = function ( self, k )
local dummy = self[k]; -- force the variable to be loaded.
return origin[k];
end
},
{
__index = function ( tbl, k )
if origin[k] ~= nil then
return nil;
end
local args, list, v = args, cfg.aliases[k];
if type( list ) == 'table' then
v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' );
if origin[k] == nil then
origin[k] = ''; -- Empty string, not nil
end
elseif list ~= nil then
v, origin[k] = args[list], list;
else
-- maybe let through instead of raising an error?
-- v, origin[k] = args[k], k;
error( cfg.messages['unknown_argument_map'] .. ': ' .. k);
end
-- Empty strings, not nil;
if v == nil then
v = '';
origin[k] = '';
end
tbl = rawset( tbl, k, v );
return v;
end,
});
end
--[[--------------------------< N O W R A P _ D A T E >-------------------------
When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>.
When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span:
<span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY
DOES NOT yet support MMMM YYYY or any of the date ranges.
]]
local function nowrap_date (date)
local cap = '';
local cap2 = '';
if date:match("^%d%d%d%d%-%d%d%-%d%d$") then
date = utilities.substitute (cfg.presentation['nowrap1'], date);
elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then
cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$");
date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2});
end
return date;
end
--[[--------------------------< S E T _ T I T L E T Y P E >---------------------
This function sets default title types (equivalent to the citation including
|type=<default value>) for those templates that have defaults. Also handles the
special case where it is desirable to omit the title type from the rendered citation
(|type=none).
]]
local function set_titletype (cite_class, title_type)
if utilities.is_set (title_type) then
if 'none' == cfg.keywords_xlate[title_type] then
title_type = ''; -- if |type=none then type parameter not displayed
end
return title_type; -- if |type= has been set to any other value use that value
end
return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation
end
--[[--------------------------< S A F E _ J O I N >-----------------------------
Joins a sequence of strings together while checking for duplicate separation characters.
]]
local function safe_join( tbl, duplicate_char )
local f = {}; -- create a function table appropriate to type of 'duplicate character'
if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions
f.gsub = string.gsub
f.match = string.match
f.sub = string.sub
else -- for multi-byte characters use the ustring library functions
f.gsub = mw.ustring.gsub
f.match = mw.ustring.match
f.sub = mw.ustring.sub
end
local str = ''; -- the output string
local comp = ''; -- what does 'comp' mean?
local end_chr = '';
local trim;
for _, value in ipairs( tbl ) do
if value == nil then value = ''; end
if str == '' then -- if output string is empty
str = value; -- assign value to it (first time through the loop)
elseif value ~= '' then
if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup.
comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string)
else
comp = value;
end
-- typically duplicate_char is sepc
if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character?
-- Because individual string segments often (always?) begin with terminal punct for the
-- preceding segment: 'First element' .. 'sepc next element' .. etc.?
trim = false;
end_chr = f.sub(str, -1, -1); -- get the last character of the output string
-- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff?
if end_chr == duplicate_char then -- if same as separator
str = f.sub(str, 1, -2); -- remove it
elseif end_chr == "'" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc''
str = f.sub(str, 1, -4) .. "''"; -- remove them and add back ''
elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]''
trim = true; -- why? why do this and next differently from previous?
elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]''
trim = true; -- same question
end
elseif end_chr == "]" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink
trim = true;
elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link
trim = true;
elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link
trim = true;
elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title.
trim = true;
end
elseif end_chr == " " then -- if last char of output string is a space
if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space>
str = f.sub(str, 1, -3); -- remove them both
end
end
if trim then
if value ~= comp then -- value does not equal comp when value contains HTML markup
local dup2 = duplicate_char;
if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it
value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup
else
value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character
end
end
end
str = str .. value; -- add it to the output string
end
end
return str;
end
--[[--------------------------< I S _ S U F F I X >-----------------------------
returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9.
Puncutation not allowed.
]]
local function is_suffix (suffix)
if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then
return true;
end
return false;
end
--[[--------------------< I S _ G O O D _ V A N C _ N A M E >-------------------
For Vancouver style, author/editor names are supposed to be rendered in Latin
(read ASCII) characters. When a name uses characters that contain diacritical
marks, those characters are to be converted to the corresponding Latin
character. When a name is written using a non-Latin alphabet or logogram, that
name is to be transliterated into Latin characters. The module doesn't do this
so editors may/must.
This test allows |first= and |last= names to contain any of the letters defined
in the four Unicode Latin character sets
[http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A
[http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF
[http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F
[http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F
|lastn= also allowed to contain hyphens, spaces, and apostrophes.
(http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
|firstn= also allowed to contain hyphens, spaces, apostrophes, and periods
This original test:
if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$")
or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then
was written outside of the code editor and pasted here because the code editor
gets confused between character insertion point and cursor position. The test has
been rewritten to use decimal character escape sequence for the individual bytes
of the Unicode characters so that it is not necessary to use an external editor
to maintain this code.
\195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls)
\195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls)
\195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B)
\199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B)
]]
local function is_good_vanc_name (last, first, suffix, position)
if not suffix then
if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix
first = first:match ('(.-)[,%s]+'); -- get name/initials
suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix
end
end
if utilities.is_set (suffix) then
if not is_suffix (suffix) then
add_vanc_error (cfg.err_msg_supl.suffix, position);
return false; -- not a name with an appropriate suffix
end
end
if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%']*$") or
nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%'%.]*$") then
add_vanc_error (cfg.err_msg_supl['non-Latin char'], position);
return false; -- not a string of Latin characters; Vancouver requires Romanization
end;
return true;
end
--[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------
Attempts to convert names to initials in support of |name-list-style=vanc.
Names in |firstn= may be separated by spaces or hyphens, or for initials, a period.
See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/.
Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered
as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/.
This code only accepts and understands generational suffix in the Vancouver format
because Roman numerals look like, and can be mistaken for, initials.
This function uses ustring functions because firstname initials may be any of the
Unicode Latin characters accepted by is_good_vanc_name ().
]]
local function reduce_to_initials (first, position)
if first:find (',', 1, true) then
return first; -- commas not allowed; abandon
end
local name, suffix = mw.ustring.match (first, "^(%u+) ([%dJS][%drndth]+)$");
if not name then -- if not initials and a suffix
name = mw.ustring.match (first, "^(%u+)$"); -- is it just initials?
end
if name then -- if first is initials with or without suffix
if 3 > mw.ustring.len (name) then -- if one or two initials
if suffix then -- if there is a suffix
if is_suffix (suffix) then -- is it legitimate?
return first; -- one or two initials and a valid suffix so nothing to do
else
add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message
return first; -- and return first unmolested
end
else
return first; -- one or two initials without suffix; nothing to do
end
end
end -- if here then name has 3 or more uppercase letters so treat them as a word
local initials_t, names_t = {}, {}; -- tables to hold name parts and initials
local i = 1; -- counter for number of initials
names_t = mw.text.split (first, '[%s%-]+'); -- split into a sequence of names and possible suffix
while names_t[i] do -- loop through the sequence
if 1 < i and names_t[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot)
names_t[i] = names_t[i]:gsub ('%.', ''); -- remove terminal dot if present
if is_suffix (names_t[i]) then -- if a legitimate suffix
table.insert (initials_t, ' ' .. names_t[i]); -- add a separator space, insert at end of initials sequence
break; -- and done because suffix must fall at the end of a name
end -- no error message if not a suffix; possibly because of Romanization
end
if 3 > i then
table.insert (initials_t, mw.ustring.sub (names_t[i], 1, 1)); -- insert the initial at end of initials sequence
end
i = i + 1; -- bump the counter
end
return table.concat (initials_t); -- Vancouver format does not include spaces.
end
--[[--------------------------< I N T E R W I K I _ P R E F I X E N _ G E T >----------------------------------
extract interwiki prefixen from <value>. Returns two one or two values:
false – no prefixen
nil – prefix exists but not recognized
project prefix, language prefix – when value has either of:
:<project>:<language>:<article>
:<language>:<project>:<article>
project prefix, nil – when <value> has only a known single-letter prefix
nil, language prefix – when <value> has only a known language prefix
accepts single-letter project prefixen: 'd' (wikidata), 's' (wikisource), and 'w' (wikipedia) prefixes; at this
writing, the other single-letter prefixen (b (wikibook), c (commons), m (meta), n (wikinews), q (wikiquote), and
v (wikiversity)) are not supported.
]]
local function interwiki_prefixen_get (value, is_link)
if not value:find (':%l+:') then -- if no prefix
return false; -- abandon; boolean here to distinguish from nil fail returns later
end
local prefix_patterns_linked_t = { -- sequence of valid interwiki and inter project prefixen
'^%[%[:([dsw]):(%l%l+):', -- wikilinked; project and language prefixes
'^%[%[:(%l%l+):([dsw]):', -- wikilinked; language and project prefixes
'^%[%[:([dsw]):', -- wikilinked; project prefix
'^%[%[:(%l%l+):', -- wikilinked; language prefix
}
local prefix_patterns_unlinked_t = { -- sequence of valid interwiki and inter project prefixen
'^:([dsw]):(%l%l+):', -- project and language prefixes
'^:(%l%l+):([dsw]):', -- language and project prefixes
'^:([dsw]):', -- project prefix
'^:(%l%l+):', -- language prefix
}
local cap1, cap2;
for _, pattern in ipairs ((is_link and prefix_patterns_linked_t) or prefix_patterns_unlinked_t) do
cap1, cap2 = value:match (pattern);
if cap1 then
break; -- found a match so stop looking
end
end
if cap1 and cap2 then -- when both then :project:language: or :language:project: (both forms allowed)
if 1 == #cap1 then -- length == 1 then :project:language:
if cfg.inter_wiki_map[cap2] then -- is language prefix in the interwiki map?
return cap1, cap2; -- return interwiki project and interwiki language
end
else -- here when :language:project:
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return cap2, cap1; -- return interwiki project and interwiki language
end
end
return nil; -- unknown interwiki language
elseif not (cap1 or cap2) then -- both are nil?
return nil; -- we got something that looks like a project prefix but isn't; return fail
elseif 1 == #cap1 then -- here when one capture
return cap1, nil; -- length is 1 so return project, nil language
else -- here when one capture and its length it more than 1
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return nil, cap1; -- return nil project, language
end
end
end
--[[--------------------------< L I S T _ P E O P L E >--------------------------
Formats a list of people (authors, contributors, editors, interviewers, translators)
names in the list will be linked when
|<name>-link= has a value
|<name>-mask- does NOT have a value; masked names are presumed to have been
rendered previously so should have been linked there
when |<name>-mask=0, the associated name is not rendered
]]
local function list_people (control, people, etal)
local sep;
local namesep;
local format = control.format;
local maximum = control.maximum;
local name_list = {};
if 'vanc' == format then -- Vancouver-like name styling?
sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma
namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space
else
sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon
namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space>
end
if sep:sub (-1, -1) ~= " " then sep = sep .. " " end
if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names
for i, person in ipairs (people) do
if utilities.is_set (person.last) then
local mask = person.mask;
local one;
local sep_one = sep;
if utilities.is_set (maximum) and i > maximum then
etal = true;
break;
end
if mask then
local n = tonumber (mask); -- convert to a number if it can be converted; nil else
if n then
one = 0 ~= n and string.rep("—", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name
person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil
else
one = mask; -- replace name with mask text (must include name-list separator)
sep_one = " "; -- modify name-list separator
end
else
one = person.last; -- get surname
local first = person.first -- get given name
if utilities.is_set (first) then
if ("vanc" == format) then -- if Vancouver format
one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested
first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials
end
end
one = one .. namesep .. first;
end
end
if utilities.is_set (person.link) then
one = utilities.make_wikilink (person.link, one); -- link author/editor
end
if one then -- if <one> has a value (name, mdash replacement, or mask text replacement)
local proj, tag = interwiki_prefixen_get (one, true); -- get the interwiki prefixen if present
if 'w' == proj and ('Wikipedia' == mw.site.namespaces.Project['name']) then
proj = nil; -- for stuff like :w:de:<article>, :w is unnecessary TODO: maint cat?
end
if proj then
local proj_name = ({['d'] = cfg.messages.wikidata, ['s'] = cfg.messages.wikisource, ['w'] = cfg.messages.wikipedia})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project
if proj_name then
one = one .. utilities.wrap_style ('interproj', proj_name); -- add resized leading space, brackets, static text, language name
utilities.add_prop_cat ('interproj-linked-name', proj); -- categorize it; <proj> is sort key
tag = nil; -- unset; don't do both project and language
end
end
if tag == cfg.this_wiki_code then
tag = nil; -- stuff like :en:<article> at en.wiki is pointless TODO: maint cat?
end
if tag then
local lang = cfg.lang_tag_remap[tag] or cfg.mw_languages_by_tag_t[tag];
if lang then -- error messaging done in extract_names() where we know parameter names
one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name
utilities.add_prop_cat ('interwiki-linked-name', tag); -- categorize it; <tag> is sort key
end
end
table.insert (name_list, one); -- add it to the list of names
table.insert (name_list, sep_one); -- add the proper name-list separator
end
end
end
local count = #name_list / 2; -- (number of names + number of separators) divided by 2
if 0 < count then
if 1 < count and not etal then
if 'amp' == format then
name_list[#name_list-2] = " & "; -- replace last separator with ampersand text
elseif 'and' == format then
if 2 == count then
name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text
else
name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text
end
end
end
name_list[#name_list] = nil; -- erase the last separator
end
local result = table.concat (name_list); -- construct list
if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list
result = result .. sep .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al.
end
return result, count; -- return name-list string and count of number of names (count used for editor names only)
end
--[[--------------------< M A K E _ C I T E R E F _ I D >-----------------------
Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise
returns an empty string.
namelist is one of the contributor-, author-, or editor-name lists chosen in that
order. year is Year or anchor_year.
]]
local function make_citeref_id (namelist, year)
local names={}; -- a table for the one to four names and year
for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names
names[i] = v.last
if i == 4 then break end -- if four then done
end
table.insert (names, year); -- add the year at the end
local id = table.concat(names); -- concatenate names and year for CITEREF id
if utilities.is_set (id) then -- if concatenation is not an empty string
return "CITEREF" .. id; -- add the CITEREF portion
else
return ''; -- return an empty string; no reason to include CITEREF id in this citation
end
end
--[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------
construct <cite> tag class attribute for this citation.
<cite_class> – config.CitationClass from calling template
<mode> – value from |mode= parameter
]]
local function cite_class_attribute_make (cite_class, mode)
local class_t = {};
table.insert (class_t, 'citation'); -- required for blue highlight
if 'citation' ~= cite_class then
table.insert (class_t, cite_class); -- identify this template for user css
table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript
else
table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript
end
for _, prop_key in ipairs (z.prop_keys_t) do
table.insert (class_t, prop_key); -- identify various properties for user css or javascript
end
return table.concat (class_t, ' '); -- make a big string and done
end
--[[---------------------< N A M E _ H A S _ E T A L >--------------------------
Evaluates the content of name parameters (author, editor, etc.) for variations on
the theme of et al. If found, the et al. is removed, a flag is set to true and
the function returns the modified name and the flag.
This function never sets the flag to false but returns its previous state because
it may have been set by previous passes through this function or by the associated
|display-<names>=etal parameter
]]
local function name_has_etal (name, etal, nocat, param)
if utilities.is_set (name) then -- name can be nil in which case just return
local patterns = cfg.et_al_patterns; -- get patterns from configuration
for _, pattern in ipairs (patterns) do -- loop through all of the patterns
if name:match (pattern) then -- if this 'et al' pattern is found in name
name = name:gsub (pattern, ''); -- remove the offending text
etal = true; -- set flag (may have been set previously here or by |display-<names>=etal)
if not nocat then -- no categorization for |vauthors=
utilities.set_message ('err_etal', {param}); -- and set an error if not added
end
end
end
end
return name, etal;
end
--[[---------------------< N A M E _ I S _ N U M E R I C >----------------------
Add an error message and category when <name> parameter value does not contain letters.
Add a maintenance category when <name> parameter value has numeric characters mixed with characters that are
not numeric characters; could be letters and/or punctuation characters.
This function will only emit one error and one maint message for the current template. Does not emit both error
and maint messages/categories for the same parameter value.
returns nothing
]]
local function name_is_numeric (name, name_alias, list_name)
local patterns = {
'^%D+%d', -- <name> must have digits preceded by other characters
'^%D*%d+%D+', -- <name> must have digits followed by other characters
}
if not added_numeric_name_errs and mw.ustring.match (name, '^[%A]+$') then -- if we have not already set an error message and <name> does not have any alpha characters
utilities.set_message ('err_numeric_names', name_alias); -- add an error message
added_numeric_name_errs = true; -- set the flag so we emit only one error message
return; -- when here no point in further testing; abandon
end
if not added_numeric_name_maint then -- if we have already set a maint message
for _, pattern in ipairs (patterns) do -- spin through list of patterns
if mw.ustring.match (name, pattern) then -- digits preceded or followed by anything but digits; %D+ includes punctuation
utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template
added_numeric_name_maint = true; -- set the flag so we emit only one maint message
return; -- when here no point in further testing; abandon
end
end
end
end
--[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------
Evaluates the content of last/surname (authors etc.) parameters for multiple names.
Multiple names are indicated if there is more than one comma or any "unescaped"
semicolons. Escaped semicolons are ones used as part of selected HTML entities.
If the condition is met, the function adds the multiple name maintenance category.
Same test for first except that commas should not appear in given names (MOS:JR says
that the generational suffix does not take a separator character). Titles, degrees,
postnominals, affiliations, all normally comma separated don't belong in a citation.
<name> – name parameter value
<list_name> – AuthorList, EditorList, etc
<limit> – number of allowed commas; 1 (default) for surnames; 0 for given names
returns nothing
]]
local function name_has_mult_names (name, list_name, limit)
local _, commas, semicolons, nbsps;
limit = limit and limit or 1;
if utilities.is_set (name) then
_, commas = name:gsub (',', ''); -- count the number of commas
_, semicolons = name:gsub (';', ''); -- count the number of semicolons
-- nbsps probably should be its own separate count rather than merged in
-- some way with semicolons because Lua patterns do not support the
-- grouping operator that regex does, which means there is no way to add
-- more entities to escape except by adding more counts with the new
-- entities
_, nbsps = name:gsub (' ',''); -- count nbsps
-- There is exactly 1 semicolon per entity, so subtract nbsps
-- from semicolons to 'escape' them. If additional entities are added,
-- they also can be subtracted.
if limit < commas or 0 < (semicolons - nbsps) then
utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message
end
end
end
--[=[-------------------------< I S _ G E N E R I C >----------------------------------------------------------
Compares values assigned to various parameters according to the string provided as <item> in the function call.
<item> can have on of two values:
'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc
'generic_titles' – for |title=
There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the
'reject' test. For example,
|author=[[John Smith (author)|Smith, John]]
would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be
rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject
tests.
Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local'])
that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index
[2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true)
or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so
that we don't run out of processing time on very large articles.
Returns
true when a reject test finds the pattern or string
false when an accept test finds the pattern or string
nil else
]=]
local function is_generic (item, value, wiki)
local test_val;
local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local'])
['en'] = string.lower,
['local'] = mw.ustring.lower,
}
local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local'])
['en'] = string.find,
['local'] = mw.ustring.find,
}
local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions
val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value
return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched
end
local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns
local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second
for _, test_type in ipairs (test_types_t) do -- for each test type
for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject
for _, wiki in ipairs (wikis_t) do
if generic_value[wiki] then
if test (value, generic_value[wiki], wiki) then -- go do the test
return ('reject' == test_type); -- param value rejected, return true; false else
end
end
end
end
end
end
--[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------
calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the
parameter name used in error messaging
]]
local function name_is_generic (name, name_alias)
if not added_generic_name_errs and is_generic ('generic_names', name) then
utilities.set_message ('err_generic_name', name_alias); -- set an error message
added_generic_name_errs = true;
end
end
--[[--------------------------< N A M E _ C H E C K S >--------------------------------------------------------
This function calls various name checking functions used to validate the content of the various name-holding parameters.
]]
local function name_checks (last, first, list_name, last_alias, first_alias)
local accept_name;
if utilities.is_set (last) then
last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last>
if not accept_name then -- <last> not wrapped in accept-as-written markup
name_has_mult_names (last, list_name); -- check for multiple names in the parameter
name_is_numeric (last, last_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (last, last_alias); -- check for names found in the generic names list
end
end
if utilities.is_set (first) then
first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first>
if not accept_name then -- <first> not wrapped in accept-as-written markup
name_has_mult_names (first, list_name, 0); -- check for multiple names in the parameter; 0 is number of allowed commas in a given name
name_is_numeric (first, first_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (first, first_alias); -- check for names found in the generic names list
end
local wl_type, D = utilities.is_wikilink (first);
if 0 ~= wl_type then
first = D;
utilities.set_message ('err_bad_paramlink', first_alias);
end
end
return last, first; -- done
end
--[[----------------------< E X T R A C T _ N A M E S >-------------------------
Gets name list from the input arguments
Searches through args in sequential order to find |lastn= and |firstn= parameters
(or their aliases), and their matching link and mask parameters. Stops searching
when both |lastn= and |firstn= are not found in args after two sequential attempts:
found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the
search is done.
This function emits an error message when there is a |firstn= without a matching
|lastn=. When there are 'holes' in the list of last names, |last1= and |last3=
are present but |last2= is missing, an error message is emitted. |lastn= is not
required to have a matching |firstn=.
When an author or editor parameter contains some form of 'et al.', the 'et al.'
is stripped from the parameter and a flag (etal) returned that will cause list_people()
to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps
'et al.' out of the template's metadata. When this occurs, an error is emitted.
]]
local function extract_names(args, list_name)
local names = {}; -- table of names
local last; -- individual name components
local first;
local link;
local mask;
local i = 1; -- loop counter/indexer
local n = 1; -- output table indexer
local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors)
local etal = false; -- return value set to true when we find some form of et al. in an author parameter
local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging
while true do
last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1
first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i );
link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i );
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
if last then -- error check |lastn= alias for unknown interwiki link prefix; done here because this is where we have the parameter name
local project, language = interwiki_prefixen_get (last, true); -- true because we expect interwiki links in |lastn= to be wikilinked
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', last_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
last = utilities.remove_wiki_link (last); -- remove wikilink markup; show display value only
end
end
if link then -- error check |linkn= alias for unknown interwiki link prefix
local project, language = interwiki_prefixen_get (link, false); -- false because wiki links in |author-linkn= is an error
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', link_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
link = nil; -- unset so we don't link
link_alias = nil;
end
end
last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al.
first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al.
last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks
if first and not last then -- if there is a firstn without a matching lastn
local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias
utilities.set_message ('err_first_missing_last', {
first_alias, -- param name of alias missing its mate
first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form
}); -- add this error message
elseif not first and not last then -- if both firstn and lastn aren't found, are we done?
count = count + 1; -- number of times we haven't found last and first
if 2 <= count then -- two missing names and we give up
break; -- normal exit or there is a two-name hole in the list; can't tell which
end
else -- we have last with or without a first
local result;
link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup
if first then
link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup
end
names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only)
n = n + 1; -- point to next location in the names table
if 1 == count then -- if the previous name was missing
utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message
end
count = 0; -- reset the counter, we're looking for two consecutive missing names
end
i = i + 1; -- point to next args location
end
return names, etal; -- all done, return our list of names and the etal flag
end
--[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------
attempt to decode |language=<lang_param> and return language name and matching tag; nil else.
This function looks for:
<lang_param> as a tag in cfg.lang_tag_remap{}
<lang_param> as a name in cfg.lang_name_remap{}
<lang_param> as a name in cfg.mw_languages_by_name_t
<lang_param> as a tag in cfg.mw_languages_by_tag_t
when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all
script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag
and look for the new <lang_param> in cfg.mw_languages_by_tag_t{}
on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil
]]
local function name_tag_get (lang_param)
local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables
local name;
local tag;
name = cfg.lang_tag_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name
if name then -- when <name>, <lang_param> is a tag for a remapped language name
if cfg.lang_name_remap[name:lower()][2] ~= lang_param_lc then
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
return name, cfg.lang_name_remap[name:lower()][2]; -- so return name and tag from lang_name_remap[name]; special case to xlate sr-ec and sr-el to sr-cyrl and sr-latn
end
return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags
name = cfg.lang_tag_remap[tag]; -- attempt to get remapped language name with language subtag only
if name then -- when <name>, <tag> is a tag for a remapped language name
return name, tag; -- so return <name> from remap and <tag>
end
if cfg.lang_name_remap[lang_param_lc] then -- not a remapped tag, assume <lang_param_lc> is a name; attempt to get remapped language tag
return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag
end
name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name
if name then
return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name>
end
tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag
if tag then
return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else
if tag then
name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag>
if name then
return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag
end
end
end
--[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------
Gets language name from a provided two- or three-character ISO 639 code. If a code
is recognized by MediaWiki, use the returned name; if not, then use the value that
was provided with the language parameter.
When |language= contains a recognized language (either code or name), the page is
assigned to the category for that code: Category:Norwegian-language sources (no).
For valid three-character code languages, the page is assigned to the single category
for '639-2' codes: Category:CS1 ISO 639-2 language sources.
Languages that are the same as the local wiki are not categorized. MediaWiki does
not recognize three-character equivalents of two-character codes: code 'ar' is
recognized but code 'ara' is not.
This function supports multiple languages in the form |language=nb, French, th
where the language names or codes are separated from each other by commas with
optional space characters.
]]
local function language_parameter (lang)
local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags
local lang_subtag; -- ve populates |language= with mostly unecessary region subtags the MediaWiki does not recognize; this is the base language subtag
local name; -- the language name
local language_list = {}; -- table of language names to be rendered
local names_t = {}; -- table made from the value assigned to |language=
local this_wiki_name = mw.language.fetchLanguageName (cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name
names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list
for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag
name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase
if utilities.is_set (tag) then
lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag
if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language
if 2 == lang_subtag:len() then -- and is a two-character tag
utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization
else -- or is a recognized language (but has a three-character tag)
utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template?
end
elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled
utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it
end
else
name = lang; -- return whatever <lang> has so that we show something
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
end
table.insert (language_list, name);
name = ''; -- so we can reuse it
end
name = utilities.make_sep_list (#language_list, language_list);
if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English'
return ''; -- if one language and that language is this wiki's return an empty string (no annotation)
end
return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)'
--[[ TODO: should only return blank or name rather than full list
so we can clean up the bunched parenthetical elements Language, Type, Format
]]
end
--[[-----------------------< S E T _ C S _ S T Y L E >--------------------------
Gets the default CS style configuration for the given mode.
Returns default separator and either postscript as passed in or the default.
In CS1, the default postscript and separator are '.'.
In CS2, the default postscript is the empty string and the default separator is ','.
]]
local function set_cs_style (postscript, mode)
if utilities.is_set(postscript) then
-- emit a maintenance message if user postscript is the default cs1 postscript
-- we catch the opposite case for cs2 in set_style
if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then
utilities.set_message ('maint_postscript');
end
else
postscript = cfg.presentation['ps_' .. mode];
end
return cfg.presentation['sep_' .. mode], postscript;
end
--[[--------------------------< S E T _ S T Y L E >-----------------------------
Sets the separator and postscript styles. Checks the |mode= first and the
#invoke CitationClass second. Removes the postscript if postscript == none.
]]
local function set_style (mode, postscript, cite_class)
local sep;
if 'cs2' == mode then
sep, postscript = set_cs_style (postscript, 'cs2');
elseif 'cs1' == mode then
sep, postscript = set_cs_style (postscript, 'cs1');
elseif 'citation' == cite_class then
sep, postscript = set_cs_style (postscript, 'cs2');
else
sep, postscript = set_cs_style (postscript, 'cs1');
end
if cfg.keywords_xlate[postscript:lower()] == 'none' then
-- emit a maintenance message if user postscript is the default cs2 postscript
-- we catch the opposite case for cs1 in set_cs_style
if 'cs2' == mode or ('cs1' ~= mode and 'citation' == cite_class) then -- {{citation |title=Title |mode=cs1 |postscript=none}} should not emit maint message
utilities.set_message ('maint_postscript');
end
postscript = '';
end
return sep, postscript
end
--[=[-------------------------< I S _ P D F >-----------------------------------
Determines if a URL has the file extension that is one of the PDF file extensions
used by [[MediaWiki:Common.css]] when applying the PDF icon to external links.
returns true if file extension is one of the recognized extensions, else false
]=]
local function is_pdf (url)
return url:match ('%.pdf$') or url:match ('%.PDF$') or
url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or
url:match ('%.PDF#') or url:match ('%.pdf#');
end
--[[--------------------------< S T Y L E _ F O R M A T >-----------------------
Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message
if the format parameter does not have a matching URL parameter. If the format parameter
is not set and the URL contains a file extension that is recognized as a PDF document
by MediaWiki's commons.css, this code will set the format parameter to (PDF) with
the appropriate styling.
]]
local function style_format (format, url, fmt_param, url_param)
if utilities.is_set (format) then
format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize
if not utilities.is_set (url) then
utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message
end
elseif is_pdf (url) then -- format is not set so if URL is a PDF file then
format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF
else
format = ''; -- empty string for concatenation
end
return format;
end
--[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------
Returns a number that defines the number of names displayed for author and editor
name lists and a Boolean flag to indicate when et al. should be appended to the name list.
When the value assigned to |display-xxxxors= is a number greater than or equal to zero,
return the number and the previous state of the 'etal' flag (false by default
but may have been set to true if the name list contains some variant of the text 'et al.').
When the value assigned to |display-xxxxors= is the keyword 'etal', return a number
that is one greater than the number of authors in the list and set the 'etal' flag true.
This will cause the list_people() to display all of the names in the name list followed by 'et al.'
In all other cases, returns nil and the previous state of the 'etal' flag.
inputs:
max: A['DisplayAuthors'] or A['DisplayEditors'], etc; a number or some flavor of etal
count: #a or #e
list_name: 'authors' or 'editors'
etal: author_etal or editor_etal
This function sets an error message when |display-xxxxors= value greater than or equal to number of names but
not when <max> comes from {{cs1 config}} global settings. When using global settings, <param> is set to the
keyword 'cs1 config' which is used to supress the normal error. Error is suppressed because it is to be expected
that some citations in an article will have the same or fewer names that the limit specified in {{cs1 config}}.
]]
local function get_display_names (max, count, list_name, etal, param)
if utilities.is_set (max) then
if 'etal' == max:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
max = count + 1; -- number of authors + 1 so display all author name plus et al.
etal = true; -- overrides value set by extract_names()
elseif max:match ('^%d+$') then -- if is a string of numbers
max = tonumber (max); -- make it a number
if (max >= count) and ('cs1 config' ~= param) then -- error when local |display-xxxxors= value greater than or equal to number of names; not an error when using global setting
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil;
end
else -- not a valid keyword or number
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil; -- unset; as if |display-xxxxors= had not been set
end
end
return max, etal;
end
--[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >---------------
Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be
some form of p. or pp. abbreviation in the first characters of the parameter content.
check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value:
good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px
where x and X are letters and # is a digit
bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG
]]
local function extra_text_in_page_check (val, name)
if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message ('err_extra_text_pages', name); -- add error message
return; -- and done
end
end
end
end
--[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------
Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator. Applies to
both; this function looks for issue text in both |issue= and |volume= and looks for volume-like text in |voluem=
and |issue=.
For |volume=:
'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter
content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so
are allowed.
For |issue=:
'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the
parameter content (all case insensitive); numero styling: 'n°' with degree sign U+00B0, and № precomposed
numero sign U+2116.
Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or
whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module.
<val> is |volume= or |issue= parameter value
<name> is |volume= or |issue= parameter name for error message
<selector> is 'v' for |volume=, 'i' for |issue=
sets error message on failure; returns nothing
]]
local function extra_text_in_vol_iss_check (val, name, selector)
if not utilities.is_set (val) then
return;
end
local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue';
local accept_val;
val, accept_val = utilities.has_accept_as_written (val);
--if accept_val then -- if uncomment this, |volume=((vol. 1)) suppresses error
-- return;
--end
--val = mw.text.unstripNoWiki (val); -- if uncomment this, |volume=<nowiki>vol. 1</nowiki> shows error
val = val:lower(); -- force parameter value to lower case
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.vi_patterns_t) do -- spin through the sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message (handler, name); -- add error message
return; -- and done
end
end
end
--[=[-------------------------< G E T _ V _ N A M E _ T A B L E >----------------------------------------------
split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled
parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the
rendered citation and in the metadata. Individual author names may be wikilinked
|vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.))
]=]
local function get_v_name_table (vparam, output_table, output_link_table)
local _, accept = utilities.has_accept_as_written (vparam);
if accept then
utilities.add_prop_cat ('vanc-accept'); -- add properties category
end
local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas
local wl_type, label, link; -- wl_type not used here; just a placeholder
local i = 1;
while name_table[i] do
if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses
local name = name_table[i];
i = i + 1; -- bump indexer to next segment
while name_table[i] do
name = name .. ', ' .. name_table[i]; -- concatenate with previous segments
if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses
break; -- and done reassembling so
end
i = i + 1; -- bump indexer
end
table.insert (output_table, name); -- and add corporate name to the output table
table.insert (output_link_table, ''); -- no wikilink
else
wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
table.insert (output_table, label); -- add this name
if 1 == wl_type then
table.insert (output_link_table, label); -- simple wikilink [[D]]
else
table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string
end
end
i = i + 1;
end
return output_table;
end
--[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >--------------------------------
This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and
|xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does.
Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names
may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance
tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests.
Supports generational suffixes Jr, 2nd, 3rd, 4th–6th.
This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials.
]]
local function parse_vauthors_veditors (args, vparam, list_name)
local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn=
local v_name_table = {};
local v_link_table = {}; -- when name is wikilinked, targets go in this table
local etal = false; -- return value set to true when we find some form of et al. vauthors parameter
local last, first, link, mask, suffix;
local corporate = false;
vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period)
v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas
for i, v_name in ipairs(v_name_table) do
first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor
local accept_name;
v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name>
if accept_name then
last = v_name;
corporate = true; -- flag used in list_people()
elseif string.find(v_name, "%s") then
if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters;
add_vanc_error (cfg.err_msg_supl.punctuation, i);
end
local lastfirstTable = {}
lastfirstTable = mw.text.split(v_name, "%s+")
first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be initials or generational suffix
if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters
suffix = first; -- not initials so assume that whatever we got is a generational suffix
first = table.remove(lastfirstTable); -- get what should be the initials from the table
end
last = table.concat(lastfirstTable, ' ') -- returns a string that is the concatenation of all other names that are not initials and generational suffix
if not utilities.is_set (last) then
first = ''; -- unset
last = v_name; -- last empty because something wrong with first
add_vanc_error (cfg.err_msg_supl.name, i);
end
if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then
add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing
end
if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test
add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials
end
else
last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this?
end
if utilities.is_set (first) then
if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else
add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials
end
is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit
if utilities.is_set (suffix) then
first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials
suffix = ''; -- unset so we don't add this suffix to all subsequent names
end
else
if not corporate then
is_good_vanc_name (last, '', nil, i);
end
end
link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i];
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list
end
return names, etal; -- all done, return our list of names
end
--[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------
Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or
select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list.
Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest;
|editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn)
When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second
test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better
way to do this, I just haven't discovered what that way is.
Emits an error message when more than one xxxxor name source is provided.
In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate.
]]
local function select_author_editor_source (vxxxxors, xxxxors, args, list_name)
local lastfirst = false;
if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ...
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors=
utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then
lastfirst = true;
end
if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions
(utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or
(true == lastfirst and utilities.is_set (xxxxors)) then
utilities.set_message ('err_redundant_parameters',
utilities.substitute (cfg.special_case_translation.name_list_params,
('AuthorList' == list_name) and cfg.special_case_translation.author or cfg.special_case_translation.editor)); -- add error message
end
if true == lastfirst then return 1 end; -- return a number indicating which author name source to use
if utilities.is_set (vxxxxors) then return 2 end;
if utilities.is_set (xxxxors) then return 3 end;
return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last
end
--[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------
This function is used to validate a parameter's assigned value for those parameters that have only a limited number
of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing
or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one
of the list of allowed values returns the translated value; else, emits an error message and returns the value
specified by ret_val.
TODO: explain <invert>
]]
local function is_valid_parameter_value (value, name, possible, ret_val, invert)
if not utilities.is_set (value) then
return ret_val; -- an empty parameter is ok
end
if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table
return cfg.keywords_xlate[value]; -- return translation of parameter keyword
elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table
return value; -- return <value> as it is
else
utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message
return ret_val;
end
end
--[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >----------------------------------------
This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space
when the last character is not a sepc character or when the last three characters are not sepc followed by two
closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a
single space character.
]]
local function terminate_name_list (name_list, sepc)
if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated
return name_list; -- just return the name list
elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char
return name_list .. " "; -- don't add another
else
return name_list .. sepc .. ' '; -- otherwise terminate the name list
end
end
--[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >-----------------------------------------
returns the concatenation of the formatted volume and issue (or journal article number) parameters as a single
string; or formatted volume or formatted issue, or an empty string if neither are set.
]]
local function format_volume_issue (volume, issue, article, cite_class, origin, sepc, lower)
if not utilities.is_set (volume) and not utilities.is_set (issue) and not utilities.is_set (article) then
return '';
end
-- same condition as in format_pages_sheets()
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits?
local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters?
if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters?
utilities.add_prop_cat ('long-vol'); -- yes, add properties cat
end
if is_journal then -- journal-style formatting
local vol = '';
if utilities.is_set (volume) then
if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals?
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face
elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters?
vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold
else -- four or fewer characters
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold
end
end
vol = vol .. (utilities.is_set (issue) and utilities.substitute (cfg.messages['j-issue'], issue) or '')
vol = vol .. (utilities.is_set (article) and utilities.substitute (cfg.messages['j-article-num'], article) or '')
return vol;
end
if 'podcast' == cite_class and utilities.is_set (issue) then
return wrap_msg ('issue', {sepc, issue}, lower);
end
if 'conference' == cite_class and utilities.is_set (article) then -- |article-number= supported only in journal and conference cites
if utilities.is_set (volume) and utilities.is_set (article) then -- both volume and article number
return wrap_msg ('vol-art', {sepc, utilities.hyphen_to_dash (volume), article}, lower);
elseif utilities.is_set (article) then -- article number alone; when volume alone, handled below
return wrap_msg ('art', {sepc, article}, lower);
end
end
-- all other types of citation
if utilities.is_set (volume) and utilities.is_set (issue) then
return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower);
elseif utilities.is_set (volume) then
return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower);
else
return wrap_msg ('issue', {sepc, issue}, lower);
end
end
--[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >-----------------------------------------
adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings.
The return order is:
page, pages, sheet, sheets
Singular has priority over plural when both are provided.
]]
local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower)
if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators
if utilities.is_set (sheet) then
if 'journal' == origin then
return '', '', wrap_msg ('j-sheet', sheet, lower), '';
else
return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), '';
end
elseif utilities.is_set (sheets) then
if 'journal' == origin then
return '', '', '', wrap_msg ('j-sheets', sheets, lower);
else
return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower);
end
end
end
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
if utilities.is_set (page) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', '';
elseif not nopp then
return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', '';
else
return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', '';
end
elseif utilities.is_set (pages) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', '';
elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number
return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', '';
elseif not nopp then
return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', '';
else
return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', '';
end
end
return '', '', '', ''; -- return empty strings
end
--[[--------------------------< I N S O U R C E _ L O C _ G E T >----------------------------------------------
returns one of the in-source locators: page, pages, or at.
If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text
for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and
add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it?
TODO: add support for sheet and sheets?; streamline;
TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned
to a new name)?
]]
local function insource_loc_get (page, page_orig, pages, pages_orig, at)
local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?)
if utilities.is_set (page) then
if utilities.is_set (pages) or utilities.is_set (at) then
pages = ''; -- unset the others
at = '';
end
extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label
if ws_url then
page = external_link (ws_url, ws_label .. ' ', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page});
coins_pages = ws_label;
end
elseif utilities.is_set (pages) then
if utilities.is_set (at) then
at = ''; -- unset
end
extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label
if ws_url then
pages = external_link (ws_url, ws_label .. ' ', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages});
coins_pages = ws_label;
end
elseif utilities.is_set (at) then
ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label
if ws_url then
at = external_link (ws_url, ws_label .. ' ', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at});
coins_pages = ws_label;
end
end
return page, pages, at, coins_pages;
end
--[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------
add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value
]]
local function is_unique_archive_url (archive, url, c_url, source, date)
if utilities.is_set (archive) then
if archive == url or archive == c_url then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message
return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url=
end
end
return archive, date;
end
--[=[-------------------------< A R C H I V E _ U R L _ C H E C K >--------------------------------------------
Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the
save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...)
archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow
unwitting readers to do.
When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own
algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results.
This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and
|archive-date= and an error message when:
|archive-url= holds an archive.org save command URL
|archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the
correct place
otherwise returns |archive-url= and |archive-date=
There are two mostly compatible archive.org URLs:
//web.archive.org/<timestamp>... -- the old form
//web.archive.org/web/<timestamp>... -- the new form
The old form does not support or map to the new form when it contains a display flag. There are four identified flags
('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore)
we don't check for these specific flags but we do check the form.
This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified
archive URL:
for save command errors, return undated wildcard (/*/)
for timestamp errors when the timestamp has a wildcard, return the URL unmodified
for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/)
A secondary function is to return an archive-url timestamp from those archive urls that have them. The timestamp
is used by validation.archive_date_check() to see if the value in |archive-date= matches the timestamp in the
archive url.
]=]
local function archive_url_check (url, date)
local err_msg = ''; -- start with the error message empty
local path, timestamp, flag; -- portions of the archive.org URL
local function is_ts_date_valid (timestamp, origin_date) -- local function to validate archive url taimestamp date; time ignored
local y, m, d = timestamp:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- split into parts
if y and validation.is_valid_date (y, m, d) and (tonumber (y) >= 1996) then
return true, tonumber (y) >= origin_date; -- <origin_date> is 1996 for archive.org
end
end
if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL
return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate
end
if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page
err_msg = cfg.err_msg_supl.save;
url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL
elseif url:match('//liveweb%.archive%.org/') then
err_msg = cfg.err_msg_supl.liveweb;
else
path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation
if not path then -- malformed in some way; pattern did not match
err_msg = cfg.err_msg_supl.timestamp;
elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here
err_msg = cfg.err_msg_supl.timestamp;
if '*' ~= flag then
local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY)
if replacement then -- nil if there aren't at least 4 digits (year)
replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp
url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display
end
end
elseif not is_ts_date_valid (timestamp, 1996) then -- is ymd portion of timestamp a valid date?
err_msg = cfg.err_msg_supl.timestamp;
timestamp = nil; -- unset because invalid
elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element
err_msg = cfg.err_msg_supl.path;
elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
else
return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
end
end
-- if here, something not right so
utilities.set_message ('err_archive_url', {err_msg}); -- add error message and
if is_preview_mode then
return url, date, timestamp; -- preview mode so return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
else
return '', ''; -- return empty strings for ArchiveURL and ArchiveDate
end
end
--[[--------------------------< P L A C E _ C H E C K >--------------------------------------------------------
check |place=, |publication-place=, |location= to see if these params include digits. This function added because
many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that)
returns the original parameter value without modification; added maint cat when parameter value contains digits
]]
local function place_check (param_val)
if not utilities.is_set (param_val) then -- parameter empty or omitted
return param_val; -- return that empty state
end
if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value
utilities.set_message ('maint_location'); -- yep, add maint cat
end
return param_val; -- and done
end
--[[--------------------------< I S _ A R C H I V E D _ C O P Y >----------------------------------------------
compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else
]]
local function is_archived_copy (title)
title = mw.ustring.lower(title); -- switch title to lower case
if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy'
return true;
elseif cfg.special_case_translation.archived_copy['local'] then
if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script
return true;
end
end
end
--[[--------------------------< D I S P L A Y _ N A M E S _ S E L E C T >--------------------------------------
for any of the |display-authors=, |display-editors=, etc parameters, select either the local or global setting.
When both are present, look at <local_display_names> value. When the value is some sort of 'et al.'string,
special handling is required.
When {{cs1 config}} has |display-<namelist>= AND this template has |display-<namelist>=etal AND:
the number of names specified by <number_of_names> is:
greater than the number specified in the global |display-<namelist>= parameter (<global_display_names>)
use global |display-<namelist>= parameter value
set overridden maint category
less than or equal to the number specified in the global |display-<namelist>= parameter
use local |display-<namelist>= parameter value
The purpose of this function is to prevent categorizing a template that has fewer names than the global setting
to keep the etal annotation specified by <local_display_names>.
]]
local function display_names_select (global_display_names, local_display_names, param_name, number_of_names, test)
if global_display_names and utilities.is_set (local_display_names) then -- when both
if 'etal' == local_display_names:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
number_of_names = tonumber (number_of_names); -- convert these to numbers for comparison
local global_display_names_num = tonumber (global_display_names); -- <global_display_names> not set when parameter value is not digits
if number_of_names > global_display_names_num then -- template has more names than global config allows to be displayed?
utilities.set_message ('maint_overridden_setting'); -- set a maint message because global is overriding local |display-<namelist>=etal
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local because fewer names so let <local_display_names> control
end
end
-- here when <global_display_names> and <local_display_names> both numbers; <global_display_names> controls
utilities.set_message ('maint_overridden_setting'); -- set a maint message
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
end
-- here when only one of <global_display_names> or <local_display_names> set
if global_display_names then
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local
end
end
--[[--------------------------< M O D E _ S E T >--------------------------------------------------------------
fetch global mode setting from {{cs1 config}} (if present) or from |mode= (if present); global setting overrides
local |mode= parameter value. When both are present, emit maintenance message
]]
local function mode_set (Mode, Mode_origin)
local mode;
if cfg.global_cs1_config_t['Mode'] then -- global setting in {{cs1 config}}; nil when empty or assigned value invalid
mode = is_valid_parameter_value (cfg.global_cs1_config_t['Mode'], 'cs1 config: mode', cfg.keywords_lists['mode'], ''); -- error messaging 'param' here is a hoax
else
mode = is_valid_parameter_value (Mode, Mode_origin, cfg.keywords_lists['mode'], '');
end
if cfg.global_cs1_config_t['Mode'] and utilities.is_set (Mode) then -- when template has |mode=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
return mode;
end
--[[--------------------------< Q U O T E _ M A K E >----------------------------------------------------------
create quotation from |quote=, |trans-quote=, and/or script-quote= with or without |quote-page= or |quote-pages=
when any of those three quote parameters are set, this function unsets <PostScript>. When none of those parameters
are set, |quote-page= and |quote-pages= are unset to nil so that they are not included in the template's metadata
]]
local function quote_make (quote, trans_quote, script_quote, quote_page, quote_pages, nopp, sepc, postscript)
if utilities.is_set (quote) or utilities.is_set (trans_quote) or utilities.is_set (script_quote) then
if utilities.is_set (quote) then
if quote:sub(1, 1) == '"' and quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks
quote = quote:sub(2, -2); -- strip them off
end
end
quote = kern_quotes (quote); -- kern if needed
quote = utilities.wrap_style ('quoted-text', quote ); -- wrap in <q>...</q> tags
if utilities.is_set (script_quote) then
quote = script_concatenate (quote, script_quote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped
end
if utilities.is_set (trans_quote) then
if trans_quote:sub(1, 1) == '"' and trans_quote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks
trans_quote = trans_quote:sub(2, -2); -- strip them off
end
quote = quote .. " " .. utilities.wrap_style ('trans-quoted-title', trans_quote );
end
if utilities.is_set (quote_page) or utilities.is_set (quote_pages) then -- add page prefix
local quote_prefix = '';
if utilities.is_set (quote_page) then
extra_text_in_page_check (quote_page, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc.
if not nopp then
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, quote_page}), '', '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, quote_page}), '', '', '';
end
elseif utilities.is_set (quote_pages) then
extra_text_in_page_check (quote_pages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc.
if tonumber(quote_pages) ~= nil and not nopp then -- if only digits, assume single page
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, quote_pages}), '', '';
elseif not nopp then
quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, quote_pages}), '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, quote_pages}), '', '';
end
end
quote = quote_prefix .. ": " .. quote;
else
quote = sepc .. " " .. quote;
end
postscript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set
elseif utilities.is_set (quote_page) or utilities.is_set (quote_pages) then
quote_page = nil; -- unset; these require |quote=; TODO: error message?
quote_pages = nil;
end
return quote, quote_page, quote_pages, postscript;
end
--[[--------------------------< C H E C K _ P U B L I S H E R _ N A M E >--------------------------------------
look for variations of '<text>: <text>' that might be '<location>: <publisher>' in |publisher= parameter value.
when found, emit a maintenance message; return nil else
<publisher> is the value assigned to |publisher= or |institution=
]]
local function check_publisher_name (publisher)
local patterns_t = {
'^[%w%s]+%s*:%s*[%w%s]+$', -- plain text <location>: <publisher>
'^%[+[%w%s:|]+%]+%s*:%s*[%w%s]+$', -- partially wikilinked [[<location>]]: <publisher>
'^[%w%s]+%s*:%s*%[+[%w%s:|]+%]+$', -- partially wikilinked <location>: [[<publisher>]]
'^%[+[%w%s:|]+%]+%s*:%s*%[+[%w%s:|]+%]+$', -- wikilinked [[<location>]]: [[<publisher>]]
}
for _, pattern in ipairs (patterns_t) do -- spin through the patterns_t sequence
if mw.ustring.match (publisher, pattern) then -- does this pattern match?
utilities.set_message ('maint_publisher_location'); -- set a maint message
return; -- and done
end
end
end
--[[--------------------------< I S _ P A G E _ A R T _ N U M >------------------------------------------------
compare the trailing (rightmost) characters of the |doi= value against the whole value assigned to |page(s)=.
return boolean true when:
|page(s)= has exactly 8 digits and a dot between the fourth and fifth digits matches the trailing 9 characters
of the |doi= value: |page=12345678 → |page=1234.5678 matches |doi=10.xxxx/yyyy1234.5678
|page(s)= is 5 or more characters and matches |doi= values's trailing characters
|page(s)= begins with a lowercase 'e' and |page(s)= without the 'e' matches |doi= values's trailing
characters: |page=e12345 → |page=12345 matches |doi=10.xxxx/yyyy12345
|page(s)= begins with a uppercase 'CD' followed by (typically) six digits matches |doi= values that ends with
'CDxxxxxx.pubx' (where 'x' is any single digit)
return nil when |page(s)= values:
are ranges separated by underscore, hyphen, emdash, endash, figure dash, or minus character
are comma- or semicolon-separated lists of pages
have external urls (has text 'http')
are digit-only values less than 10000
do not match |doi= values's trailing characters
]]
local function is_page_art_num (page, doi)
if not (utilities.is_set (page) and utilities.is_set (doi)) then -- both required
return; -- abandon; nothing to do
end
if page:match ('[,;_−–—‒%-]') then -- when |page(s)= might be a page range or a separated list of pages
return; -- abandon
end
page = page:lower(); -- because doi names are case insensitive
doi = doi:lower(); -- force these to lowercase for testing
if page:match ('http') then -- when |page(s)= appears to hold a url
return; -- abandon
end
if tonumber (page) then -- is |page(s)= digits only
if 10000 > tonumber (page) then -- when |page(s)= less than 10000
return; -- abandon
end
if doi:match (page .. '$') then -- digits only page number match the last digits in |doi=?
return true;
end
if 8 == page:len() then -- special case when |page(s)= is exactly 8 digits
local dot_page = page:gsub ('(%d%d%d%d)(%d%d%d%d)', '%1.%2'); -- make a |page=xxxx.yyyy version commonly used in |doi=
if doi:match (dot_page .. '$') then -- 8-digit dotted page number match the last characters in |doi=?
return true;
end
end
else -- here when |page(s)= is alpha-numeric
if 4 < page:len() then -- when |page(s)= is five or more characters
if doi:match (page .. '$') then -- alpha-numeric page match the last characters in |doi=?
return true;
end
local epage = page:match ('^e([%w]+)$'); -- if first character of |page= is 'e', remove it
if epage and doi:match (epage .. '$') then -- page number match the last characters in |doi=?
return true;
end
local cdpage = page:match ('^cd%d+$'); -- if first characters of |page= are 'CD' and last characters are digits (typically 6 digits)
if cdpage and doi:match (cdpage .. '%.pub%d$') then -- page number matches doi 'CDxxxxxx.pubx' where 'x' is a digit
return true;
end
end
end
end
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
This is the main function doing the majority of the citation formatting.
]]
local function citation0( config, args )
--[[
Load Input Parameters
The argument_wrapper facilitates the mapping of multiple aliases to single internal variable.
]]
local A = argument_wrapper ( args );
local i
-- Pick out the relevant fields from the arguments. Different citation templates
-- define different field names for the same underlying things.
local author_etal;
local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors=
local Authors;
local NameListStyle;
if cfg.global_cs1_config_t['NameListStyle'] then -- global setting in {{cs1 config}} overrides local |name-list-style= parameter value; nil when empty or assigned value invalid
NameListStyle = is_valid_parameter_value (cfg.global_cs1_config_t['NameListStyle'], 'cs1 config: name-list-style', cfg.keywords_lists['name-list-style'], ''); -- error messaging 'param' here is a hoax
else
NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], '');
end
if cfg.global_cs1_config_t['NameListStyle'] and utilities.is_set (A['NameListStyle']) then -- when template has |name-list-style=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
local Collaboration = A['Collaboration'];
do -- to limit scope of selected
local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList');
if 1 == selected then
a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn=
elseif 3 == selected then
Authors = A['Authors']; -- use content of |people= or |credits=; |authors= is deprecated; TODO: constrain |people= and |credits= to cite av media, episode, serial?
end
if utilities.is_set (Collaboration) then
author_etal = true; -- so that |display-authors=etal not required
end
end
local editor_etal;
local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors=
do -- to limit scope of selected
local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn
if 1 == selected then
e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn=
end
end
local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= and |script-chapter= aliases
local Chapter_origin = A:ORIGIN ('Chapter');
local ScriptChapter = A['ScriptChapter'];
local ScriptChapter_origin = A:ORIGIN ('ScriptChapter');
local Contribution; -- because contribution is required for contributor(s)
if 'contribution' == Chapter_origin then -- is there a |contribution= parameter?
Contribution = Chapter; -- get the name of the contribution
elseif 'script-contribution' == ScriptChapter_origin then -- no, so is there a |script-contribution= parameter?
Contribution = ScriptChapter; -- get the name of the contribution
end
local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (A['Periodical']) then -- |contributor= and |contribution= only supported in book cites
c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn=
if 0 < #c then
if not utilities.is_set (Contribution) then -- |contributor= requires |contribution=
utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
if 0 == #a then -- |contributor= requires |author=
utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
end
else -- if not a book cite
if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters?
utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message
end
Contribution = nil; -- unset
end
local Title = A['Title'];
local TitleLink = A['TitleLink'];
local auto_select = ''; -- default is auto
local accept_link;
TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup
if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords
auto_select = TitleLink; -- remember selection for later
TitleLink = ''; -- treat as if |title-link= would have been empty
end
TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set
local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used
if 'map' == config.CitationClass and 'section' == Chapter_origin then
Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}}
Chapter = ''; -- unset for now; will be reset later from |map= if present
end
local Periodical = A['Periodical'];
local Periodical_origin = A:ORIGIN('Periodical');
local ScriptPeriodical = A['ScriptPeriodical'];
local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical');
local TransPeriodical = A['TransPeriodical'];
local TransPeriodical_origin = A:ORIGIN ('TransPeriodical');
if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical))) then
local param;
if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters
Periodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = Periodical_origin -- get parameter name for error messaging
elseif utilities.is_set (TransPeriodical) then
TransPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = TransPeriodical_origin; -- get parameter name for error messaging
elseif utilities.is_set (ScriptPeriodical) then
ScriptPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = ScriptPeriodical_origin; -- get parameter name for error messaging
end
if utilities.is_set (param) then -- if we found one
utilities.set_message ('err_periodical_ignored', {param}); -- emit an error message
end
end
if utilities.is_set (Periodical) then
local i;
Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated
if i then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {Periodical_origin});
end
end
if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}}
if utilities.is_set (Periodical) and utilities.is_set (A ['MailingList']) then -- both set emit an error TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'mailinglist')});
end
Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}}
Periodical_origin = A:ORIGIN('MailingList');
end
-- web and news not tested for now because of
-- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors?
if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter
-- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message
local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message
if p[config.CitationClass] then
utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]});
end
end
local Volume;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) then
if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used
Volume = A['Volume']; -- but does for all other 'periodicals'
end
elseif utilities.is_set (ScriptPeriodical) then
if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website=
Volume = A['Volume']; -- but does for all other 'periodicals'
end
else
Volume = A['Volume']; -- and does for non-'periodical' cites
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings
Volume = A['Volume'];
end
extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v');
local Issue;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used
Issue = A['Issue'];
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table
if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then
Issue = A['Issue'];
end
end
local ArticleNumber;
if utilities.in_array (config.CitationClass, {'journal', 'conference'}) or ('citation' == config.CitationClass and utilities.is_set (Periodical) and 'journal' == Periodical_origin) then
ArticleNumber = A['ArticleNumber'];
end
extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i');
Issue = utilities.hyphen_to_dash (Issue);
local Page;
local Pages;
local At;
local QuotePage;
local QuotePages;
if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then -- TODO: rewrite to emit ignored parameter error message?
Page = A['Page'];
Pages = utilities.hyphen_to_dash (A['Pages']);
At = A['At'];
QuotePage = A['QuotePage'];
QuotePages = utilities.hyphen_to_dash (A['QuotePages']);
end
local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil);
local Mode = mode_set (A['Mode'], A:ORIGIN('Mode'));
-- separator character and postscript
local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass);
local Quote;
Quote, QuotePage, QuotePages, PostScript = quote_make (A['Quote'], A['TransQuote'], A['ScriptQuote'], QuotePage, QuotePages, NoPP, sepc, PostScript);
local Edition = A['Edition'];
local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace'));
local Place = place_check (A['Place'], A:ORIGIN('Place'));
local PublisherName = A['PublisherName'];
local PublisherName_origin = A:ORIGIN('PublisherName');
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then
local i = 0;
PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized
if i and (0 < i) then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {PublisherName_origin});
end
end
if ('document' == config.CitationClass) and not utilities.is_set (PublisherName) then
utilities.set_message ('err_missing_publisher', {config.CitationClass, 'publisher'});
end
local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup?
local Newsgroup_origin = A:ORIGIN('Newsgroup');
if 'newsgroup' == config.CitationClass then
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup
utilities.set_message ('err_parameter_ignored', {PublisherName_origin});
end
PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS
end
if 'book' == config.CitationClass or 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and not utilities.is_set (Periodical)) then
local accept;
PublisherName, accept = utilities.has_accept_as_written (PublisherName); -- check for and remove accept-as-written markup from |publisher= wrapped
if not accept then -- when no accept-as-written markup
check_publisher_name (PublisherName); -- emit maint message when |publisher= might be prefixed with publisher's location
end
end
local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL?
local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then
UrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', 'url');
end
local ChapterURL = A['ChapterURL'];
local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then
ChapterUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')});
end
local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then
MapUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {'map-url'});
end
local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language
local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil);
-- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories
if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page
if cfg.uncategorized_namespaces[this_page.namespace] then -- is this page's namespace id one of the uncategorized namespace ids?
no_tracking_cats = "true"; -- set no_tracking_cats
end
for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns
if this_page.text:match (v) then -- test page name against each pattern
no_tracking_cats = "true"; -- set no_tracking_cats
break; -- bail out if one is found
end
end
end
-- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it)
utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category
local coins_pages;
Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At);
if utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- both |publication-place= and |place= (|location=) allowed if different
utilities.add_prop_cat ('location-test'); -- add property cat to evaluate how often PublicationPlace and Place are used together
if PublicationPlace == Place then
Place = ''; -- unset; don't need both if they are the same
end
elseif not utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- when only |place= (|location=) is set ...
PublicationPlace = Place; -- promote |place= (|location=) to |publication-place
end
if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same
local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL
local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL
-- local ScriptChapter = A['ScriptChapter'];
-- local ScriptChapter_origin = A:ORIGIN ('ScriptChapter');
local Format = A['Format'];
local ChapterFormat = A['ChapterFormat'];
local TransChapter = A['TransChapter'];
local TransChapter_origin = A:ORIGIN ('TransChapter');
local TransTitle = A['TransTitle'];
local ScriptTitle = A['ScriptTitle'];
--[[
Parameter remapping for cite encyclopedia:
When the citation has these parameters:
|encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title= for rendering
|encyclopedia= and |article= then map |encyclopedia= to |title= for rendering
|trans-title= maps to |trans-chapter= when |title= is re-mapped
|url= maps to |chapter-url= when |title= is remapped
All other combinations of |encyclopedia=, |title=, and |article= are not modified
]]
local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS
local ScriptEncyclopedia = A['ScriptEncyclopedia'];
local TransEncyclopedia = A['TransEncyclopedia'];
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}}
if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then
if utilities.is_set (Encyclopedia) then
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')});
else
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('ScriptEncyclopedia')});
end
Encyclopedia = nil; -- unset these because not supported by this template
ScriptEncyclopedia = nil;
TransEncyclopedia = nil;
end
elseif utilities.is_set (TransEncyclopedia) then
utilities.set_message ('err_trans_missing_title', {'encyclopedia'});
end
if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Periodical) and utilities.is_set (Encyclopedia) then -- when both parameters set emit an error message; {{citation}} only; Periodical not allowed in {{cite encyclopedia}}
utilities.set_message ('err_periodical_ignored', {Periodical_origin});
end
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then
Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia
Periodical_origin = A:ORIGIN ('Encyclopedia');
ScriptPeriodical = ScriptEncyclopedia;
ScriptPeriodical_origin = A:ORIGIN ('ScriptEncyclopedia');
if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then
if not utilities.is_set (Chapter) then
Chapter = Title; -- |encyclopedia= and |title= are set so map |title= params to |article= params for rendering
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle')
TransChapter = TransTitle;
ChapterURL = URL;
ChapterURL_origin = URL_origin;
ChapterUrlAccess = UrlAccess;
ChapterFormat = Format;
if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then
Chapter = utilities.make_wikilink (TitleLink, Chapter);
end
Title = Periodical; -- now map |encyclopedia= params to |title= params for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
URL = '';
Format = '';
TitleLink = '';
end
elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set
Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
end
end
end
-- special case for cite techreport.
local ID = A['ID'];
if (config.CitationClass == "techreport") then -- special case for cite techreport
if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue'
if not utilities.is_set (ID) then -- can we use ID for the "number"?
ID = A['Number']; -- yes, use it
else -- ID has a value so emit error message
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'number')});
end
end
end
-- Account for the oddity that is {{cite conference}}, before generation of COinS data.
local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode
local Conference = A['Conference'];
local BookTitle = A['BookTitle'];
local TransTitle_origin = A:ORIGIN ('TransTitle');
if 'conference' == config.CitationClass then
if utilities.is_set (BookTitle) then
Chapter = Title;
Chapter_origin = 'title';
-- ChapterLink = TitleLink; -- |chapter-link= is deprecated
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
URL_origin = '';
ChapterFormat = Format;
TransChapter = TransTitle;
TransChapter_origin = TransTitle_origin;
Title = BookTitle;
Format = '';
-- TitleLink = '';
TransTitle = '';
URL = '';
end
elseif 'speech' ~= config.CitationClass then
Conference = ''; -- not cite conference or cite speech so make sure this is empty string
end
local cs2_lower = function (text) -- if mode is cs2, use lower case
if (sepc ~= '.') then
return text:lower();
end
return text;
end
local use_lowercase = ( sepc == ',' ); -- controls capitalization of certain static text
-- cite map oddities
local Cartography = "";
local Scale = "";
local Sheet = A['Sheet'] or '';
local Sheets = A['Sheets'] or '';
if config.CitationClass == "map" then
if utilities.is_set (Chapter) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'map') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', Chapter_origin)}); -- add error message
end
Chapter = A['Map'];
Chapter_origin = A:ORIGIN('Map');
ChapterURL = A['MapURL'];
ChapterURL_origin = A:ORIGIN('MapURL');
TransChapter = A['TransMap'];
ScriptChapter = A['ScriptMap']
ScriptChapter_origin = A:ORIGIN('ScriptMap')
ChapterUrlAccess = MapUrlAccess;
ChapterFormat = A['MapFormat'];
Cartography = A['Cartography'];
if utilities.is_set ( Cartography ) then
Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase);
end
Scale = A['Scale'];
if utilities.is_set ( Scale ) then
Scale = sepc .. " " .. Scale;
end
end
-- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data.
local Series = A['Series'];
if 'episode' == config.CitationClass or 'serial' == config.CitationClass then
local SeriesLink = A['SeriesLink'];
SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set
local Network = A['Network'];
local Station = A['Station'];
local s, n = {}, {};
-- do common parameters first
if utilities.is_set (Network) then table.insert(n, Network); end
if utilities.is_set (Station) then table.insert(n, Station); end
ID = table.concat(n, sepc .. ' ');
if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}}
local Season = A['Season'];
local SeriesNumber = A['SeriesNumber'];
if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message
SeriesNumber = ''; -- unset; prefer |season= over |seriesno=
end
-- assemble a table of parts concatenated later into Series
if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end
if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end
if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end
Issue = ''; -- unset because this is not a unique parameter
Chapter = Title; -- promote title parameters to chapter
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle');
ChapterLink = TitleLink; -- alias |episode-link=
TransChapter = TransTitle;
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
ChapterFormat = Format;
Title = Series; -- promote series to title
TitleLink = SeriesLink;
Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number
if utilities.is_set (ChapterLink) and not utilities.is_set (ChapterURL) then -- link but not URL
Chapter = utilities.make_wikilink (ChapterLink, Chapter);
elseif utilities.is_set (ChapterLink) and utilities.is_set (ChapterURL) then -- if both are set, URL links episode;
Series = utilities.make_wikilink (ChapterLink, Series);
end
URL = ''; -- unset
TransTitle = '';
ScriptTitle = '';
Format = '';
else -- now oddities that are cite serial
Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial
Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday?
if utilities.is_set (Series) and utilities.is_set (SeriesLink) then
Series = utilities.make_wikilink (SeriesLink, Series);
end
Series = utilities.wrap_style ('italic-title', Series); -- series is italicized
end
end
-- end of {{cite episode}} stuff
-- handle type parameter for those CS1 citations that have default values
local TitleType = A['TitleType'];
local Degree = A['Degree'];
if utilities.in_array (config.CitationClass, {'AV-media-notes', 'document', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then
TitleType = set_titletype (config.CitationClass, TitleType);
if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis
TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower();
end
end
if utilities.is_set (TitleType) then -- if type parameter is specified
TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses
-- TODO: Hack on TitleType to fix bunched parentheses problem
end
-- legacy: promote PublicationDate to Date if neither Date nor Year are set.
local Date = A['Date'];
local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging
local PublicationDate = A['PublicationDate'];
local Year = A['Year'];
if utilities.is_set (Year) then
validation.year_check (Year); -- returns nothing; emits maint message when |year= doesn't hold a 'year' value
end
if not utilities.is_set (Date) then
Date = Year; -- promote Year to Date
Year = nil; -- make nil so Year as empty string isn't used for CITEREF
if not utilities.is_set (Date) and utilities.is_set (PublicationDate) then -- use PublicationDate when |date= and |year= are not set
Date = PublicationDate; -- promote PublicationDate to Date
PublicationDate = ''; -- unset, no longer needed
Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter
else
Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter
end
else
Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging
end
if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation
--[[
Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where
we get the date used in the metadata.
Date validation supporting code is in Module:Citation/CS1/Date_validation
]]
local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], '');
if not utilities.is_set (DF) then
DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template
end
local ArchiveURL;
local ArchiveDate;
local ArchiveFormat = A['ArchiveFormat'];
local archive_url_timestamp; -- timestamp from wayback machine url
ArchiveURL, ArchiveDate, archive_url_timestamp = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url');
ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL
local AccessDate = A['AccessDate'];
local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification
local DoiBroken = A['DoiBroken'];
local Embargo = A['Embargo'];
local anchor_year; -- used in the CITEREF identifier
do -- create defined block to contain local variables error_message, date_parameters_list, mismatch
local error_message = '';
-- AirDate has been promoted to Date so not necessary to check it
local date_parameters_list = {
['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')},
['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')},
['date'] = {val = Date, name = Date_origin},
['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')},
['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')},
['publication-date'] = {val = PublicationDate, name = A:ORIGIN ('PublicationDate')},
['year'] = {val = Year, name = A:ORIGIN ('Year')},
};
local error_list = {};
anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list);
if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed;
validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list);
end
if 0 == #error_list then -- error free dates only; 0 when error_list is empty
local modified = false; -- flag
if utilities.is_set (DF) then -- if we need to reformat dates
modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate
end
if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate
modified = true;
utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category
end
-- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki
if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then
utilities.set_message ('maint_date_auto_xlated'); -- add maint cat
modified = true;
end
if modified then -- if the date_parameters_list values were modified
AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values
ArchiveDate = date_parameters_list['archive-date'].val;
Date = date_parameters_list['date'].val;
DoiBroken = date_parameters_list['doi-broken-date'].val;
PublicationDate = date_parameters_list['publication-date'].val;
end
if archive_url_timestamp and utilities.is_set (ArchiveDate) then
validation.archive_date_check (ArchiveDate, archive_url_timestamp, DF); -- does YYYYMMDD in archive_url_timestamp match date in ArchiveDate
end
else
utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message
end
end -- end of do
if utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or -- {{cite book}}, {{cite encyclopedia}}; TODO: {{cite conference}} and others?
('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) or -- {{citation}} as an encylopedia citation
('citation' == config.CitationClass and not utilities.is_set (Periodical)) then -- {{citation}} as a book citation
if utilities.is_set (PublicationPlace) then
if not utilities.is_set (PublisherName) then
local date = COinS_date.rftdate and tonumber (COinS_date.rftdate:match ('%d%d%d%d')); -- get year portion of COinS date (because in Arabic numerals); convert string to number
if date and (1850 <= date) then -- location has no publisher; if date is 1850 or later
utilities.set_message ('maint_location_no_publisher'); -- add maint cat
end
else -- PublisherName has a value
if cfg.keywords_xlate['none'] == PublisherName then -- if that value is 'none' (only for book and encyclopedia citations)
PublisherName = ''; -- unset
end
end
end
end
local ID_list = {}; -- sequence table of rendered identifiers
local ID_list_coins = {}; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key
local Class = A['Class']; -- arxiv class identifier
local ID_support = {
{A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')},
{DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')},
{Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')},
}
ID_list, ID_list_coins = identifiers.identifier_lists_get (args, {
DoiBroken = DoiBroken, -- for |doi=
ASINTLD = A['ASINTLD'], -- for |asin=
Embargo = Embargo, -- for |pmc=
Class = Class, -- for |arxiv=
CitationClass = config.CitationClass, -- for |arxiv=
Year=anchor_year, -- for |isbn=
}, ID_support);
if 'citation' == config.CitationClass then -- catch ve/citoid malformed book cites in {{citation}} templates
for _, id in ipairs (ID_list) do -- search through the ID_list sequence looking for an ISBN identifier string
if id:find ('ISBN', 3, true) then -- plain find, start at index 3 ([[ISBN)
if utilities.is_set (Periodical) then -- when a |work= alias is set
utilities.set_message ('maint_work_isbn'); -- add maint cat
end
end
end
end
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, {{cite ssrn}}, before generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv=, |citeseerx=, |medrxiv=, |ssrn= required for their templates
if not (args[cfg.id_handlers[config.CitationClass:upper()].parameters[1]] or -- can't use ID_list_coins k/v table here because invalid parameters omitted
args[cfg.id_handlers[config.CitationClass:upper()].parameters[2]]) then -- which causes unexpected parameter missing error message
utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message
end
Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['medrxiv'] = 'medRxiv', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass];
end
-- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free
if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead
if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled
if identifiers.auto_link_urls[auto_select] then -- manual selection
URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link
URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC
URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed
URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI
URL = identifiers.auto_link_urls['doi'];
URL_origin = cfg.id_handlers['DOI'].parameters[1];
end
end
if utilities.is_set (URL) then -- set when using an identifier-created URL
if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_accessdate_missing_url'); -- add an error message
AccessDate = ''; -- unset
end
if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_archive_missing_url'); -- add an error message
ArchiveURL = ''; -- unset
end
end
end
-- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
-- Test if citation has no title
if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode
utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'});
end
if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and
utilities.in_array (config.CitationClass, {'journal', 'citation'}) and
(utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and
('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites
Title = ''; -- set title to empty string
utilities.set_message ('maint_untitled'); -- add maint cat
end
if 'journal' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Periodical) and 'journal' == Periodical_origin) then
if is_page_art_num (((utilities.is_set (Page) and Page) or (utilities.is_set (Pages) and Pages)) or nil, ID_list_coins['DOI']) then -- does |page(s)= look like it holds an article number
utilities.set_message ('maint_page_art_num'); -- add maint cat
end
end
-- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information.
-- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that
-- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title
-- is the article title, and Chapter is a section within the article. So, we remap
local coins_chapter = Chapter; -- default assuming that remapping not required
local coins_title = Title; -- et tu
if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then
coins_chapter = Title; -- remap
coins_title = Periodical;
end
end
local coins_author = a; -- default for coins rft.au
if 0 < #c then -- but if contributor list
coins_author = c; -- use that instead
end
-- this is the function call to COinS()
local OCinSoutput = metadata.COinS({
['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata
['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS
['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup
['Degree'] = Degree; -- cite thesis only
['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup
['PublicationPlace'] = PublicationPlace,
['Date'] = COinS_date.rftdate, -- COinS_date.* has correctly formatted date values if Date is valid;
['Season'] = COinS_date.rftssn,
['Quarter'] = COinS_date.rftquarter,
['Chron'] = COinS_date.rftchron,
['Series'] = Series,
['Volume'] = Volume,
['Issue'] = Issue,
['ArticleNumber'] = ArticleNumber,
['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links
['Edition'] = Edition,
['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName
['URL'] = first_set ({ChapterURL, URL}, 2),
['Authors'] = coins_author,
['ID_list'] = ID_list_coins,
['RawPage'] = this_page.prefixedText,
}, config.CitationClass);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, and {{cite ssrn}} AFTER generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, medRxiv, or ssrn now unset so it isn't displayed
Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal
end
-- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text
if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then
PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil ));
end
local Editors;
local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list
local Contributors; -- assembled contributors name list
local contributor_etal;
local Translators; -- assembled translators name list
local translator_etal;
local t = {}; -- translators list from |translator-lastn= / translator-firstn= pairs
t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn=
local Interviewers;
local interviewers_list = {};
interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters
local interviewer_etal;
-- Now perform various field substitutions.
-- We also add leading spaces and surrounding markup and punctuation to the
-- various parts of the citation, but only when they are non-nil.
do
local last_first_list;
local control = {
format = NameListStyle, -- empty string, '&', 'amp', 'and', or 'vanc'
maximum = nil, -- as if display-authors or display-editors not set
mode = Mode
};
do -- do editor name list first because the now unsupported coauthors used to modify control table
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayEditors'], A['DisplayEditors'], A:ORIGIN ('DisplayEditors'), #e);
control.maximum, editor_etal = get_display_names (display_names, #e, 'editors', editor_etal, param);
Editors, EditorCount = list_people (control, e, editor_etal);
if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then
EditorCount = 2; -- spoof to display (eds.) annotation
end
end
do -- now do interviewers
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayInterviewers'], A['DisplayInterviewers'], A:ORIGIN ('DisplayInterviewers'), #interviewers_list);
control.maximum, interviewer_etal = get_display_names (display_names, #interviewers_list, 'interviewers', interviewer_etal, param);
Interviewers = list_people (control, interviewers_list, interviewer_etal);
end
do -- now do translators
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayTranslators'], A['DisplayTranslators'], A:ORIGIN ('DisplayTranslators'), #t);
control.maximum, translator_etal = get_display_names (display_names, #t, 'translators', translator_etal, param);
Translators = list_people (control, t, translator_etal);
end
do -- now do contributors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayContributors'], A['DisplayContributors'], A:ORIGIN ('DisplayContributors'), #c);
control.maximum, contributor_etal = get_display_names (display_names, #c, 'contributors', contributor_etal, param);
Contributors = list_people (control, c, contributor_etal);
end
do -- now do authors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayAuthors'], A['DisplayAuthors'], A:ORIGIN ('DisplayAuthors'), #a, author_etal);
control.maximum, author_etal = get_display_names (display_names, #a, 'authors', author_etal, param);
last_first_list = list_people (control, a, author_etal);
if utilities.is_set (Authors) then
Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al.
if author_etal then
Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter
end
else
Authors = last_first_list; -- either an author name list or an empty string
end
end -- end of do
if utilities.is_set (Authors) and utilities.is_set (Collaboration) then
Authors = Authors .. ' (' .. Collaboration .. ')'; -- add collaboration after et al.
end
end
local ConferenceFormat = A['ConferenceFormat'];
local ConferenceURL = A['ConferenceURL'];
ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url');
Format = style_format (Format, URL, 'format', 'url');
-- special case for chapter format so no error message or cat when chapter not supported
if not (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia))) then
ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url');
end
if not utilities.is_set (URL) then
if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for {{cite web}}, {{cite podcast}}, and {{cite mailing list}}
('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website=
if not url_was_archive_today then -- is <URL> empty/missing because it was a deprecated archive.today url
utilities.set_message ('err_cite_web_url'); -- no; emit an error message for an empty/ missing |url=
end
end
-- do we have |accessdate= without either |url= or |chapter-url=?
if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set;
utilities.set_message ('err_accessdate_missing_url');
AccessDate = '';
end
end
local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], '');
local OriginalURL
local OriginalURL_origin
local OriginalFormat
local OriginalAccess;
UrlStatus = UrlStatus:lower(); -- used later when assembling archived text
if utilities.is_set ( ArchiveURL ) then
if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it
OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text
OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages
OriginalFormat = ChapterFormat; -- and original |chapter-format=
if 'live' ~= UrlStatus then
ChapterURL = ArchiveURL -- swap-in the archive's URL
ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages
ChapterFormat = ArchiveFormat or ''; -- swap in archive's format
ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
elseif utilities.is_set (URL) then
OriginalURL = URL; -- save copy of original source URL
OriginalURL_origin = URL_origin; -- name of URL parameter for error messages
OriginalFormat = Format; -- and original |format=
OriginalAccess = UrlAccess;
if 'live' ~= UrlStatus then -- if URL set then |archive-url= applies to it
URL = ArchiveURL -- swap-in the archive's URL
URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages
Format = ArchiveFormat or ''; -- swap in archive's format
UrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
end
elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set
utilities.set_message ('maint_url_status'); -- add maint cat
end
if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) then
local chap_param;
if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters
chap_param = A:ORIGIN ('Chapter')
elseif utilities.is_set (TransChapter) then
chap_param = A:ORIGIN ('TransChapter')
elseif utilities.is_set (ChapterURL) then
chap_param = A:ORIGIN ('ChapterURL')
elseif utilities.is_set (ScriptChapter) then
chap_param = ScriptChapter_origin;
else utilities.is_set (ChapterFormat)
chap_param = A:ORIGIN ('ChapterFormat')
end
if utilities.is_set (chap_param) then -- if we found one
utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message
Chapter = ''; -- and set them to empty string to be safe with concatenation
TransChapter = '';
ChapterURL = '';
ScriptChapter = '';
ChapterFormat = '';
end
else -- otherwise, format chapter / article title
local no_quotes = false; -- default assume that we will be quoting the chapter parameter value
if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s)
if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title
no_quotes = true; -- then render it unquoted
end
end
Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter
if utilities.is_set (Chapter) then
Chapter = Chapter .. ChapterFormat ;
if 'map' == config.CitationClass and utilities.is_set (TitleType) then
Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title
end
Chapter = Chapter .. sepc .. ' ';
elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ...
Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it
end
end
-- Format main title
local plain_title = false;
local accept_title;
Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title>
if accept_title and ('' == Title) then -- only support forced empty for now "(())"
Title = cfg.messages['notitle']; -- replace by predefined "No title" message
-- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting
ScriptTitle = ''; -- just mute for now
TransTitle = ''; -- just mute for now
plain_title = true; -- suppress text decoration for descriptive title
utilities.set_message ('maint_untitled'); -- add maint cat
end
if not accept_title then -- <Title> not wrapped in accept-as-written markup
if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title=
Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three
elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ...
not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.)
Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters
end
if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then
utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title
end
if is_generic ('generic_titles', Title) then
utilities.set_message ('err_generic_title'); -- set an error message
end
end
if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'document', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) or
('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article
Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks
Title = utilities.wrap_style ('quoted-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle );
elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above)
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title
else
Title = utilities.wrap_style ('italic-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle);
end
if utilities.is_set (TransTitle) then
if utilities.is_set (Title) then
TransTitle = " " .. TransTitle;
else
utilities.set_message ('err_trans_missing_title', {'title'});
end
end
if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs?
if utilities.is_set (TitleLink) and utilities.is_set (URL) then
utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both
TitleLink = ''; -- unset
end
if not utilities.is_set (TitleLink) and utilities.is_set (URL) then
Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format;
URL = ''; -- unset these because no longer needed
Format = "";
elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then
local ws_url;
ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here
if ws_url then
Title = external_link (ws_url, Title .. ' ', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title});
Title = Title .. TransTitle;
else
Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle;
end
else
local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink)
ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label
if ws_url then
Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup
Title = external_link (ws_url, Title .. ' ', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title});
Title = Title .. TransTitle;
else
Title = Title .. TransTitle;
end
end
else
Title = TransTitle;
end
if utilities.is_set (Place) then
Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " ";
end
local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL
if utilities.is_set (Conference) then
if utilities.is_set (ConferenceURL) then
Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil );
end
Conference = sepc .. " " .. Conference .. ConferenceFormat;
elseif utilities.is_set (ConferenceURL) then
Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil );
end
local Position = '';
if not utilities.is_set (Position) then
local Minutes = A['Minutes'];
local Time = A['Time'];
if utilities.is_set (Minutes) then
if utilities.is_set (Time) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')});
end
Position = utilities.substitute (cfg.messages.minutes, Minutes);
else
if utilities.is_set (Time) then
local TimeCaption = A['TimeCaption']
if not utilities.is_set (TimeCaption) then
TimeCaption = cs2_lower(cfg.messages['event']);
end
Position = " " .. TimeCaption .. " " .. Time;
end
end
else
Position = " " .. Position;
At = '';
end
Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, sepc, NoPP, use_lowercase);
At = utilities.is_set (At) and (sepc .. " " .. At) or "";
Position = utilities.is_set (Position) and (sepc .. " " .. Position) or "";
if config.CitationClass == 'map' then
local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier
local Inset = A['Inset'];
if utilities.is_set ( Inset ) then
Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase);
end
if utilities.is_set ( Sections ) then
Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase);
elseif utilities.is_set ( Section ) then
Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase);
end
At = At .. Inset .. Section;
end
local Others = A['Others'];
if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor=
if config.CitationClass == "AV-media-notes"
or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now
utilities.set_message ('maint_others_avm')
else
utilities.set_message ('maint_others');
end
end
Others = utilities.is_set (Others) and (sepc .. " " .. Others) or "";
if utilities.is_set (Translators) then
Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc);
end
if utilities.is_set (Interviewers) then
Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc);
end
local TitleNote = A['TitleNote'];
TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or "";
if utilities.is_set (Edition) then
if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn.
utilities.set_message ('err_extra_text_edition'); -- add error message
end
Edition = " " .. wrap_msg ('edition', Edition);
else
Edition = '';
end
Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum
local Agency = A['Agency'] or ''; -- |agency= is supported by {{cite magazine}}, {{cite news}}, {{cite press release}}, {{cite web}}, and certain {{citation}} templates
if utilities.is_set (Agency) then -- this testing done here because {{citation}} supports 'news' citations
if utilities.in_array (config.CitationClass, {'magazine', 'news', 'pressrelease', 'web'}) or ('citation' == config.CitationClass and utilities.in_array (Periodical_origin, {"magazine", "newspaper", "work"})) then
Agency = wrap_msg ('agency', {sepc, Agency}); -- format for rendering
else
Agency = ''; -- unset; not supported
utilities.set_message ('err_parameter_ignored', {'agency'}); -- add error message
end
end
Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, sepc, use_lowercase);
if utilities.is_set (AccessDate) then
local retrv_text = " " .. cfg.messages['retrieved'];
AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format
retrv_text = cs2_lower(retrv_text); -- if mode is cs2, lower case
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text
AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates
end
if utilities.is_set (ID) then ID = sepc .. " " .. ID; end
local Docket = A['Docket'];
if "thesis" == config.CitationClass and utilities.is_set (Docket) then
ID = sepc .. " Docket " .. Docket .. ID;
end
if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set
ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set
end
if utilities.is_set (URL) then
URL = " " .. external_link( URL, nil, URL_origin, UrlAccess );
end
-- We check length of PostScript here because it will have been nuked by
-- the quote parameters. We'd otherwise emit a message even if there wasn't
-- a displayed postscript.
-- TODO: Should the max size (1) be configurable?
-- TODO: Should we check a specific pattern?
if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then
utilities.set_message ('maint_postscript')
end
local Archived;
if utilities.is_set (ArchiveURL) then
if not utilities.is_set (ArchiveDate) then -- ArchiveURL set but ArchiveDate not set
utilities.set_message ('err_archive_missing_date'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
else
if utilities.is_set (ArchiveDate) then -- ArchiveURL not set but ArchiveDate is set
utilities.set_message ('err_archive_date_missing_url'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
end
if utilities.is_set (ArchiveURL) then
local arch_text;
if "live" == UrlStatus then
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'],
{ external_link( ArchiveURL, cs2_lower(cfg.messages['archived']), A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } );
else
Archived = '';
end
if not utilities.is_set (OriginalURL) then
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown'
if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then
Archived = sepc .. ' ' .. utilities.substitute ( cs2_lower(cfg.messages['archived-unfit']), ArchiveDate);
if 'bot: unknown' == UrlStatus then
utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added
else
utilities.add_prop_cat ('unfit'); -- and add a category if not already added
end
else -- UrlStatus is empty, 'dead'
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cs2_lower(cfg.messages['archived-dead']),
{ external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } );
else
Archived = ''; -- unset for concatenation
end
end
else -- OriginalUrl not set
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (ArchiveFormat) then
Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message
else
Archived = '';
end
local TranscriptURL = A['TranscriptURL']
local TranscriptFormat = A['TranscriptFormat'];
TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl');
local Transcript = A['Transcript'];
local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL
if utilities.is_set (Transcript) then
if utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil );
end
Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat;
elseif utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil );
end
local Publisher;
if utilities.is_set (PublicationDate) then
PublicationDate = wrap_msg ('published', PublicationDate);
end
if utilities.is_set (PublisherName) then
if utilities.is_set (PublicationPlace) then
Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate;
else
Publisher = sepc .. " " .. PublisherName .. PublicationDate;
end
elseif utilities.is_set (PublicationPlace) then
Publisher= sepc .. " " .. PublicationPlace .. PublicationDate;
else
Publisher = PublicationDate;
end
-- Several of the above rely upon detecting this as nil, so do it last.
if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then
if utilities.is_set (Title) or utilities.is_set (TitleNote) then
Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
else
Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
end
end
local Language = A['Language'];
if utilities.is_set (Language) then
Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc.
else
Language=''; -- language not specified so make sure this is an empty string;
--[[ TODO: need to extract the wrap_msg from language_parameter
so that we can solve parentheses bunching problem with Format/Language/TitleType
]]
end
--[[
Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that
the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided).
]]
if "speech" == config.CitationClass then -- cite speech only
TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event=
TitleType = ''; -- and unset
if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter
if utilities.is_set (Conference) then -- and if |event= is set
Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering
end
end
end
-- Piece all bits together at last. Here, all should be non-nil.
-- We build things this way because it is more efficient in LUA
-- not to keep reassigning to the same string variable over and over.
local tcommon;
local tcommon2; -- used for book cite when |contributor= is set
local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
-- Volume = safe_join ({Volume, pgtext}, sepc);
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites
if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc.
tcommon = safe_join ({Title, TitleNote}, sepc); -- author and other stuff will come after this and before tcommon2
tcommon2 = safe_join ({TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
else
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
end
elseif 'map' == config.CitationClass then -- special cases for cite map
if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter
tcommon = safe_join ({Title, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
elseif utilities.is_set (Periodical) then -- map in a periodical
tcommon = safe_join ({Title, TitleType, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
else -- a sheet or stand-alone map
tcommon = safe_join ({Title, TitleType, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc);
end
elseif 'episode' == config.CitationClass then -- special case for cite episode
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc);
else -- all other CS1 templates
tcommon = safe_join ({Title, TitleNote, Conference, Periodical, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc);
end
if #ID_list > 0 then
ID_list = safe_join( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc );
else
ID_list = ID;
end
local Via = A['Via'];
Via = utilities.is_set (Via) and wrap_msg ('via', Via) or '';
local idcommon;
if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript
idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Quote }, sepc );
else
idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Quote }, sepc );
end
local text;
-- local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
local OrigDate = A['OrigDate'];
OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or '';
if utilities.is_set (Date) then
if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set
Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses
else -- neither of authors and editors set
if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc
Date = " " .. Date .. OrigDate; -- Date does not begin with sepc
else
Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc
end
end
end
if utilities.is_set (Authors) then
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination
Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Editors) then
local in_text = '';
local post_text = '';
if utilities.is_set (Chapter) and 0 == #c then
in_text = cfg.messages['in'] .. ' ';
in_text = cs2_lower(in_text); -- lowercase for cs2
end
if EditorCount <= 1 then
post_text = ' (' .. cfg.messages['editor'] .. ')'; -- be consistent with no-author, no-date case
else
post_text = ' (' .. cfg.messages['editors'] .. ')';
end
Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc.
local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' ';
by_text = cs2_lower(by_text); -- lowercase for cs2
Authors = by_text .. Authors; -- author follows title so tweak it here
if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated
Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space
end
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination
Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space
end
text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon }, sepc );
-- text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, idcommon }, sepc );
else
text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon }, sepc );
-- text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, idcommon }, sepc );
end
elseif utilities.is_set (Editors) then
if utilities.is_set (Date) then
if EditorCount <= 1 then
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editor'];
else
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editors'];
end
else
if EditorCount <= 1 then
Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " "
else
Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " "
end
end
text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc );
-- text = safe_join( {Editors, Date, Chapter, Place, tcommon, idcommon}, sepc );
else
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc );
-- text = safe_join( {Chapter, Place, tcommon, Date, idcommon}, sepc );
else
text = safe_join( {Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc );
-- text = safe_join( {Chapter, Place, tcommon, Date, idcommon}, sepc );
end
end
if utilities.is_set (PostScript) and PostScript ~= sepc then
text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc.
if '.' == sepc then -- remove final seperator if present
text = text:gsub ('%' .. sepc .. '$', ''); -- dot must be escaped here
else
text = mw.ustring.gsub (text, sepc .. '$', ''); -- using ustring for non-dot sepc (likely a non-Latin character)
end
end
text = safe_join( {text, PostScript}, sepc );
-- Now enclose the whole thing in a <cite> element
local options_t = {};
options_t.class = cite_class_attribute_make (config.CitationClass, Mode);
local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else
if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then
local namelist_t = {}; -- holds selected contributor, author, editor name list
local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation
if #c > 0 then -- if there is a contributor list
namelist_t = c; -- select it
elseif #a > 0 then -- or an author list
namelist_t = a;
elseif #e > 0 then -- or an editor list
namelist_t = e;
end
local citeref_id;
if #namelist_t > 0 then -- if there are names in namelist_t
citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor
if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison
utilities.set_message ('maint_ref_duplicates_default');
end
else
citeref_id = ''; -- unset
end
options_t.id = Ref or citeref_id;
end
if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains;
z.error_cats_t = {}; -- blank the categories list
z.error_msgs_t = {}; -- blank the error messages list
OCinSoutput = nil; -- blank the metadata string
text = ''; -- blank the the citation
utilities.set_message ('err_empty_citation'); -- set empty citation message and category
end
local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation
if is_preview_mode and (0 ~= #z.error_msgs_t or 0 ~= #z.maint_cats_t) then -- when in preview mode
if not utilities.is_set (options_t.id) then -- and when this template has not created an anchor ID
math.randomseed (tonumber (mw.getLanguage ('en'):formatDate ('U')) * 10000 + os.clock() * 10000);
options_t.id = 'CITEREF_temp_preview_id_' .. math.random (100000, 999999); -- create temporary anchor ID for preview mode
end
end
if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags
options_t.id = mw.uri.anchorEncode(options_t.id); -- do this here; also used when adding preview warning messages
table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {options_t.id, mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist
else
table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty
end
if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span
table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation
end
local template_name = cfg.citation_class_map_t[config.CitationClass];
local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]';
local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: ';
if 0 ~= #z.error_msgs_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, {template_link, options_t.id}));
table.insert (render_t, ' '); -- insert a space between citation and its error messages
table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error
local hidden = true; -- presume that the only error messages emited by this template are hidden
for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages
if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name
hidden = false; -- found one; so don't hide the error message prefix
break; -- and done because no need to look further
end
end
z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation
table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering
end
if 0 ~= #z.maint_cats_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, {template_link, options_t.id}));
table.sort (z.maint_cats_t); -- sort the maintenance messages list
local maint_msgs_t = {}; -- here we collect all of the maint messages
if 0 == #z.error_msgs_t then -- if no error messages
table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery
end
for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories
table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table
table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'})
);
end
table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save
end
if not no_tracking_cats then
local sort_key;
local cat_wikilink = 'cat wikilink';
if cfg.enable_sort_keys then -- when namespace sort keys enabled
local namespace_number = mw.title.getCurrentTitle().namespace; -- get namespace number for this wikitext
sort_key = (0 ~= namespace_number and (cfg.name_space_sort_keys[namespace_number] or cfg.name_space_sort_keys.other)) or nil; -- get sort key character; nil for mainspace
cat_wikilink = (not sort_key and 'cat wikilink') or 'cat wikilink sk'; -- make <cfg.messages> key
end
for _, v in ipairs (z.error_cats_t) do -- append error categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
if cfg.id_limits_data_load_fail then -- boolean true when load failed
utilities.set_message ('maint_id_limit_load_fail'); -- done here because this maint cat emits no message
end
for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
for _, v in ipairs (z.prop_cats_t) do -- append properties categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); -- no sort keys
end
end
return table.concat (render_t); -- make a big string and done
end
--[[--------------------------< V A L I D A T E >--------------------------------------------------------------
Looks for a parameter's name in one of several whitelists.
Parameters in the whitelist can have three values:
true - active, supported parameters
false - deprecated, supported parameters
nil - unsupported parameters
]]
local function validate (name, cite_class, empty)
local name = tostring (name);
local enum_name; -- parameter name with enumerator (if any) replaced with '#'
local state;
local function state_test (state, name) -- local function to do testing of state values
if true == state then return true; end -- valid actively supported parameter
if false == state then
if empty then return nil; end -- empty deprecated parameters are treated as unknowns
deprecated_parameter (name); -- parameter is deprecated but still supported
return true;
end
if 'tracked' == state then
local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name
utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key>
return true;
end
return nil;
end
if name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted
return nil;
end
-- replace enumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits)
enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=)
enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity
if 'document' == cite_class then -- special case for {{cite document}}
state = whitelist.document_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test (state, name) then return true; end
return false;
end
if utilities.in_array (cite_class, whitelist.preprint_template_list_t) then -- limited parameter sets allowed for these templates
state = whitelist.limited_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test (state, name) then return true; end
state = whitelist.preprint_arguments_t[cite_class][name]; -- look in the parameter-list for the template identified by cite_class
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end -- end limited parameter-set templates
if utilities.in_array (cite_class, whitelist.unique_param_template_list_t) then -- template-specific parameters for templates that accept parameters from the basic argument list
state = whitelist.unique_arguments_t[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class
if true == state_test (state, name) then return true; end
end -- if here, fall into general validation
state = whitelist.common_parameters_t[enum_name]; -- all other templates; all normal parameters allowed; this list holds enumerated and nonenumerated parameters
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end
--[=[-------------------------< I N T E R _ W I K I _ C H E C K >----------------------------------------------
check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language
code. when these values have the form (without leading colon):
[[<prefix>:link|label]] return label as plain-text
[[<prefix>:link]] return <prefix>:link as plain-text
return value as is else
]=]
local function inter_wiki_check (parameter, value)
local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists
local _;
if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so
utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message
_, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink
end
return value;
end
--[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------
Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal
sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a
parameter that is missing its pipe. There are two tests made:
{{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name
{{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki)
cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML
tags are removed before the search.
If a missing pipe is detected, this function adds the missing pipe maintenance category.
]]
local function missing_pipe_check (parameter, value)
local capture;
value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc.
capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes
if capture and validate (capture) then -- if the capture is a valid parameter name
utilities.set_message ('err_missing_pipe', parameter);
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >--------------------------------------
look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_punc (param, value)
if 'number' == type (param) then
return;
end
param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize
if cfg.punct_skip[param] then
return; -- parameter name found in the skip table so done
end
if value:match ('[,;:]$') then
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
if value:match ('^=') then -- sometimes an extraneous '=' character appears ...
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
end
--[[--------------------------< H A S _ T W L _ U R L >--------------------------------------------------------
look for The Wikipedia Library urls in url-holding parameters. TWL urls are accessible only for readers who are
active extended confirmed Wikipedia editors. This function sets an error message when such urls are discovered
and when appropriate, sets the |<param>-url-access=subscription. returns nothing.
looks for: '.wikipedialibrary.idm.oclc.org'
]]
local function has_twl_url (url_params_t, cite_args_t)
local url_error_t = {}; -- sequence of url-holding parameters that have a TWL url
for param, value in pairs (url_params_t) do
if value:find ('%.wikipedialibrary%.idm%.oclc%.org') then -- has the TWL base url?
table.insert (url_error_t, param); -- add parameter name to the error list
end
end
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t); -- sor for error messaging
for i, param in ipairs (url_error_t) do
if cfg.url_access_map_t[param] then -- if <param> has a matching -access parameter
cite_args_t[cfg.url_access_map_t[param]] = cfg.keywords_xlate.subscription; -- set |<param>-url-access=subscription
end
url_error_t[i] = utilities.wrap_style ('parameter', param); -- make the parameter pretty for error message
end
utilities.set_message ('err_param_has_twl_url', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------
look for extraneous url parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_url (non_url_param_t)
local url_error_t = {};
check_for_url (non_url_param_t, url_error_t); -- extraneous url check
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t);
utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< _ C I T A T I O N >------------------------------------------------------------
Module entry point
frame – from template call (citation()); may be nil when called from another module
args_t – table of all cs1|2 parameters in the template (the parent frame)
config_t – table of template-supplied parameter (the #invoke frame)
]]
local function _citation (frame, args_t, config_t) -- save a copy in case we need to display an error message in preview mode
if not frame then
frame = mw.getCurrentFrame(); -- if called from another module, get a frame for frame-provided functions
end
-- i18n: set the name that your wiki uses to identify sandbox subpages from sandbox template invoke (or can be set here)
local sandbox = ((config_t.SandboxPath and '' ~= config_t.SandboxPath) and config_t.SandboxPath) or '/sandbox'; -- sandbox path from {{#invoke:Citation/CS1/sandbox|citation|SandboxPath=/...}}
is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module?
sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else
cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else
whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox);
utilities = require ('Module:Citation/CS1/Utilities' .. sandbox);
validation = require ('Module:Citation/CS1/Date_validation' .. sandbox);
identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox);
metadata = require ('Module:Citation/CS1/COinS' .. sandbox);
utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables
identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module
validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module
metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module
z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities
local cite_args_t = {}; -- because args_t is the parent (template) frame args (which cannot be modified); params and their values will be placed here
is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}'));
local suggestions = {}; -- table where we store suggestions if we need to loadData them
local error_text; -- used as a flag
local capture; -- the single supported capture when matching unknown parameters using patterns
local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing
for k, v in pairs (args_t) do -- get parameters from the parent (template) frame
v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string
if v ~= '' then
if cfg.enum_needs_xlation and 'string' == type (k) then -- for wikis that set date_names['local_digits'] to non-western digits
k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- translate 'local' digits enumerators to Western 0-9
end
if not validate( k, config_t.CitationClass ) then
if type (k) ~= 'string' then -- exclude empty numbered parameters
if v:match("%S+") ~= nil then
error_text = utilities.set_message ('err_text_ignored', {v});
end
elseif validate (k:lower(), config_t.CitationClass) then
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter
else
if nil == suggestions.suggestions then -- if this table is nil then we need to load it
suggestions = mw.loadData ('Module:Citation/CS1/Suggestions' .. sandbox); --load sandbox version of suggestion module when {{#invoke:Citation/CS1/sandbox|...}}; live module else
end
for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter
capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match
if capture then -- if the pattern matches
param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator)
if validate (param, config_t.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists)
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message
else
error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template
v = ''; -- unset
end
end
end
if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion?
if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config_t.CitationClass) then
utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]});
else
utilities.set_message ('err_parameter_ignored', {k});
v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists)
end
end
end
end
cite_args_t[k] = v; -- save this parameter and its value
elseif not utilities.is_set (v) then -- for empty parameters
if not validate (k, config_t.CitationClass, true) then -- is this empty parameter a valid parameter
k = ('' == k) and cfg.err_msg_supl.empty_str or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text
table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list
end
end
end
if 0 ~= #empty_unknowns then -- create empty unknown error message
utilities.set_message ('err_param_unknown_empty', {
1 == #empty_unknowns and '' or 's',
utilities.make_sep_list (#empty_unknowns, empty_unknowns)
});
end
local non_url_param_t = {}; -- table of parameters and values that are not url-holding parameters
local url_param_t = {}; -- table of url-holding paramters and their values
for k, v in pairs (cite_args_t) do
if 'string' == type (k) then -- don't evaluate positional parameters
has_invisible_chars (k, v); -- look for invisible characters
end
has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values
missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe?
cite_args_t[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label
if 'string' == type (k) then -- when parameter k is not positional
if not cfg.url_skip[k] then -- and not in url skip table
non_url_param_t[k] = v; -- make a parameter/value list for extraneous url check
else -- and is in url skip table (a url-holding parameter)
url_param_t[k] = v; -- make a parameter/value list to check for values that are The Wikipedia Library url
end
end
end
if cfg.suppress_archive_today_urls then
has_archive_today_url (cite_args_t); -- look for and suppress archive.today urls and dependent parameters for all templates
end
has_extraneous_url (non_url_param_t); -- look for url in parameter values where a url does not belong
has_twl_url (url_param_t, cite_args_t); -- look for url-holding parameters that hold a The Wikipedia Library url
return table.concat ({
frame:extensionTag ('templatestyles', '', {src='Module:Citation/CS1' .. sandbox .. '/styles.css'}),
citation0 (config_t, cite_args_t)
});
end
--[[--------------------------< C I T A T I O N >--------------------------------------------------------------
Template entry point
]]
local function citation (frame)
local config_t = {}; -- table to store parameters from the module {{#invoke:}}
local args_t = frame:getParent().args; -- get template's preset parameters
for k, v in pairs (frame.args) do -- get parameters from the {{#invoke}} frame
config_t[k] = v;
-- args_t[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep?
end
return _citation (frame, args_t, config_t)
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
citation = citation, -- template entry point
_citation = _citation, -- module entry point
}
o0mp7ygqu5bibs2dabkkkkneiickrfx
Module:Citation/CS1/Configuration
828
15540
167627
147622
2026-04-25T18:53:38Z
Ellenor2000
20768
copia de https://en.wikipedia.org/w/index.php?title=Module:Citation/CS1/Configuration&oldid=1340931211 e prova partialmen traducer
167627
Scribunto
text/plain
local lang_obj = mw.language.getContentLanguage(); -- make a language object for the local language; used here for languages and dates
--[[--------------------------< S E T T I N G S >--------------------------------------------------------------
boolean settings used to control various things. these setting located here to make them easy to find
]]
-- these settings local to this module only
local local_digits_from_mediawiki = false; -- for i18n; when true, module fills date_names['local_digits'] from MediaWiki; manual fill required else; always false at en.wiki
local local_date_names_from_mediawiki = false; -- for i18n; when true, module fills date_names['local']['long'] and date_names['local']['short'] from MediaWiki;
-- manual translation required else; ; always false at en.wiki
-- these settings exported to other modules
local use_identifier_redirects = true; -- when true use redirect name for identifier label links; always true at en.wiki
local local_lang_cat_enable = false; -- when true categorizes pages where |language=<local wiki's language>; always false at en.wiki
local date_name_auto_xlate_enable = false; -- when true translates English month-names to the local-wiki's language month names; always false at en.wiki
local date_digit_auto_xlate_enable = false; -- when true translates Western date digit to the local-wiki's language digits (date_names['local_digits']); always false at en.wiki
local enable_sort_keys = true; -- when true module adds namespace sort keys to error and maintenance category links
local suppress_archive_today_urls = true; -- when true module suppresses all parameters with an archive.today url and any deprendent parameters
--[[--------------------------< U N C A T E G O R I Z E D _ N A M E S P A C E S >------------------------------
List of namespaces identifiers for namespaces that will not be included in citation error categories.
Same as setting notracking = true by default.
For wikis that have a current version of Module:cs1 documentation support, this #invoke will return an unordered
list of namespace names and their associated identifiers:
{{#invoke:cs1 documentation support|uncategorized_namespace_lister|all=<anything>}}
]]
local uncategorized_namespaces_t = {[2]=true}; -- init with user namespace id
for k, _ in pairs (mw.site.talkNamespaces) do -- add all talk namespace ids
uncategorized_namespaces_t[k] = true;
end
local uncategorized_subpages = {'/[Ss]andbox', '/[Tt]estcases', '/[^/]*[Ll]og', '/[Aa]rchive'}; -- list of Lua patterns found in page names of pages we should not categorize
--[[
at en.wiki Greek characters are used as sort keys for certain items in a category so that those items are
placed at the end of a category page. See Wikipedia:Categorization#Sort_keys. That works well for en.wiki
because English is written using the Latn script. This may not work well for other languages. At en.wiki it
is desireable to place content from certain namespaces at the end of a category listing so the module adds sort
keys to error and maintenance category links when rendering a cs1|2 template on a page in that namespace.
i18n: if this does not work well for your language, set <enable_sort_keys> to false.
]]
local name_space_sort_keys = { -- sort keys to be used with these namespaces:
[4] = 'ω', -- wikipedia; omega
[10] = 'τ', -- template; tau
[118] = 'Δ', -- draft; delta
['other'] = 'ο', -- all other non-talk namespaces except main (article); omicron
}
--[[--------------------------< M E S S A G E S >--------------------------------------------------------------
Translation table
The following contains fixed text that may be output as part of a citation.
This is separated from the main body to aid in future translations of this
module.
]]
local messages = {
['agency'] = '$1 $2', -- $1 is sepc, $2 is agency
['archived-dead'] = 'Archivat de $1 li $2',
['archived-live'] = '$1 del original li $2',
['archived-unfit'] = 'Archived del original li $1',
['archived'] = 'Archivat',
['by'] = 'De', -- contributions to authored works: introduction, foreword, afterword
['cartography'] = 'Cartografie de $1',
['editor'] = 'red.',
['editors'] = 'reds.',
['edition'] = '($1 ed.)',
['episode'] = 'Episode $1',
['et al'] = 'et al.',
['in'] = 'In', -- edited works
['inactive'] = ' (inactive $1)', -- $1 is date which the doi was found to be broken in
['inset'] = '$1 inset',
['interview'] = 'Interviewat de $1',
invisible_1 = '$1 $2', -- $1 stripmarker name; $2 is text from <invisible_chars[1]>
invisible_2 = '$1 character', -- $1 character name from <invisible_chars[1]>
['mismatch'] = '<code class="cs1-code">|$1=</code> / <code class="cs1-code">|$2=</code> ne es egal', -- $1 is year param name; $2 is date param name
['newsgroup'] = '[[Usenet newsgroup|Newsgroup]]: $1',
['notitle'] = 'No title', -- for |title=(()) and (in the future) |title=none
['original'] = 'the original',
['origdate'] = ' [$1]',
['published'] = ' (published $1)',
['retrieved'] = 'Retrieved $1',
['season'] = 'Season $1',
['section'] = '§ $1',
['sections'] = '§§ $1',
['series'] = '$1 $2', -- $1 is sepc, $2 is series
['seriesnum'] = 'Series $1',
['translated'] = 'Traductet de $1',
['type'] = ' ($1)', -- for titletype
wikidata = 'Wikidata', -- these used for interwikilinked author/editor/... names
wikipedia = 'Wikipedia',
wikisource = 'Wikisource',
['written'] = 'Scrit li $1',
['vol'] = '$1 Tom $2', -- $1 is sepc; bold journal style volume is in presentation{}
['vol-no'] = '$1 Tom $2, nró. $3', -- sepc, volume, issue (alternatively insert $1 after $2, but then we'd also have to change capitalization)
['issue'] = '$1 Nró. $2', -- $1 is sepc
['art'] = '$1 Art. $2', -- $1 is sepc; for {{cite conference}} only
['vol-art'] = '$1 Tom. $2, art. $3', -- sepc, volume, article-number; for {{cite conference}} only
['j-vol'] = '$1 $2', -- sepc, volume; bold journal volume is in presentation{}
['j-issue'] = ' ($1)',
['j-article-num'] = ' $1', -- TODO: any punctuation here? static text?
['nopp'] = '$1 $2'; -- page(s) without prefix; $1 is sepc
['p-prefix'] = "$1 p. $2", -- $1 is sepc
['pp-prefix'] = "$1 pp. $2", -- $1 is sepc
['j-page(s)'] = ': $1', -- same for page and pages
['sheet'] = '$1 Sheet $2', -- $1 is sepc
['sheets'] = '$1 Sheets $2', -- $1 is sepc
['j-sheet'] = ': Sheet $1',
['j-sheets'] = ': Sheets $1',
['language'] = '(in $1)',
['via'] = " – via $1",
['event'] = 'Eveniment eveni a',
['minutes'] = ' $1 minutes in', -- $1 is the number of minutes
-- Determines the location of the help page
['help page link'] = 'Help:CS1 errors',
['help page label'] = 'help',
-- categories
['cat wikilink'] = '[[Category:$1]]', -- $1 is the category name
['cat wikilink sk'] = '[[Category:$1|$2]]', -- $1 is the category name; $2 is namespace sort key
[':cat wikilink'] = '[[:Category:$1|link]]', -- category name as maintenance message wikilink; $1 is the category name
-- Internal errors (should only occur if configuration is bad)
['undefined_error'] = 'Called with an undefined error condition',
['unknown_ID_key'] = 'Unrecognized ID key: ', -- an ID key in id_handlers not found in ~/Identifiers func_map{}
['unknown_ID_access'] = 'Unrecognized ID access keyword: ', -- an ID access keyword in id_handlers not found in keywords_lists['id-access']{}
['unknown_argument_map'] = 'Argument map not defined for this variable',
['bare_url_no_origin'] = 'Bare URL found but origin indicator is nil or empty',
['warning_msg_e'] = '<span style="color:#d33"><code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code>: this [[#$2|reference]] has errors</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link; $2 is anchor ID
['warning_msg_m'] = '<span style="color:#085"><code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code>: this [[#$2|reference]] has maintenance messages</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link; $2 is anchor ID
}
--[[--------------------------< C I T A T I O N _ C L A S S _ M A P >------------------------------------------
this table maps the value assigned to |CitationClass= in the cs1|2 templates to the canonical template name when
the value assigned to |CitationClass= is different from the canonical template name. |CitationClass= values are
used as class attributes in the <cite> tag that encloses the citation so these names may not contain spaces while
the canonical template name may. These names are used in warning_msg_e and warning_msg_m to create links to the
template's documentation when an article is displayed in preview mode.
]]
local citation_class_map_t = { -- TODO: in Module:Cite/config write a function to use this table
arxiv = 'cite arXiv', -- as the source for known_templates_t and citation_classes_t
['audio-visual'] = 'cite AV media',
['AV-media-notes'] = 'cite AV media notes',
biorxiv = 'cite bioRxiv',
book = 'cite book',
citation = 'citation',
citeseerx = 'cite CiteSeerX',
conference = 'cite conference',
document = 'cite document',
encyclopaedia = 'cite encyclopedia',
episode = 'cite episode',
interview = 'cite interview',
journal = 'cite journal',
magazine = 'cite magazine',
mailinglist = 'cite mailing list',
map = 'cite map',
medrxiv = 'cite medRxiv',
news = 'cite news',
newsgroup = 'cite newsgroup',
podcast = 'cite podcast',
pressrelease = 'cite press release',
report = 'cite report',
serial = 'cite serial',
sign = 'cite sign',
speech = 'cite speech',
ssrn = 'cite SSRN',
techreport = 'cite tech report',
thesis = 'cite thesis',
web = 'cite web',
}
--[=[-------------------------< E T _ A L _ P A T T E R N S >--------------------------------------------------
This table provides Lua patterns for the phrase "et al" and variants in name text
(author, editor, etc.). The main module uses these to identify and emit the 'etal' message.
]=]
local et_al_patterns = {
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][%.;,\"']*$", -- variations on the 'et al' theme
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][Ii][AaIi][Ee]?[%.;,\"']*$", -- variations on the 'et alia', 'et alii' and 'et aliae' themes (false positive 'et aliie' unlikely to match)
"[;,]? *%f[%a]and [Oo]thers", -- an alternative to et al.
"%[%[ *[Ee][Tt]%.? *[Aa][Ll]%.? *%]%]", -- a wikilinked form
"%(%( *[Ee][Tt]%.? *[Aa][Ll]%.? *%)%)", -- a double-bracketed form (to counter partial removal of ((...)) syntax)
"[%(%[] *[Ee][Tt]%.? *[Aa][Ll]%.? *[%)%]]", -- a bracketed form
}
--[[--------------------------< P R E S E N T A T I O N >------------------------
Fixed presentation markup. Originally part of citation_config.messages it has
been moved into its own, more semantically correct place.
]]
local presentation =
{
-- .citation-comment class is specified at Help:CS1_errors#Controlling_error_message_display
['hidden-error'] = '<span class="cs1-hidden-error citation-comment">$1</span>',
['visible-error'] = '<span class="cs1-visible-error citation-comment">$1</span>',
['hidden-maint'] = '<span class="cs1-maint citation-comment">$1</span>',
['accessdate'] = '<span class="reference-accessdate">$1$2</span>', -- to allow editors to hide accessdate using personal CSS
['bdi'] = '<bdi$1>$2</bdi>', -- bidirectional isolation used with |script-title= and the like
['cite'] = '<cite class="$1">$2</cite>'; -- for use when citation does not have a namelist and |ref= not set so no id="..." attribute
['cite-id'] = '<cite id="$1" class="$2">$3</cite>'; -- for use when when |ref= is set or when citation has a namelist
['format'] = ' <span class="cs1-format">($1)</span>', -- for |format=, |chapter-format=, etc.
['interwiki'] = ' <span class="cs1-format">[in $1]</span>', -- for interwiki-language-linked author, editor, etc
['interproj'] = ' <span class="cs1-format">[at $1]</span>', -- for interwiki-project-linked author, editor, etc (:d: and :s: supported; :w: ignored)
-- various access levels, for |access=, |doi-access=, |arxiv=, ...
-- narrow no-break space   may work better than nowrap CSS. Or not? Browser support?
['ext-link-access-signal'] = '<span class="$1" title="$2">$3</span>', -- external link with appropriate lock icon
['free'] = {class='id-lock-free', title='Con accesse gratis'}, -- classes defined in Module:Citation/CS1/styles.css
['registration'] = {class='id-lock-registration', title='Exige registration gratuit'},
['limited'] = {class='id-lock-limited', title='Free access subject to limited trial, subscription normally required'},
['subscription'] = {class='id-lock-subscription', title='Exige subscrition'},
['interwiki-icon'] = '<span class="$1" title="$2">$3</span>',
['class-wikisource'] = 'cs1-ws-icon',
['italic-title'] = "''$1''",
['kern-left'] = '<span class="cs1-kern-left"></span>$1', -- spacing to use when title contains leading single or double quote mark
['kern-right'] = '$1<span class="cs1-kern-right"></span>', -- spacing to use when title contains trailing single or double quote mark
['nowrap1'] = '<span class="nowrap">$1</span>', -- for nowrapping an item: <span ...>yyyy-mm-dd</span>
['nowrap2'] = '<span class="nowrap">$1</span> $2', -- for nowrapping portions of an item: <span ...>dd mmmm</span> yyyy (note white space)
['ocins'] = '<span title="$1" class="Z3988"></span>',
['parameter'] = '<code class="cs1-code">|$1=</code>',
['ps_cs1'] = '.'; -- CS1 style postscript (terminal) character
['ps_cs2'] = ''; -- CS2 style postscript (terminal) character (empty string)
['quoted-text'] = '<q>$1</q>', -- for wrapping |quote= content
['quoted-title'] = '"$1"',
['sep_cs1'] = '.', -- CS1 element separator
['sep_cs2'] = ',', -- CS2 separator
['sep_nl'] = ';', -- CS1|2 style name-list separator between names is a semicolon
['sep_nl_and'] = ' and ', -- used as last nl sep when |name-list-style=and and list has 2 items
['sep_nl_end'] = '; and ', -- used as last nl sep when |name-list-style=and and list has 3+ names
['sep_name'] = ', ', -- CS1|2 style last/first separator is <comma><space>
['sep_nl_vanc'] = ',', -- Vancouver style name-list separator between authors is a comma
['sep_name_vanc'] = ' ', -- Vancouver style last/first separator is a space
['sep_list'] = ', ', -- used for |language= when list has 3+ items except for last sep which uses sep_list_end
['sep_list_pair'] = ' and ', -- used for |language= when list has 2 items
['sep_list_end'] = ', and ', -- used as last list sep for |language= when list has 3+ items
['trans-italic-title'] = "[''$1'']",
['trans-quoted-title'] = "[$1]", -- for |trans-title= and |trans-quote=
['vol-bold'] = '$1 <b>$2</b>', -- sepc, volume; for bold journal cites; for other cites ['vol'] in messages{}
}
--[[--------------------------< A L I A S E S >---------------------------------
Aliases table for commonly passed parameters.
Parameter names on the right side in the assignments in this table must have been
defined in the Whitelist before they will be recognized as valid parameter names
]]
local aliases = {
['AccessDate'] = {'access-date', 'accessdate'}, -- Used by InternetArchiveBot
['Agency'] = 'agency',
['ArchiveDate'] = {'archive-date', 'archivedate'}, -- Used by InternetArchiveBot
['ArchiveFormat'] = 'archive-format',
['ArchiveURL'] = {'archive-url', 'archiveurl'}, -- Used by InternetArchiveBot
['ArticleNumber'] = 'article-number',
['ASINTLD'] = 'asin-tld',
['At'] = 'at', -- Used by InternetArchiveBot
['Authors'] = {'people', 'credits'},
['BookTitle'] = {'book-title', 'booktitle'},
['Cartography'] = 'cartography',
['Chapter'] = {'chapter', 'contribution', 'entry', 'article', 'section'},
['ChapterFormat'] = {'chapter-format', 'contribution-format', 'entry-format',
'article-format', 'section-format'};
['ChapterURL'] = {'chapter-url', 'contribution-url', 'entry-url', 'article-url', 'section-url'}, -- Used by InternetArchiveBot
['ChapterUrlAccess'] = {'chapter-url-access', 'contribution-url-access',
'entry-url-access', 'article-url-access', 'section-url-access'}, -- Used by InternetArchiveBot
['Class'] = 'class', -- cite arxiv and arxiv identifier
['Collaboration'] = 'collaboration',
['Conference'] = {'conference', 'event'},
['ConferenceFormat'] = 'conference-format',
['ConferenceURL'] = 'conference-url', -- Used by InternetArchiveBot
['Date'] = {'date', 'air-date', 'airdate'}, -- air-date and airdate for cite episode and cite serial only
['Degree'] = 'degree',
['DF'] = 'df',
['DisplayAuthors'] = {'display-authors', 'display-subjects'},
['DisplayContributors'] = 'display-contributors',
['DisplayEditors'] = 'display-editors',
['DisplayInterviewers'] = 'display-interviewers',
['DisplayTranslators'] = 'display-translators',
['Docket'] = 'docket',
['DoiBroken'] = 'doi-broken-date',
['Edition'] = 'edition',
['Embargo'] = 'pmc-embargo-date',
['Encyclopedia'] = {'encyclopedia', 'encyclopaedia', 'dictionary'}, -- cite encyclopedia only
['Episode'] = 'episode', -- cite serial only TODO: make available to cite episode?
['Format'] = 'format',
['ID'] = {'id', 'ID'},
['Inset'] = 'inset',
['Issue'] = {'issue', 'number'},
['Language'] = {'language', 'lang'},
['MailingList'] = {'mailing-list', 'mailinglist'}, -- cite mailing list only
['Map'] = 'map', -- cite map only
['MapFormat'] = 'map-format', -- cite map only
['MapURL'] = {'map-url', 'mapurl'}, -- cite map only -- Used by InternetArchiveBot
['MapUrlAccess'] = 'map-url-access', -- cite map only -- Used by InternetArchiveBot
['Minutes'] = 'minutes',
['Mode'] = 'mode',
['NameListStyle'] = 'name-list-style',
['Network'] = 'network',
['Newsgroup'] = 'newsgroup', -- cite newsgroup only
['NoPP'] = {'no-pp', 'nopp'},
['NoTracking'] = {'no-tracking', 'template-doc-demo'},
['Number'] = 'number', -- this case only for cite techreport
['OrigDate'] = {'orig-date', 'orig-year', 'origyear'},
['Others'] = 'others',
['Page'] = {'page', 'p'}, -- Used by InternetArchiveBot
['Pages'] = {'pages', 'pp'}, -- Used by InternetArchiveBot
['Periodical'] = {'journal', 'magazine', 'newspaper', 'periodical', 'website', 'work'},
['Place'] = {'place', 'location'},
['PostScript'] = 'postscript',
['PublicationDate'] = {'publication-date', 'publicationdate'},
['PublicationPlace'] = {'publication-place', 'publicationplace'},
['PublisherName'] = {'publisher', 'institution'},
['Quote'] = {'quote', 'quotation'},
['QuotePage'] = 'quote-page',
['QuotePages'] = 'quote-pages',
['Ref'] = 'ref',
['Scale'] = 'scale',
['ScriptChapter'] = {'script-chapter', 'script-contribution', 'script-entry',
'script-article', 'script-section'},
['ScriptEncyclopedia'] = {'script-encyclopedia', 'script-encyclopaedia'}, -- cite encyclopedia only
['ScriptMap'] = 'script-map',
['ScriptPeriodical'] = {'script-journal', 'script-magazine', 'script-newspaper',
'script-periodical', 'script-website', 'script-work'},
['ScriptQuote'] = 'script-quote',
['ScriptTitle'] = 'script-title', -- Used by InternetArchiveBot
['Season'] = 'season',
['Sections'] = 'sections', -- cite map only
['Series'] = {'series', 'version'},
['SeriesLink'] = {'series-link', 'serieslink'},
['SeriesNumber'] = {'series-number', 'series-no'},
['Sheet'] = 'sheet', -- cite map only
['Sheets'] = 'sheets', -- cite map only
['Station'] = 'station',
['Time'] = 'time',
['TimeCaption'] = 'time-caption',
['Title'] = 'title', -- Used by InternetArchiveBot
['TitleLink'] = {'title-link', 'episode-link', 'episodelink'}, -- Used by InternetArchiveBot
['TitleNote'] = {'title-note', 'department'},
['TitleType'] = {'type', 'medium'},
['TransChapter'] = {'trans-article', 'trans-chapter', 'trans-contribution',
'trans-entry', 'trans-section'},
['Transcript'] = 'transcript',
['TranscriptFormat'] = 'transcript-format',
['TranscriptURL'] = 'transcript-url', -- Used by InternetArchiveBot
['TransEncyclopedia'] = {'trans-encyclopedia', 'trans-encyclopaedia'}, -- cite encyclopedia only
['TransMap'] = 'trans-map', -- cite map only
['TransPeriodical'] = {'trans-journal', 'trans-magazine', 'trans-newspaper',
'trans-periodical', 'trans-website', 'trans-work'},
['TransQuote'] = 'trans-quote',
['TransTitle'] = 'trans-title', -- Used by InternetArchiveBot
['URL'] = {'url', 'URL'}, -- Used by InternetArchiveBot
['UrlAccess'] = 'url-access', -- Used by InternetArchiveBot
['UrlStatus'] = 'url-status', -- Used by InternetArchiveBot
['Vauthors'] = 'vauthors',
['Veditors'] = 'veditors',
['Via'] = 'via',
['Volume'] = 'volume',
['Year'] = 'year',
['AuthorList-First'] = {"first#", "author-first#", "author#-first", "author-given#", "author#-given",
"subject-first#", "subject#-first", "subject-given#", "subject#-given",
"given#"},
['AuthorList-Last'] = {"last#", "author-last#", "author#-last", "author-surname#", "author#-surname",
"subject-last#", "subject#-last", "subject-surname#", "subject#-surname",
"author#", 'host#', "subject#", "surname#"},
['AuthorList-Link'] = {"author-link#", "author#-link", "subject-link#",
"subject#-link", "authorlink#", "author#link"},
['AuthorList-Mask'] = {"author-mask#", "author#-mask", "subject-mask#", "subject#-mask"},
['ContributorList-First'] = {'contributor-first#', 'contributor#-first',
'contributor-given#', 'contributor#-given'},
['ContributorList-Last'] = {'contributor-last#', 'contributor#-last',
'contributor-surname#', 'contributor#-surname', 'contributor#'},
['ContributorList-Link'] = {'contributor-link#', 'contributor#-link'},
['ContributorList-Mask'] = {'contributor-mask#', 'contributor#-mask'},
['EditorList-First'] = {"editor-first#", "editor#-first", "editor-given#", "editor#-given"},
['EditorList-Last'] = {"editor-last#", "editor#-last", "editor-surname#",
"editor#-surname", "editor#"},
['EditorList-Link'] = {"editor-link#", "editor#-link"},
['EditorList-Mask'] = {"editor-mask#", "editor#-mask"},
['InterviewerList-First'] = {'interviewer-first#', 'interviewer#-first',
'interviewer-given#', 'interviewer#-given'},
['InterviewerList-Last'] = {'interviewer-last#', 'interviewer#-last',
'interviewer-surname#', 'interviewer#-surname', 'interviewer#'},
['InterviewerList-Link'] = {'interviewer-link#', 'interviewer#-link'},
['InterviewerList-Mask'] = {'interviewer-mask#', 'interviewer#-mask'},
['TranslatorList-First'] = {'translator-first#', 'translator#-first',
'translator-given#', 'translator#-given'},
['TranslatorList-Last'] = {'translator-last#', 'translator#-last',
'translator-surname#', 'translator#-surname', 'translator#'},
['TranslatorList-Link'] = {'translator-link#', 'translator#-link'},
['TranslatorList-Mask'] = {'translator-mask#', 'translator#-mask'},
}
--[[--------------------------< D E P E N D E N C I E S _ T >--------------------------------------------------
a table of url-holding parameters upon which other parameters are dependent.
this table is used by has_archive_today_url() to suppress parameters that are dependant upon a url-holding parameter
that has as a value an archive.today (or alternate tld) url.
archive.today is deprecated at en.wiki; see Wikipedia:Requests_for_comment/Archive.is_RFC_5
]]
local url_dependency_map_t = { -- table of url-holding parameters and the meta-parameters that are dependent on them
['url'] = {'AccessDate', 'ArchiveURL', 'Format', 'UrlAccess'},
['archive-url'] = {'ArchiveDate', 'ArchiveFormat', 'UrlStatus'},
['archiveurl'] = {'ArchiveDate', 'ArchiveFormat', 'UrlStatus'},
['article-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['chapter-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['conference-url'] = {'ConferenceFormat'},
['contribution-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['entry-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['map-url'] = {'MapFormat', 'MapUrlAccess'},
['section-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['transcript-url'] = {'TranscriptFormat'},
};
local dependencies_t = {}; -- the table of url-holding parameters and their dependent parameters
for url_param, meta_parameters_t in pairs (url_dependency_map_t) do -- sequence of meta-parameters (indexes) into <aliases> table
local dependant_params_t = {}; -- collection of parameters that are dependent on this <url_param>
for _, meta_parameter in ipairs (meta_parameters_t) do -- for each <aliases> meta-parameter (index)
if 'string' == type (aliases[meta_parameter]) then -- for single parameter names (no aliases), <aliases[meta_parameter]> will be a string
table.insert (dependant_params_t, aliases[meta_parameter]); -- add to this <url_param>'s dependency sequence
else
for _, alias in ipairs (aliases[meta_parameter]) do -- for each alias in aliases[meta_parameter] (aliases['AccessDate'] for example)
table.insert (dependant_params_t, alias); -- add to this <url_param>'s dependency sequence
end
end
end
dependencies_t[url_param] = dependant_params_t; -- add the <url_param> and its dependent parameters
end
--[[--------------------------< P U N C T _ S K I P >---------------------------
builds a table of parameter names that the extraneous terminal punctuation check should not check.
]]
local punct_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'BookTitle', 'Chapter', 'ScriptChapter', 'ScriptTitle', 'Title', 'TransChapter', 'Transcript', 'TransMap', 'TransTitle', -- title-holding parameters
'AuthorList-Mask', 'ContributorList-Mask', 'EditorList-Mask', 'InterviewerList-Mask', 'TranslatorList-Mask', -- name-list mask may have name separators
'PostScript', 'Quote', 'ScriptQuote', 'TransQuote', 'Ref', -- miscellaneous
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'MapURL', 'TranscriptURL', 'URL', -- URL-holding parameters
}
local url_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'ID', 'MapURL', 'TranscriptURL', 'URL', -- parameters allowed to hold urls
'Page', 'Pages', 'At', 'QuotePage', 'QuotePages', -- insource locators allowed to hold urls
}
local function build_skip_table (skip_t, meta_params)
for _, meta_param in ipairs (meta_params) do -- for each meta parameter key
local params = aliases[meta_param]; -- get the parameter or the table of parameters associated with the meta parameter name
if 'string' == type (params) then
skip_t[params] = 1; -- just a single parameter
else
for _, param in ipairs (params) do -- get the parameter name
skip_t[param] = 1; -- add the parameter name to the skip table
local count;
param, count = param:gsub ('#', ''); -- remove enumerator marker from enumerated parameters
if 0 ~= count then -- if removed
skip_t[param] = 1; -- add param name without enumerator marker
end
end
end
end
return skip_t;
end
local punct_skip = {};
local url_skip = {};
--[[--------------------------< U R L _ A C C E S S _ M A P >--------------------------------------------------
this table used by the wikipedia library url test, has_twl_url(), which automatically sets a url-access parameter
to 'subscription' when it discovers a wikipedia library url in any of the url-holding paramters used as keys in
this table.
translators: if your wiki uses parameter names for these url-holding parameters and their matching -access parameters,
add your wiki's parameters to this list. Leave the English parameters in place.
TODO: is there a better way to do this?
]]
local url_access_map_t = {
['chapter-url'] = 'chapter-url-access',
['contribution-url'] = 'contribution-url-access',
['entry-url'] = 'entry-url-access',
['article-url'] = 'article-url-access',
['section-url'] = 'section-url-access',
['map-url'] = 'map-url-access',
['mapurl'] = 'map-url-access',
['url'] = 'url-access',
['URL'] = 'url-access'
}
--[[--------------------------< S I N G L E - L E T T E R S E C O N D - L E V E L D O M A I N S >----------
this is a list of tlds that are known to have single-letter second-level domain names. This list does not include
ccTLDs which are accepted in is_domain_name().
]]
local single_letter_2nd_lvl_domains_t = {'cash', 'company', 'foundation', 'media', 'org', 'today'};
--[[-----------< S P E C I A L C A S E T R A N S L A T I O N S >------------
This table is primarily here to support internationalization. Translations in
this table are used, for example, when an error message, category name, etc.,
is extracted from the English alias key. There may be other cases where
this translation table may be useful.
]]
local is_Latn = 'A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191';
local special_case_translation = {
author = 'author',
editor = 'editor',
name_list_params = '$1-name-list parameters', -- $1 is 'author' or 'editor'; used with err_redundant_parameters
['AuthorList'] = 'authors list', -- used to assemble maintenance category names
['ContributorList'] = 'contributors list', -- translation of these names plus translation of the base maintenance category names in maint_cats{} table below
['EditorList'] = 'editors list', -- must match the names of the actual categories
['InterviewerList'] = 'interviewers list', -- this group or translations used by name_has_ed_markup() and name_has_mult_names()
['TranslatorList'] = 'translators list',
-- Lua patterns to match pseudo-titles used by InternetArchiveBot and others as placeholder for unknown |title= value
['archived_copy'] = { -- used with CS1 maint: Archive[d] copy as title
['en'] = '^archived?%s+copy$', -- for English; translators: keep this because templates imported from en.wiki
['local'] = nil, -- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
},
-- Lua patterns to match generic titles; usually created by bots or reference filling tools
-- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
-- generic titles and patterns in this table should be lowercase only
-- leave ['local'] nil except when there is a matching generic title in your language
-- boolean 'true' for plain-text searches; 'false' for pattern searches
['generic_titles'] = {
['accept'] = {
},
['reject'] = {
{['en'] = {'^wayback%s+machine$', false}, ['local'] = nil},
{['en'] = {'are you a robot', true}, ['local'] = nil},
{['en'] = {'hugedomains', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?no +title[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'page not found', true}, ['local'] = nil},
{['en'] = {'subscribe to read', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?unknown[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'website is for sale', true}, ['local'] = nil},
{['en'] = {'^404', false}, ['local'] = nil},
{['en'] = {'error[ %-]404', false}, ['local'] = nil},
{['en'] = {'internet archive wayback machine', true}, ['local'] = nil},
{['en'] = {'log into facebook', true}, ['local'] = nil},
{['en'] = {'login • instagram', true}, ['local'] = nil},
{['en'] = {'redirecting...', true}, ['local'] = nil},
{['en'] = {'usurped title', true}, ['local'] = nil}, -- added by a GreenC bot
{['en'] = {'wayback machine', true}, ['local'] = nil},
{['en'] = {'webcite query result', true}, ['local'] = nil},
{['en'] = {'wikiwix\'s cache', true}, ['local'] = nil},
{['en'] = {'bot verification', true}, ['local'] = nil},
}
},
-- boolean 'true' for plain-text searches, search string must be lowercase only
-- boolean 'false' for pattern searches
-- leave ['local'] nil except when there is a matching generic name in your language
['generic_names'] = {
['accept'] = {
{['en'] = {'%[%[[^|]*%(author%) *|[^%]]*%]%]', false}, ['local'] = nil},
},
['reject'] = {
{['en'] = {'about us', true}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]dvisor%f[%A]', false}, ['local'] = nil},
{['en'] = {'allmusic', true}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]uthor%f[%A]', false}, ['local'] = nil},
{['en'] = {'^[Bb]ureau$', false}, ['local'] = nil},
{['en'] = {'business', true}, ['local'] = nil},
{['en'] = {'cnn', true}, ['local'] = nil},
{['en'] = {'collaborator', true}, ['local'] = nil},
{['en'] = {'^[Cc]ompany$', false}, ['local'] = nil},
{['en'] = {'contributor', true}, ['local'] = nil},
{['en'] = {'contact us', true}, ['local'] = nil},
{['en'] = {'correspondent', true}, ['local'] = nil},
{['en'] = {'^[Dd]esk$', false}, ['local'] = nil},
{['en'] = {'directory', true}, ['local'] = nil},
{['en'] = {'%f[%(%[][%(%[]%s*eds?%.?%s*[%)%]]?$', false}, ['local'] = nil},
{['en'] = {'[,%.%s]%f[e]eds?%.?$', false}, ['local'] = nil},
{['en'] = {'^eds?[%.,;]', false}, ['local'] = nil},
{['en'] = {'^[%(%[]%s*[Ee][Dd][Ss]?%.?%s*[%)%]]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]dited%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]ditors?%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]mail%f[%A]', false}, ['local'] = nil},
{['en'] = {'facebook', true}, ['local'] = nil},
{['en'] = {'google', true}, ['local'] = nil},
{['en'] = {'^[Gg]roup$', false}, ['local'] = nil},
{['en'] = {'home page', true}, ['local'] = nil},
{['en'] = {'^[Ii]nc%.?$', false}, ['local'] = nil},
{['en'] = {'instagram', true}, ['local'] = nil},
{['en'] = {'interviewer', true}, ['local'] = nil},
{['en'] = {'^[Ll]imited$', false}, ['local'] = nil},
{['en'] = {'linkedIn', true}, ['local'] = nil},
{['en'] = {'^[Nn]ews$', false}, ['local'] = nil},
{['en'] = {'[Nn]ews[ %-]?[Rr]oom', false}, ['local'] = nil},
{['en'] = {'pinterest', true}, ['local'] = nil},
{['en'] = {'policy', true}, ['local'] = nil},
{['en'] = {'privacy', true}, ['local'] = nil},
{['en'] = {'reuters', true}, ['local'] = nil},
{['en'] = {'translator', true}, ['local'] = nil},
{['en'] = {'tumblr', true}, ['local'] = nil},
{['en'] = {'twitter', true}, ['local'] = nil},
{['en'] = {'site name', true}, ['local'] = nil},
{['en'] = {'statement', true}, ['local'] = nil},
{['en'] = {'submitted', true}, ['local'] = nil},
{['en'] = {'super.?user', false}, ['local'] = nil},
{['en'] = {'%f['..is_Latn..'][Uu]ser%f[^'..is_Latn..']', false}, ['local'] = nil},
{['en'] = {'updated', true}, ['local'] = nil},
{['en'] = {'verfasser', true}, ['local'] = nil},
}
}
}
--[[--------------------------< D A T E _ N A M E S >----------------------------------------------------------
This table of tables lists local language date names and fallback English date names.
The code in Date_validation will look first in the local table for valid date names.
If date names are not found in the local table, the code will look in the English table.
Because citations can be copied to the local wiki from en.wiki, the English is
required when the date-name translation function date_name_xlate() is used.
In these tables, season numbering is defined by
Extended Date/Time Format (EDTF) Specification (https://www.loc.gov/standards/datetime/)
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard
defines various divisions using numbers 21-41. CS1|2 only supports generic seasons.
EDTF does support the distinction between north and south hemisphere seasons
but CS1|2 has no way to make that distinction.
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
The standard does not address 'named' dates so, for the purposes of CS1|2,
Easter and Christmas are defined here as 98 and 99, which should be out of the
ISO 8601 (EDTF) range of uses for a while.
local_date_names_from_mediawiki is a boolean. When set to:
true – module will fetch local month names from MediaWiki for both date_names['local']['long'] and date_names['local']['short']; this will unconditionally overwrite manual translations
false – module will *not* fetch local month names from MediaWiki
Caveat lector: There is no guarantee that MediaWiki will provide short month names. At your wiki you can test
the results of the MediaWiki fetch in the debug console with this command (the result is alpha sorted):
=mw.dumpObject (p.date_names['local'])
While the module can fetch month names from MediaWiki, it cannot fetch the quarter, season, and named date names
from MediaWiki. Those must be translated manually.
]]
local local_date_names_from_mediawiki = true; -- when false, manual translation required for date_names['local']['long'] and date_names['local']['short']; overwrites manual translations
-- when true, module fetches long and short month names from MediaWiki
local date_names = {
['en'] = { -- English
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
-- when local_date_names_from_mediawiki = false
['local'] = { -- replace these English date names with the local language equivalents
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
['inv_local_long'] = {}, -- used in date reformatting & translation; copy of date_names['local'].long where k/v are inverted: [1]='<local name>' etc.
['inv_local_short'] = {}, -- used in date reformatting & translation; copy of date_names['local'].short where k/v are inverted: [1]='<local name>' etc.
['inv_local_quarter'] = {}, -- used in date translation; copy of date_names['local'].quarter where k/v are inverted: [1]='<local name>' etc.
['inv_local_season'] = {}, -- used in date translation; copy of date_names['local'].season where k/v are inverted: [1]='<local name>' etc.
['inv_local_named'] = {}, -- used in date translation; copy of date_names['local'].named where k/v are inverted: [1]='<local name>' etc.
['local_digits'] = {['0'] = '0', ['1'] = '1', ['2'] = '2', ['3'] = '3', ['4'] = '4', ['5'] = '5', ['6'] = '6', ['7'] = '7', ['8'] = '8', ['9'] = '9'}, -- used to convert local language digits to Western 0-9
['xlate_digits'] = {},
}
if local_date_names_from_mediawiki then -- if fetching local month names from MediaWiki is enabled
local long_t = {};
local short_t = {};
for i=1, 12 do -- loop 12x and
local name = lang_obj:formatDate('F', '2022-' .. i .. '-1'); -- get long month name for each i
long_t[name] = i; -- save it
name = lang_obj:formatDate('M', '2022-' .. i .. '-1'); -- get short month name for each i
short_t[name] = i; -- save it
end
date_names['local']['long'] = long_t; -- write the long table – overwrites manual translation
date_names['local']['short'] = short_t; -- write the short table – overwrites manual translation
end
-- create inverted date-name tables for reformatting and/or translation
for _, invert_t in pairs {{'long', 'inv_local_long'}, {'short', 'inv_local_short'}, {'quarter', 'inv_local_quarter'}, {'season', 'inv_local_season'}, {'named', 'inv_local_named'}} do
for name, i in pairs (date_names['local'][invert_t[1]]) do -- this table is ['name'] = i
date_names[invert_t[2]][i] = name; -- invert to get [i] = 'name' for conversions from ymd
end
end
if local_digits_from_mediawiki then -- if fetching local digits from MediaWiki is enabled
local digits_t = {};
for i=0, 9 do -- loop 10x and
digits_t [lang_obj:formatNum (i)] = tostring (i); -- format the loop indexer as local lang table index and assign loop indexer (a string) as the value
end
date_names['local_digits'] = digits_t;
end
for ld, ed in pairs (date_names.local_digits) do -- make a digit translation table for simple date translation from en to local language using local_digits table
date_names.xlate_digits [ed] = ld; -- en digit becomes index with local digit as the value
end
local df_template_patterns = { -- table of redirects to {{Use dmy dates}} and {{Use mdy dates}}
'{{ *[Uu]se +(dmy) +dates *[|}]', -- 1159k -- sorted by approximate transclusion count
'{{ *[Uu]se +(mdy) +dates *[|}]', -- 212k
'{{ *[Uu]se +(MDY) +dates *[|}]', -- 788
'{{ *[Uu]se +(DMY) +dates *[|}]', -- 343
'{{ *([Mm]dy) *[|}]', -- 176
'{{ *[Uu]se *(dmy) *[|}]', -- 156 + 18
'{{ *[Uu]se *(mdy) *[|}]', -- 149 + 11
'{{ *([Dd]my) *[|}]', -- 56
'{{ *[Uu]se +(MDY) *[|}]', -- 5
'{{ *([Dd]MY) *[|}]', -- 3
'{{ *[Uu]se(mdy)dates *[|}]', -- 1
'{{ *[Uu]se +(DMY) *[|}]', -- 0
'{{ *([Mm]DY) *[|}]', -- 0
}
local title_object = mw.title.getCurrentTitle();
local content; -- done this way so that unused templates appear in unused-template-reports; self-transcluded makes them look like they are used
if 10 ~= title_object.namespace then -- all namespaces except Template
content = title_object:getContent() or ''; -- get the content of the article or ''; new pages edited w/ve do not have 'content' until saved; ve does not preview; phab:T221625
end
local function get_date_format ()
if not content then -- nil content when we're in template
return nil; -- auto-formatting does not work in Template space so don't set global_df
end
for _, pattern in ipairs (df_template_patterns) do -- loop through the patterns looking for {{Use dmy dates}} or {{Use mdy dates}} or any of their redirects
local start, _, match = content:find(pattern); -- match is the three letters indicating desired date format
if match then
local use_dates_template = content:match ('%b{}', start); -- get the whole template
if use_dates_template:match ('| *cs1%-dates *= *[lsy][sy]?') then -- look for |cs1-dates=publication date length access-/archive-date length
return match:lower() .. '-' .. use_dates_template:match ('| *cs1%-dates *= *([lsy][sy]?)');
else
return match:lower() .. '-all'; -- no |cs1-dates= k/v pair; return value appropriate for use in |df=
end
end
end
end
local global_df; -- TODO: add this to <global_cs1_config_t>?
--[[-----------------< V O L U M E , I S S U E , P A G E S >------------------
These tables hold cite class values (from the template invocation) and identify those templates that support
|volume=, |issue=, and |page(s)= parameters. Cite conference and cite map require further qualification which
is handled in the main module.
]]
local templates_using_volume = {'citation', 'audio-visual', 'book', 'conference', 'encyclopaedia', 'interview', 'journal', 'magazine', 'map', 'news', 'report', 'techreport', 'thesis'}
local templates_using_issue = {'citation', 'conference', 'episode', 'interview', 'journal', 'magazine', 'map', 'news', 'podcast'}
local templates_not_using_page = {'audio-visual', 'episode', 'mailinglist', 'newsgroup', 'podcast', 'serial', 'sign', 'speech'}
--[[
These tables control when it is appropriate for {{citation}} to render |volume= and/or |issue=. The parameter
names in the tables constrain {{citation}} so that its renderings match the renderings of the equivalent cs1
templates. For example, {{cite web}} does not support |volume= so the equivalent {{citation |website=...}} must
not support |volume=.
]]
local citation_no_volume_t = { -- {{citation}} does not render |volume= when these parameters are used
'website', 'mailinglist', 'script-website',
}
local citation_issue_t = { -- {{citation}} may render |issue= when these parameters are used
'journal', 'magazine', 'newspaper', 'periodical', 'work',
'script-journal', 'script-magazine', 'script-newspaper', 'script-periodical', 'script-work',
}
--[[
Patterns for finding extra text in |volume=, |issue=, |page=, |pages=
]]
local vol_iss_pg_patterns = {
good_ppattern = '^P[^%.PpGg]', -- OK to begin with uppercase P: P7 (page 7 of section P), but not p123 (page 123); TODO: this allows 'Pages' which it should not
bad_ppatterns = { -- patterns for |page= and |pages=
'^[Pp][PpGg]?%.?[ %d]',
'^[Pp][Pp]?%. ', -- from {{p.}} and {{pp.}} templates
'^[Pp]ages?',
'^[Pp]gs.?',
},
vi_patterns_t = { -- combined to catch volume-like text in |issue= and issue-like text in |volume=
'^volumes?', -- volume-like text
'^vols?[%.:=]?',
'^issues?', --issue-like text
'^iss[%.:=]?',
'^numbers?',
'^nos?%A', -- don't match 'november' or 'nostradamus'
'^nr[%.:=]?',
'^n[%.:= ]', -- might be a valid issue without separator (space char is sep char here)
'^n°', -- 'n' with degree sign (U+00B0)
'^№', -- precomposed unicode numero character (U+2116)
},
}
--[[--------------------------< K E Y W O R D S >-------------------------------
These tables hold keywords for those parameters that have defined sets of acceptable keywords.
]]
--[[-------------------< K E Y W O R D S T A B L E >--------------------------
this is a list of keywords; each key in the list is associated with a table of
synonymous keywords possibly from different languages.
for I18N: add local-language keywords to value table; do not change the key.
For example, adding the German keyword 'ja':
['affirmative'] = {'yes', 'true', 'y', 'ja'},
Because CS1|2 templates from en.wiki articles are often copied to other local wikis,
it is recommended that the English keywords remain in these tables.
]]
local keywords = {
['amp'] = {'&', 'amp', 'ampersand'}, -- |name-list-style=
['and'] = {'and', 'serial'}, -- |name-list-style=
['affirmative'] = {'yes', 'true', 'y'}, -- |no-tracking=, |no-pp= -- Used by InternetArchiveBot
['afterword'] = {'afterword'}, -- |contribution=
['bot: unknown'] = {'bot: unknown'}, -- |url-status= -- Used by InternetArchiveBot
['cs1'] = {'cs1'}, -- |mode=
['cs2'] = {'cs2'}, -- |mode=
['dead'] = {'dead', 'deviated'}, -- |url-status= -- Used by InternetArchiveBot
['dmy'] = {'dmy'}, -- |df=
['dmy-all'] = {'dmy-all'}, -- |df=
['foreword'] = {'foreword'}, -- |contribution=
['free'] = {'free'}, -- |<id>-access= -- Used by InternetArchiveBot
['harv'] = {'harv'}, -- |ref=; this no longer supported; is_valid_parameter_value() called with <invert> = true
['introduction'] = {'introduction'}, -- |contribution=
['limited'] = {'limited'}, -- |url-access= -- Used by InternetArchiveBot
['live'] = {'live'}, -- |url-status= -- Used by InternetArchiveBot
['mdy'] = {'mdy'}, -- |df=
['mdy-all'] = {'mdy-all'}, -- |df=
['none'] = {'none'}, -- |postscript=, |ref=, |title=, |type= -- Used by InternetArchiveBot
['off'] = {'off'}, -- |title= (potentially also: |title-link=, |postscript=, |ref=, |type=)
['preface'] = {'preface'}, -- |contribution=
['registration'] = {'registration'}, -- |url-access= -- Used by InternetArchiveBot
['subscription'] = {'subscription'}, -- |url-access= -- Used by InternetArchiveBot
['unfit'] = {'unfit'}, -- |url-status= -- Used by InternetArchiveBot
['usurped'] = {'usurped'}, -- |url-status= -- Used by InternetArchiveBot
['vanc'] = {'vanc'}, -- |name-list-style=
['ymd'] = {'ymd'}, -- |df=
['ymd-all'] = {'ymd-all'}, -- |df=
-- ['yMd'] = {'yMd'}, -- |df=; not supported at en.wiki
-- ['yMd-all'] = {'yMd-all'}, -- |df=; not supported at en.wiki
}
--[[------------------------< X L A T E _ K E Y W O R D S >---------------------
this function builds a list, keywords_xlate{}, of the keywords found in keywords{} where the values from keywords{}
become the keys in keywords_xlate{} and the keys from keywords{} become the values in keywords_xlate{}:
['affirmative'] = {'yes', 'true', 'y'}, -- in keywords{}
becomes
['yes'] = 'affirmative', -- in keywords_xlate{}
['true'] = 'affirmative',
['y'] = 'affirmative',
the purpose of this function is to act as a translator between a non-English keyword and its English equivalent
that may be used in other modules of this suite
]]
local function xlate_keywords ()
local out_table = {}; -- output goes here
for k, keywords_t in pairs (keywords) do -- spin through the keywords table
for _, keyword in ipairs (keywords_t) do -- for each keyword
out_table[keyword] = k; -- create an entry in the output table where keyword is the key
end
end
return out_table;
end
local keywords_xlate = xlate_keywords (); -- the list of translated keywords
--[[----------------< M A K E _ K E Y W O R D S _ L I S T >---------------------
this function assembles, for parameter-value validation, the list of keywords appropriate to that parameter.
keywords_lists{}, is a table of tables from keywords{}
]]
local function make_keywords_list (keywords_lists)
local out_table = {}; -- output goes here
for _, keyword_list in ipairs (keywords_lists) do -- spin through keywords_lists{} and get a table of keywords
for _, keyword in ipairs (keyword_list) do -- spin through keyword_list{} and add each keyword, ...
table.insert (out_table, keyword); -- ... as plain text, to the output list
end
end
return out_table;
end
--[[----------------< K E Y W O R D S _ L I S T S >-----------------------------
this is a list of lists of valid keywords for the various parameters in [key].
Generally the keys in this table are the canonical en.wiki parameter names though
some are contrived because of use in multiple differently named parameters:
['yes_true_y'], ['id-access'].
The function make_keywords_list() extracts the individual keywords from the
appropriate list in keywords{}.
The lists in this table are used to validate the keyword assignment for the
parameters named in this table's keys.
]]
local keywords_lists = {
['yes_true_y'] = make_keywords_list ({keywords.affirmative}),
['contribution'] = make_keywords_list ({keywords.afterword, keywords.foreword, keywords.introduction, keywords.preface}),
['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all']}),
-- ['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all'], keywords.yMd, keywords['yMd-all']}), -- not supported at en.wiki
['mode'] = make_keywords_list ({keywords.cs1, keywords.cs2}),
['name-list-style'] = make_keywords_list ({keywords.amp, keywords['and'], keywords.vanc}),
['ref'] = make_keywords_list ({keywords.harv}), -- inverted check; |ref=harv no longer supported
['url-access'] = make_keywords_list ({keywords.subscription, keywords.limited, keywords.registration}),
['url-status'] = make_keywords_list ({keywords.dead, keywords.live, keywords.unfit, keywords.usurped, keywords['bot: unknown']}),
['id-access'] = make_keywords_list ({keywords.free}),
}
--[[--------------------------< C S 1 _ C O N F I G _ G E T >--------------------------------------------------
fetch and validate values from {{cs1 config}} template to fill <global_cs1_config_t>
no error messages; when errors are detected, the parameter value from {{cs1 config}} is blanked.
Supports all parameters and aliases associated with the metaparameters: DisplayAuthors, DisplayContributors,
DisplayEditors, DisplayInterviewers, DisplayTranslators, NameListStyle, and Mode. The DisplayWhatever metaparameters
accept numeric values only (|display-authors=etal and the like is not supported).
]]
local global_cs1_config_t = {}; -- TODO: add value returned from get_date_format() to this table?
local function get_cs1_config ()
if not content then -- nil content when we're in template
return nil; -- auto-formatting does not work in Template space so don't set global_df
end
local start = content:find('{{ *[Cc][Ss]1 config *[|}]'); -- <start> is offset into <content> when {{cs1 config}} found; nil else
if start then
local cs1_config_template = content:match ('%b{}', start); -- get the whole template
if not cs1_config_template then
return nil;
end
local params_t = mw.text.split (cs1_config_template:gsub ('^{{%s*', ''):gsub ('%s*}}$', ''), '%s*|%s*'); -- remove '{{' and '}}'; make a sequence of parameter/value pairs (split on the pipe)
table.remove (params_t, 1); -- remove the template name because it isn't a parameter/value pair
local config_meta_params_t = {'DisplayAuthors', 'DisplayContributors', 'DisplayEditors', 'DisplayInterviewers', 'DisplayTranslators', 'NameListStyle', 'Mode'};
local meta_param_map_t = {}; -- list of accepted parameter names usable in {{cs1 config}} goes here
for _, meta_param in ipairs (config_meta_params_t) do -- for i18n using <config_meta_params_t>, map template parameter names to their metaparameter equivalents
if 'table' == type (aliases[meta_param]) then -- if <meta_param> is a sequence,
for _, param in ipairs (aliases[meta_param]) do -- extract its contents
meta_param_map_t[param] = meta_param; -- and add to <meta_param_map_t>
end
else
meta_param_map_t[aliases[meta_param]] = meta_param; -- not a sequence so just add the parameter to <meta_param_map_t>
end
end
local keywords_t = {}; -- map valid keywords to their associate metaparameter; reverse form of <keyword_lists[key] for these metaparameters
for _, metaparam_t in ipairs ({{'NameListStyle', 'name-list-style'}, {'Mode', 'mode'}}) do -- only these metaparameter / keywords_lists key pairs
for _, keyword in ipairs (keywords_lists[metaparam_t[2]]) do -- spin through the list of keywords
keywords_t[keyword] = metaparam_t[1]; -- add [keyword] = metaparameter to the map
end
end
for _, param in ipairs (params_t) do -- spin through the {{cs1 config}} parameters and fill <global_cs1_config_t>
local k, v = param:match ('([^=]-)%s*=%s*(.+)'); -- <k> is the parameter name; <v> is parameter's assigned value
if k then
if k:find ('^display') then -- if <k> is one of the |display-<namelist>= parameters
if v:match ('%d+') then -- the assigned value must be digits; doesn't accept 'etal'
global_cs1_config_t[meta_param_map_t[k]]=v; -- add the display param and its value to globals table
end
else
if keywords_t[v] == meta_param_map_t[k] then -- keywords_t[v] returns nil or the metaparam name; these must be the same
global_cs1_config_t[meta_param_map_t[k]]=v; -- add the parameter and its value to globals table
end
end
end
end
end
end
get_cs1_config (); -- fill <global_cs1_config_t>
--[[---------------------< S T R I P M A R K E R S >----------------------------
Common pattern definition location for stripmarkers so that we don't have to go
hunting for them if (when) MediaWiki changes their form.
]]
local stripmarkers = {
['any'] = '\127[^\127]*UNIQ%-%-(%a+)%-[%a%d]+%-QINU[^\127]*\127', -- capture returns name of stripmarker
['math'] = '\127[^\127]*UNIQ%-%-math%-[%a%d]+%-QINU[^\127]*\127' -- math stripmarkers used in coins_cleanup() and coins_replace_math_stripmarker()
}
--[[------------< I N V I S I B L E _ C H A R A C T E R S >---------------------
This table holds non-printing or invisible characters indexed either by name or
by Unicode group. Values are decimal representations of UTF-8 codes. The table
is organized as a table of tables because the Lua pairs keyword returns table
data in an arbitrary order. Here, we want to process the table from top to bottom
because the entries at the top of the table are also found in the ranges specified
by the entries at the bottom of the table.
Also here is a pattern that recognizes stripmarkers that begin and end with the
delete characters. The nowiki stripmarker is not an error but some others are
because the parameter values that include them become part of the template's
metadata before stripmarker replacement.
]]
local invisible_defs = {
del = '\127', -- used to distinguish between stripmarker and del char
zwj = '\226\128\141', -- used with capture because zwj may be allowed
}
local invisible_chars = {
{'replacement', '\239\191\189'}, -- U+FFFD, EF BF BD
{'zero width joiner', '('.. invisible_defs.zwj .. ')'}, -- U+200D, E2 80 8D; capture because zwj may be allowed
{'zero width space', '\226\128\139'}, -- U+200B, E2 80 8B
{'hair space', '\226\128\138'}, -- U+200A, E2 80 8A
{'soft hyphen', '\194\173'}, -- U+00AD, C2 AD
{'horizontal tab', '\009'}, -- U+0009 (HT), 09
{'line feed', '\010'}, -- U+000A (LF), 0A
{'no-break space', '\194\160'}, -- U+00A0 (NBSP), C2 A0
{'carriage return', '\013'}, -- U+000D (CR), 0D
{'stripmarker', stripmarkers.any}, -- stripmarker; may or may not be an error; capture returns the stripmaker type
{'delete', '('.. invisible_defs.del .. ')'}, -- U+007F (DEL), 7F; must be done after stripmarker test; capture to distinguish isolated del chars not part of stripmarker
{'C0 control', '[\000-\008\011\012\014-\031]'}, -- U+0000–U+001F (NULL–US), 00–1F (except HT, LF, CR (09, 0A, 0D))
{'C1 control', '[\194\128-\194\159]'}, -- U+0080–U+009F (XXX–APC), C2 80 – C2 9F
-- {'Specials', '[\239\191\185-\239\191\191]'}, -- U+FFF9-U+FFFF, EF BF B9 – EF BF BF
-- {'Private use area', '[\238\128\128-\239\163\191]'}, -- U+E000–U+F8FF, EE 80 80 – EF A3 BF
-- {'Supplementary Private Use Area-A', '[\243\176\128\128-\243\191\191\189]'}, -- U+F0000–U+FFFFD, F3 B0 80 80 – F3 BF BF BD
-- {'Supplementary Private Use Area-B', '[\244\128\128\128-\244\143\191\189]'}, -- U+100000–U+10FFFD, F4 80 80 80 – F4 8F BF BD
}
--[[
Indic script makes use of zero width joiner as a character modifier so zwj
characters must be left in. This pattern covers all of the unicode characters
for these languages:
Devanagari 0900–097F – https://unicode.org/charts/PDF/U0900.pdf
Devanagari extended A8E0–A8FF – https://unicode.org/charts/PDF/UA8E0.pdf
Bengali 0980–09FF – https://unicode.org/charts/PDF/U0980.pdf
Gurmukhi 0A00–0A7F – https://unicode.org/charts/PDF/U0A00.pdf
Gujarati 0A80–0AFF – https://unicode.org/charts/PDF/U0A80.pdf
Oriya 0B00–0B7F – https://unicode.org/charts/PDF/U0B00.pdf
Tamil 0B80–0BFF – https://unicode.org/charts/PDF/U0B80.pdf
Telugu 0C00–0C7F – https://unicode.org/charts/PDF/U0C00.pdf
Kannada 0C80–0CFF – https://unicode.org/charts/PDF/U0C80.pdf
Malayalam 0D00–0D7F – https://unicode.org/charts/PDF/U0D00.pdf
plus the not-necessarily Indic scripts for Sinhala and Burmese:
Sinhala 0D80-0DFF - https://unicode.org/charts/PDF/U0D80.pdf
Myanmar 1000-109F - https://unicode.org/charts/PDF/U1000.pdf
Myanmar extended A AA60-AA7F - https://unicode.org/charts/PDF/UAA60.pdf
Myanmar extended B A9E0-A9FF - https://unicode.org/charts/PDF/UA9E0.pdf
the pattern is used by has_invisible_chars() and coins_cleanup()
]]
local indic_script = '[\224\164\128-\224\181\191\224\163\160-\224\183\191\225\128\128-\225\130\159\234\167\160-\234\167\191\234\169\160-\234\169\191]';
-- list of emoji that use a zwj character (U+200D) to combine with another emoji
-- from: https://unicode.org/Public/emoji/17.0/emoji-zwj-sequences.txt; version: 17.0; 2025-01-08
-- table created by: [[:en:Module:Make emoji zwj table]]
local emoji_t = { -- indexes are decimal forms of the hex values in U+xxxx
[8596] = true, -- U+2194 ↔ left right arrow
[8597] = true, -- U+2195 ↕ up down arrow
[9760] = true, -- U+2620 ☠ skull and crossbones
[9792] = true, -- U+2640 ♀ female sign
[9794] = true, -- U+2642 ♂ male sign
[9877] = true, -- U+2695 ⚕ staff of aesculapius
[9878] = true, -- U+2696 ⚖ scales
[9895] = true, -- U+26A7 ⚧ male with stroke and male and female sign
[9992] = true, -- U+2708 ✈ airplane
[10052] = true, -- U+2744 ❄ snowflake
[10084] = true, -- U+2764 ❤ heavy black heart
[10145] = true, -- U+27A1 ➡ black rightwards arrow
[11035] = true, -- U+2B1B ⬛ black large square
[127752] = true, -- U+1F308 🌈 rainbow
[127787] = true, -- U+1F32B 🌫 fog
[127806] = true, -- U+1F33E 🌾 ear of rice
[127859] = true, -- U+1F373 🍳 cooking
[127868] = true, -- U+1F37C 🍼 baby bottle
[127876] = true, -- U+1F384 🎄 christmas tree
[127891] = true, -- U+1F393 🎓 graduation cap
[127908] = true, -- U+1F3A4 🎤 microphone
[127912] = true, -- U+1F3A8 🎨 artist palette
[127979] = true, -- U+1F3EB 🏫 school
[127981] = true, -- U+1F3ED 🏭 factory
[128048] = true, -- U+1F430 🐰 rabbit face
[128102] = true, -- U+1F466 👦 boy
[128103] = true, -- U+1F467 👧 girl
[128104] = true, -- U+1F468 👨 man
[128105] = true, -- U+1F469 👩 woman
[128139] = true, -- U+1F48B 💋 kiss mark
[128165] = true, -- U+1F4A5 💥 collision symbol
[128168] = true, -- U+1F4A8 💨 dash symbol
[128171] = true, -- U+1F4AB 💫 dizzy symbol
[128187] = true, -- U+1F4BB 💻 personal computer
[128188] = true, -- U+1F4BC 💼 brief case
[128293] = true, -- U+1F525 🔥 fire
[128295] = true, -- U+1F527 🔧 wrench
[128300] = true, -- U+1F52C 🔬 microscope
[128488] = true, -- U+1F5E8 🗨 left speech bubble
[128640] = true, -- U+1F680 🚀 rocket
[128658] = true, -- U+1F692 🚒 fire engine
[129001] = true, -- U+1F7E9 🟩 large green square
[129003] = true, -- U+1F7EB 🟫 large brown square
[129309] = true, -- U+1F91D 🤝 handshake
[129455] = true, -- U+1F9AF 🦯 probing cane
[129456] = true, -- U+1F9B0 🦰 emoji component red hair
[129457] = true, -- U+1F9B1 🦱 emoji component curly hair
[129458] = true, -- U+1F9B2 🦲 emoji component bald
[129459] = true, -- U+1F9B3 🦳 emoji component white hair
[129466] = true, -- U+1F9BA 🦺 safety vest
[129468] = true, -- U+1F9BC 🦼 motorized wheelchair
[129469] = true, -- U+1F9BD 🦽 manual wheelchair
[129489] = true, -- U+1F9D1 🧑 adult
[129490] = true, -- U+1F9D2 🧒 child
[129648] = true, -- U+1FA70 🩰 ballet shoes
[129657] = true, -- U+1FA79 🩹 adhesive bandage
[129775] = true, -- U+1FAEF fight cloud
[129778] = true, -- U+1FAF2 🫲 leftwards hand
}
--[[----------------------< L A N G U A G E S U P P O R T >-------------------
These tables and constants support various language-specific functionality.
]]
--local this_wiki_code = mw.getContentLanguage():getCode(); -- get this wiki's language code
local this_wiki_code = lang_obj:getCode(); -- get this wiki's language code
if string.match (mw.site.server, 'wikidata') then
this_wiki_code = mw.getCurrentFrame():callParserFunction('int', {'lang'}); -- on Wikidata so use interface language setting instead
end
local mw_languages_by_tag_t = mw.language.fetchLanguageNames (this_wiki_code, 'all'); -- get a table of language tag/name pairs known to Wikimedia; used for interwiki tests
local mw_languages_by_name_t = {};
for k, v in pairs (mw_languages_by_tag_t) do -- build a 'reversed' table name/tag language pairs know to MediaWiki; used for |language=
v = mw.ustring.lower (v); -- lowercase for tag fetch; get name's proper case from mw_languages_by_tag_t[<tag>]
if mw_languages_by_name_t[v] then -- when name already in the table
if 2 == #k or 3 == #k then -- if tag does not have subtags
mw_languages_by_name_t[v] = k; -- prefer the shortest tag for this name
end
else -- here when name not in the table
mw_languages_by_name_t[v] = k; -- so add name and matching tag
end
end
local inter_wiki_map = {}; -- map of interwiki prefixes that are language-code prefixes
for k, v in pairs (mw.site.interwikiMap ('local')) do -- spin through the base interwiki map (limited to local)
if mw_languages_by_tag_t[v["prefix"]] then -- if the prefix matches a known language tag
inter_wiki_map[v["prefix"]] = true; -- add it to our local map
end
end
--[[--------------------< S C R I P T _ L A N G _ C O D E S >-------------------
This table is used to hold ISO 639-1 two-character and ISO 639-3 three-character
language codes that apply only to |script-title= and |script-chapter=
]]
local script_lang_codes = {
'ab', 'am', 'ar', 'as', 'az', 'be', 'bg', 'bn', 'bo', 'bs', 'ce', 'chr',
'cu', 'dv', 'dz', 'el', 'fa', 'grc', 'gu', 'he', 'hi', 'hy', 'ja', 'ka',
'kaa', 'kk', 'km', 'kn', 'ko', 'ku', 'ky', 'lo', 'mk', 'ml', 'mn', 'mni',
'mr', 'my', 'ne', 'or', 'ota', 'pa', 'ps', 'ru', 'sd', 'si', 'sr', 'syc',
'ta', 'te', 'tg', 'th', 'ti', 'tkr', 'tt', 'ug', 'uk', 'ur', 'uz', 'yi',
'yue', 'zh', 'zgh'
};
--[[---------------< L A N G U A G E R E M A P P I N G >----------------------
These tables hold language information that is different (correct) from MediaWiki's definitions
For each ['<tag>'] = 'language name' in lang_code_remap{} there must be a matching ['language name'] = {'language name', '<tag>'} in lang_name_remap{}
lang_tag_remap{}:
key is always lowercase ISO 639-1, -2, -3 language tag or a valid lowercase IETF language tag
value is properly spelled and capitalized language name associated with <tag>
only one language name per <tag>;
key/value pair must have matching entry in lang_name_remap{}
lang_name_remap{}:
key is always lowercase language name
value is a table the holds correctly spelled and capitalized language name [1] and associated tag [2] (tag must match a tag key in lang_tag_remap{})
may have multiple keys referring to a common preferred name and tag; For example:
['kolsch'] and ['kölsch'] both refer to 'Kölsch' and 'ksh'
]]
local lang_tag_remap = { -- used for |language= and |script-title= / |script-chapter=
['als'] = 'Tosk Albanian', -- MediaWiki returns Alemannisch
['bh'] = 'Bihari', -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bla'] = 'Blackfoot', -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['bn'] = 'Bengali', -- MediaWiki returns Bangla
['ca-valencia'] = 'Valencian', -- IETF variant of Catalan
['fkv'] = 'Kven', -- MediaWiki returns Kvensk
['gsw'] = 'Swiss German',
['ilo'] = 'Ilocano', -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['ksh'] = 'Kölsch', -- MediaWiki: Colognian; use IANA/ISO 639 preferred name
['ksh-x-colog'] = 'Colognian', -- override MediaWiki ksh; no IANA/ISO 639 code for Colognian; IETF private code created at Module:Lang/data
['mis-x-ripuar'] = 'Ripuarian', -- override MediaWiki ksh; no IANA/ISO 639 code for Ripuarian; IETF private code created at Module:Lang/data
['nan-tw'] = 'Taiwanese Hokkien', -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese and support en.wiki preferred name
['sr-ec'] = 'Serbian (Cyrillic script)', -- MediaWiki returns српски (ћирилица)
['sr-el'] = 'Serbian (Latin script)', -- MediaWiki returns srpski (latinica)
}
local lang_name_remap = { -- used for |language=; names require proper capitalization; tags must be lowercase
['alemannic'] = {'Swiss German', 'gsw'}, -- ISO 639-2, -3 alternate for Swiss German; MediaWiki mediawiki returns Alemannic for gsw; en.wiki preferred name
['alemannisch'] = {'Swiss German', 'gsw'}, -- not an ISO or IANA language name; MediaWiki uses 'als' as a subdomain name for Alemannic Wikipedia: als.wikipedia.org
['bangla'] = {'Bengali', 'bn'}, -- MediaWiki returns Bangla (the endonym) but we want Bengali (the exonym); here we remap
['bengali'] = {'Bengali', 'bn'}, -- MediaWiki doesn't use exonym so here we provide correct language name and 639-1 code
['bhojpuri'] = {'Bhojpuri', 'bho'}, -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bihari'] = {'Bihari', 'bh'}, -- MediaWiki replaces 'Bihari' with 'Bhojpuri' so 'Bihari' cannot be found
['blackfoot'] = {'Blackfoot', 'bla'}, -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['colognian'] = {'Colognian', 'ksh-x-colog'}, -- MediaWiki preferred name for ksh
['ilocano'] = {'Ilocano', 'ilo'}, -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['kolsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name (use non-diacritical o instead of umlaut ö)
['kölsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name
['kven'] = {'Kven', 'fkv'}, -- Unicode CLDR have decided not to support English language name for these two...
['kvensk'] = {'Kven', 'fkv'}, -- ...they say to refer to IANA registry for English names
['ripuarian'] = {'Ripuarian', 'mis-x-ripuar'}, -- group of dialects; no code in MediaWiki or in IANA/ISO 639
['serbian (cyrillic script)'] = {'Serbian (Cyrillic script)', 'sr-cyrl'}, -- special case to get correct tag when |language=sr-ec
['serbian (latin script)'] = {'Serbian (Latin script)', 'sr-latn'}, -- special case to get correct tag when |language=sr-el
['swiss german'] = {'Swiss German', 'gsw'},
['taiwanese hokkien'] = {'Taiwanese Hokkien', 'nan-tw'}, -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese
['tosk albanian'] = {'Tosk Albanian', 'als'}, -- MediaWiki replaces 'Tosk Albanian' with 'Alemannisch' so 'Tosk Albanian' cannot be found
['valencian'] = {'Valencian', 'ca-valencia'}, -- variant of Catalan; categorizes as Valencian
}
--[[---------------< P R O P E R T I E S _ C A T E G O R I E S >----------------
Properties categories. These are used for investigating qualities of citations.
]]
local prop_cats = {
['foreign-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is foreign-language name, $2 is ISO639-1 code
['foreign-lang-source-2'] = 'CS1 foreign language sources (ISO 639-2)|$1', -- |language= category; a cat for ISO639-2 languages; $1 is the ISO 639-2 code used as a sort key
['interproj-linked-name'] = 'CS1 interproject-linked names|$1', -- any author, editor, etc that has an interproject link; $1 is interproject tag used as a sort key
['interwiki-linked-name'] = 'CS1 interwiki-linked names|$1', -- any author, editor, etc that has an interwiki link; $1 is interwiki tag used as a sort key; yeilds to interproject
['local-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is local-language name, $2 is ISO639-1 code; not emitted when local_lang_cat_enable is false
['location-test'] = 'CS1 location test',
['long-vol'] = 'CS1: long volume value', -- probably temporary cat to identify scope of |volume= values longer than 4 characters
['script'] = 'CS1 uses $1-language script ($2)', -- |script-title=xx: has matching category; $1 is language name, $2 is language tag
['tracked-param'] = 'CS1 tracked parameter: $1', -- $1 is base (enumerators removed) parameter name
['unfit'] = 'CS1: unfit URL', -- |url-status=unfit or |url-status=usurped; used to be a maint cat
['vanc-accept'] = 'CS1:Vancouver names with accept markup', -- for |vauthors=/|veditors= with accept-as-written markup
['year-range-abbreviated'] = 'CS1: abbreviated year range', -- probably temporary cat to identify scope of |date=, |year= values using YYYY–YY form
}
--[[-------------------< T I T L E _ T Y P E S >--------------------------------
Here we map a template's CitationClass to TitleType (default values for |type= parameter)
]]
local title_types = {
['AV-media-notes'] = 'Media notes',
['document'] = 'Document',
['interview'] = 'Interview',
['mailinglist'] = 'Mailing list',
['map'] = 'Map',
['podcast'] = 'Podcast',
['pressrelease'] = 'Press release',
['report'] = 'Report',
['speech'] = 'Speech',
['techreport'] = 'Technical report',
['thesis'] = 'Thesis',
}
--[[--------------------------< B U I L D _ K N O W N _ F R E E _ D O I _ R E G I S T R A N T S _ T A B L E >--
build a table of doi registrants known to be free-to-read In a doi, the registrant ID is the series of digits
between the '10.' and the first '/': in doi 10.1100/sommat, 1100 is the registrant ID
see §3.2.2 DOI prefix of the Doi Handbook p. 43
https://www.doi.org/doi-handbook/DOI_Handbook_Final.pdf#page=43
]]
local function build_free_doi_registrants_table()
local registrants_t = {};
for _, v in ipairs ({
'1045', '1074', '1096', '1100', '1155', '1186', '1194', '1371', '1613', '1629', '1989', '1999', '2147', '2196', '3285', '3389', '3390', '3906',
'3748', '3814', '3847', '3897', '4061', '4089', '4103', '4172', '4175', '4230', '4236', '4239', '4240', '4249', '4251',
'4252', '4253', '4254', '4291', '4292', '4329', '4330', '4331', '5086', '5194', '5210', '5306', '5312', '5313', '5314',
'5315', '5316', '5317', '5318', '5319', '5320', '5321', '5334', '5402', '5409', '5410', '5411', '5412',
'5492', '5493', '5494', '5495', '5496', '5497', '5498', '5499', '5500', '5501', '5527', '5528', '5662',
'6064', '6219', '7167', '7217', '7287', '7482', '7490', '7554', '7717', '7759', '7766', '9778', '11131', '11569', '11647',
'11648', '12688', '12703', '12715', '12942', '12998', '13105', '14256', '14293', '14303', '15215', '15347', '15412', '15560', '16995',
'17645', '18637', '19080', '19173', '20944', '21037', '21105', '21468', '21767', '21425', '22261', '22323', '22459', '24105', '24196', '24966',
'26775', '30845', '32545', '35711', '35712', '35713', '35995', '36648', '37126', '37532', '37871', '47128',
'47622', '47959', '52437', '52975', '53288', '53347', '54081', '54947', '55667', '55914', '57009', '58647', '59081',
}) do
registrants_t[v] = true; -- build a k/v table of known free-to-read doi registrants
end
return registrants_t;
end
-- known free registrants identifiable by the doi suffix incipit
local extended_registrants_t = { -- doi suffix incipits are evaluated as lua patterns
['1002'] = {'aelm', 'leap', 'loe2%.', 'lol2%.'}, -- Advanced Electronic Materials, Learned Publishing, L&O e-Lectures, L&O Letters
['1016'] = {'j%.aace', 'j%.aed', 'j%.aiopen', 'j%.animal', 'j%.apsb', 'j%.addicn', -- AACE Endocrinology and Diabetes, AACE Endocrinology and Diabetes, AI Open, Animal, Acta Pharmaceutica Sinica B, Addiction Neuroscience
'j%.abrep', 'j%.gpb', 'j%.heliyon', 'j%.nlp', 'j%.patter', 'j%.proche', -- Addictive Behaviors Reports, Genomics, Proteomics & Bioinformatics after 2015, Heliyon, Natural Language Processing, Patterns, Procedia Chemistry
'j%.vgie', 'S1672-0229'}, -- VideoGIE, Genomics, Proteomics & Bioinformatics before 2015
['1017'] = {'apj%.', 'nlp', 'mdh', 'S15574660'}, -- Natural Language Processing Journal, Medical History, Asia Pacific Journal
['1046'] = {'j%.1365-8711', 'j%.1365-246x'}, -- MNRAS, GJI
['1021'] = {'acscentsci', 'acsomega'}, -- ACS Central Science, ACS Omega
['1093'] = {'mnras', 'mnrasl', 'gji', 'pnasnexus', 'rasti'}, -- MNRAS, MNRAS Letters, GJI, PNAS Nexus, RASTI
['1098'] = {'rsbm', 'rsob', 'rsos'}, -- Biographical Memoirs of Fellows of the Royal Society, Open Biology, Royal Society Open Science
['1099'] = {'acmi', 'mic', '00221287', 'mgen'}, -- Access Microbiology, Microbiology, Journal of General Microbiology, Microbial Genomics
['1107'] = {'S20569890', 'S20522525', 'S16005775', 'S24143146'}, -- Acta Crystallographica E, IUCrJ, Journal of Synchrotron Radiation, IUCrData
['1109'] = {'oa', 'oj'}, -- IEEE Open Access..., IEEE Open Journal...
['1111'] = {'aogs', 'j%.1365-2966', 'j%.1745-3933', 'j%.1365-246X'}, -- Acta Obstetricia et Gynecologica Scandinavica, MNRAS, MNRAS Letters, GJI
['1128'] = {'asmcr', 'jmbe', 'mbio', 'mra', 'spectrum', 'msphere', 'msystems'}, --ASM Case Reports, Journal of Microbiology & Biology Education, mBio, Microbiology Resource Announcements, Microbiology Spectrum, mSphere, mSystems
['1136'] = {'bmjopen'}, -- BMJ Open
['1140'] = {'epjc'}, -- European Physical Journal C
['1192'] = {'bjo'}, -- BJPsych Open
['1210'] = {'jendso','jcemcr'}, -- Journal of the Endocrine Society, JCEM Case Reports
['1215'] = {'21573689', '21573698'}, -- L&O Fluids
['1590'] = {'0102-3306'}, -- Acta Botanica Brasilica
['4171'] = {'dm','mag'}, -- Documenta Mathematica, EMS Magazine
['4319'] = {'lo%.', 'lol%.', 'lom%.'}, -- L&O, L&O e-Lectures, L&O Methods
['5852'] = {'ejt'}, -- European Journal of Taxonomy
['7155'] = {'jgaa'}, -- Journal of Graph Algorithms and Applications
['11158'] = {'saasp'}, -- Systematic and Applied Acarology Special Publications
['11646'] = {'megataxa', 'mesozoic'}, -- Megataxa, Mesozoic
['14231'] = {'ag'}, -- Algebraic Geometry
['15446'] = {'abc'}, -- Acta Biológica Colombiana
['17239'] = {'jowr'}, -- Journal of Writing Research
['22073'] = {'pja'}, -- Persian Journal of Acarology
['24310'] = {'abm'}, -- Acta Botanica Malacitana
['24425'] = {'agp'}, -- Acta Geologica Polonica
['35249'] = {'rche'}, -- Revista Chilena de Entomología
['37520'] = {'fi'}, -- Fossil Imprint
['53562'] = {'ajcb'} -- Asian Journal of Conservation Biology
}
--[[===================<< E R R O R M E S S A G I N G >>======================
]]
--[[----------< E R R O R M E S S A G E S U P P L E M E N T S >-------------
I18N for those messages that are supplemented with additional specific text that
describes the reason for the error
TODO: merge this with special_case_translations{}?
]]
local err_msg_supl = {
['char'] = 'invalid character', -- |isbn=, |sbn=
['check'] = 'checksum', -- |isbn=, |sbn=
empty_str = '(empty string)', -- empty unknown parameter check when cite has |=
['flag'] = 'flag', -- |archive-url=
['form'] = 'invalid form', -- |isbn=, |sbn=
['group'] = 'invalid group id', -- |isbn=
['initials'] = 'initials', -- Vancouver
['invalid language code'] = 'invalid language code', -- |script-<param>=
['journal'] = 'journal', -- |bibcode=
['length'] = 'length', -- |isbn=, |bibcode=, |sbn=
['liveweb'] = 'liveweb', -- |archive-url=
['missing comma'] = 'missing comma', -- Vancouver
['missing prefix'] = 'missing prefix', -- |script-<param>=
['missing title part'] = 'missing title part', -- |script-<param>=
['name'] = 'name', -- Vancouver
['non-Latin char'] = 'non-Latin character', -- Vancouver
['path'] = 'path', -- |archive-url=
['prefix'] = 'invalid prefix', -- |isbn=
['punctuation'] = 'punctuation', -- Vancouver
['save'] = 'save command', -- |archive-url=
['suffix'] = 'suffix', -- Vancouver
['timestamp'] = 'timestamp', -- |archive-url=
['unknown language code'] = 'unknown language code', -- |script-<param>=
['value'] = 'value', -- |bibcode=
['year'] = 'year', -- |bibcode=
}
--[[--------------< E R R O R _ C O N D I T I O N S >---------------------------
Error condition table. This table has two sections: errors at the top, maintenance
at the bottom. Maint 'messaging' does not have a 'message' (message=nil)
The following contains a list of IDs for various error conditions defined in the
code. For each ID, we specify a text message to display, an error category to
include, and whether the error message should be wrapped as a hidden comment.
Anchor changes require identical changes to matching anchor in Help:CS1 errors
TODO: rename error_conditions{} to something more generic; create separate error
and maint tables inside that?
]]
local error_conditions = {
err_accessdate_missing_url = {
message = '<code class="cs1-code">|access-date=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'accessdate_missing_url',
category = 'CS1 errors: access-date without URL',
hidden = false
},
err_apostrophe_markup = {
message = 'Italic or bold markup not allowed in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'apostrophe_markup',
category = 'CS1 errors: markup',
hidden = false
},
err_archive_date_missing_url = {
message = '<code class="cs1-code">|archive-date=</code> requires <code class="cs1-code">|archive-url=</code>',
anchor = 'archive_date_missing_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_date_url_ts_mismatch = {
message = '<code class="cs1-code">|archive-date=</code> / <code class="cs1-code">|archive-url=</code> timestamp mismatch; $1 suggested',
anchor = 'archive_date_url_ts_mismatch',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_missing_date = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|archive-date=</code>',
anchor = 'archive_missing_date',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_missing_url = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'archive_missing_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_url = {
message = '<code class="cs1-code">|archive-url=</code> is malformed: $1', -- $1 is error message detail
anchor = 'archive_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_arxiv_missing = {
message = '<code class="cs1-code">|arxiv=</code> required',
anchor = 'arxiv_missing',
category = 'CS1 errors: arXiv', -- same as bad arxiv
hidden = false
},
err_asintld_missing_asin = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|asin=</code>', -- $1 is parameter name
anchor = 'asintld_missing_asin',
category = 'CS1 errors: ASIN TLD',
hidden = false
},
err_bad_arxiv = {
message = 'Check <code class="cs1-code">|arxiv=</code> value',
anchor = 'bad_arxiv',
category = 'CS1 errors: arXiv',
hidden = false
},
err_bad_asin = {
message = 'Check <code class="cs1-code">|asin=</code> value',
anchor = 'bad_asin',
category ='CS1 errors: ASIN',
hidden = false
},
err_bad_asin_tld = {
message = 'Check <code class="cs1-code">|asin-tld=</code> value',
anchor = 'bad_asin_tld',
category ='CS1 errors: ASIN TLD',
hidden = false
},
err_bad_bibcode = {
message = 'Check <code class="cs1-code">|bibcode=</code> $1', -- $1 is error message detail
anchor = 'bad_bibcode',
category = 'CS1 errors: bibcode',
hidden = false
},
err_bad_biorxiv = {
message = 'Check <code class="cs1-code">|biorxiv=</code> value',
anchor = 'bad_biorxiv',
category = 'CS1 errors: bioRxiv',
hidden = false
},
err_bad_citeseerx = {
message = 'Check <code class="cs1-code">|citeseerx=</code> value',
anchor = 'bad_citeseerx',
category = 'CS1 errors: citeseerx',
hidden = false
},
err_bad_date = {
message = 'Check date values in: $1', -- $1 is a parameter name list
anchor = 'bad_date',
category = 'CS1 errors: dates',
hidden = false
},
err_bad_doi = {
message = 'Check <code class="cs1-code">|doi=</code> value',
anchor = 'bad_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_bad_hdl = {
message = 'Check <code class="cs1-code">|hdl=</code> value',
anchor = 'bad_hdl',
category = 'CS1 errors: HDL',
hidden = false
},
err_bad_isbn = {
message = 'Check <code class="cs1-code">|isbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_isbn',
category = 'CS1 errors: ISBN',
hidden = false
},
err_bad_ismn = {
message = 'Check <code class="cs1-code">|ismn=</code> value',
anchor = 'bad_ismn',
category = 'CS1 errors: ISMN',
hidden = false
},
err_bad_issn = {
message = 'Check <code class="cs1-code">|$1issn=</code> value', -- $1 is 'e' or '' for eissn or issn
anchor = 'bad_issn',
category = 'CS1 errors: ISSN',
hidden = false
},
err_bad_jfm = {
message = 'Check <code class="cs1-code">|jfm=</code> value',
anchor = 'bad_jfm',
category = 'CS1 errors: JFM',
hidden = false
},
err_bad_jstor = {
message = 'Check <code class="cs1-code">|jstor=</code> value',
anchor = 'bad_jstor',
category = 'CS1 errors: JSTOR',
hidden = false
},
err_bad_lccn = {
message = 'Check <code class="cs1-code">|lccn=</code> value',
anchor = 'bad_lccn',
category = 'CS1 errors: LCCN',
hidden = false
},
err_bad_medrxiv = {
message = 'Check <code class="cs1-code">|medrxiv=</code> value',
anchor = 'bad_medrxiv',
category = 'CS1 errors: medRxiv',
hidden = false
},
err_bad_mr = {
message = 'Check <code class="cs1-code">|mr=</code> value',
anchor = 'bad_mr',
category = 'CS1 errors: MR',
hidden = false
},
err_bad_oclc = {
message = 'Check <code class="cs1-code">|oclc=</code> value',
anchor = 'bad_oclc',
category = 'CS1 errors: OCLC',
hidden = false
},
err_bad_ol = {
message = 'Check <code class="cs1-code">|ol=</code> value',
anchor = 'bad_ol',
category = 'CS1 errors: OL',
hidden = false
},
err_bad_osti = {
message = 'Check <code class="cs1-code">|osti=</code> value',
anchor = 'bad_osti',
category = 'CS1 errors: OSTI',
hidden = false
},
err_bad_paramlink = { -- for |title-link=, |author/editor/translator-link=, |series-link=, |episode-link=
message = 'Check <code class="cs1-code">|$1=</code> value', -- $1 is parameter name
anchor = 'bad_paramlink',
category = 'CS1 errors: parameter link',
hidden = false
},
err_bad_pmc = {
message = 'Check <code class="cs1-code">|pmc=</code> value',
anchor = 'bad_pmc',
category = 'CS1 errors: PMC',
hidden = false
},
err_bad_pmid = {
message = 'Check <code class="cs1-code">|pmid=</code> value',
anchor = 'bad_pmid',
category = 'CS1 errors: PMID',
hidden = false
},
err_bad_rfc = {
message = 'Check <code class="cs1-code">|rfc=</code> value',
anchor = 'bad_rfc',
category = 'CS1 errors: RFC',
hidden = false
},
err_bad_s2cid = {
message = 'Check <code class="cs1-code">|s2cid=</code> value',
anchor = 'bad_s2cid',
category = 'CS1 errors: S2CID',
hidden = false
},
err_bad_sbn = {
message = 'Check <code class="cs1-code">|sbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_sbn',
category = 'CS1 errors: SBN',
hidden = false
},
err_bad_ssrn = {
message = 'Check <code class="cs1-code">|ssrn=</code> value',
anchor = 'bad_ssrn',
category = 'CS1 errors: SSRN',
hidden = false
},
err_bad_url = {
message = 'Check $1 value', -- $1 is parameter name
anchor = 'bad_url',
category = 'CS1 errors: URL',
hidden = false
},
err_bad_usenet_id = {
message = 'Check <code class="cs1-code">|message-id=</code> value',
anchor = 'bad_message_id',
category = 'CS1 errors: message-id',
hidden = false
},
err_bad_zbl = {
message = 'Check <code class="cs1-code">|zbl=</code> value',
anchor = 'bad_zbl',
category = 'CS1 errors: Zbl',
hidden = false
},
err_bare_url_missing_title = {
message = '$1 missing title', -- $1 is parameter name
anchor = 'bare_url_missing_title',
category = 'CS1 errors: bare URL',
hidden = false
},
err_biorxiv_missing = {
message = '<code class="cs1-code">|biorxiv=</code> required',
anchor = 'biorxiv_missing',
category = 'CS1 errors: bioRxiv', -- same as bad bioRxiv
hidden = false
},
err_chapter_ignored = {
message = '<code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'chapter_ignored',
category = 'CS1 errors: chapter ignored',
hidden = false
},
err_citation_missing_title = {
message = 'Missing or empty <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'citation_missing_title',
category = 'CS1 errors: missing title',
hidden = false
},
err_citeseerx_missing = {
message = '<code class="cs1-code">|citeseerx=</code> required',
anchor = 'citeseerx_missing',
category = 'CS1 errors: citeseerx', -- same as bad citeseerx
hidden = false
},
err_cite_web_url = { -- this error applies to cite web and to cite podcast
message = 'Missing or empty <code class="cs1-code">|url=</code>',
anchor = 'cite_web_url',
category = 'CS1 errors: requires URL',
hidden = false
},
err_class_ignored = {
message = '<code class="cs1-code">|class=</code> ignored',
anchor = 'class_ignored',
category = 'CS1 errors: class',
hidden = false
},
err_contributor_ignored = {
message = '<code class="cs1-code">|contributor=</code> ignored',
anchor = 'contributor_ignored',
category = 'CS1 errors: contributor',
hidden = false
},
err_contributor_missing_required_param = {
message = '<code class="cs1-code">|contributor=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'contributor_missing_required_param',
category = 'CS1 errors: contributor',
hidden = false
},
err_deprecated_params = {
message = 'Cite uses deprecated parameter <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'deprecated_params',
category = 'CS1 errors: deprecated parameters',
hidden = false
},
err_disp_name = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name; $2 is the assigned value
anchor = 'disp_name',
category = 'CS1 errors: display-names',
hidden = false,
},
err_doibroken_missing_doi = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|doi=</code>', -- $1 is parameter name
anchor = 'doibroken_missing_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_embargo_missing_pmc = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|pmc=</code>', -- $1 is parameter name
anchor = 'embargo_missing_pmc',
category = 'CS1 errors: PMC embargo',
hidden = false
},
err_empty_citation = {
message = 'Empty citation',
anchor = 'empty_citation',
category = 'CS1 errors: empty citation',
hidden = false
},
err_etal = {
message = 'Explicit use of et al. in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'explicit_et_al',
category = 'CS1 errors: explicit use of et al.',
hidden = false
},
err_extra_text_edition = {
message = '<code class="cs1-code">|edition=</code> has extra text',
anchor = 'extra_text_edition',
category = 'CS1 errors: extra text: edition',
hidden = false,
},
err_extra_text_issue = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_issue',
category = 'CS1 errors: extra text: issue',
hidden = false,
},
err_extra_text_pages = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_pages',
category = 'CS1 errors: extra text: pages',
hidden = false,
},
err_extra_text_volume = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_volume',
category = 'CS1 errors: extra text: volume',
hidden = false,
},
err_first_missing_last = {
message = '<code class="cs1-code">|$1=</code> missing <code class="cs1-code">|$2=</code>', -- $1 is first alias, $2 is matching last alias
anchor = 'first_missing_last',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_format_missing_url = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|$2=</code>', -- $1 is format parameter $2 is url parameter
anchor = 'format_missing_url',
category = 'CS1 errors: format without URL',
hidden = false
},
err_generic_name = {
message = '<code class="cs1-code">|$1=</code> has generic name', -- $1 is parameter name
anchor = 'generic_name',
category = 'CS1 errors: generic name',
hidden = false,
},
err_generic_title = {
message = 'Cite uses generic title',
anchor = 'generic_title',
category = 'CS1 errors: generic title',
hidden = false,
},
err_invalid_isbn_date = {
message = 'ISBN / Date incompatibility',
anchor = 'invalid_isbn_date',
category = 'CS1 errors: ISBN date',
hidden = true
},
err_invalid_param_val = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name $2 is parameter value
anchor = 'invalid_param_val',
category = 'CS1 errors: invalid parameter value',
hidden = false
},
err_invisible_char = {
message = '$1 in $2 at position $3', -- $1 is invisible char $2 is parameter name $3 is position number
anchor = 'invisible_char',
category = 'CS1 errors: invisible characters',
hidden = false
},
err_medrxiv_missing = {
message = '<code class="cs1-code">|medrxiv=</code> required',
anchor = 'medrxiv_missing',
category = 'CS1 errors: medRxiv', -- same as bad medRxiv
hidden = false
},
err_missing_name = {
message = 'Missing <code class="cs1-code">|$1$2=</code>', -- $1 is modified NameList; $2 is enumerator
anchor = 'missing_name',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_missing_periodical = {
message = 'Cite $1 requires <code class="cs1-code">|$2=</code>', -- $1 is cs1 template name; $2 is canonical periodical parameter name for cite $1
anchor = 'missing_periodical',
category = 'CS1 errors: missing periodical',
hidden = false
},
err_missing_pipe = {
message = 'Missing pipe in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'missing_pipe',
category = 'CS1 errors: missing pipe',
hidden = false
},
err_missing_publisher = {
message = 'Cite $1 requires <code class="cs1-code">|$2=</code>', -- $1 is cs1 template name; $2 is canonical publisher parameter name for cite $1
anchor = 'missing_publisher',
category = 'CS1 errors: missing publisher',
hidden = false
},
err_numeric_names = {
message = '<code class="cs1-code">|$1=</code> has numeric name', -- $1 is parameter name',
anchor = 'numeric_names',
category = 'CS1 errors: numeric name',
hidden = false,
},
err_param_access_requires_param = {
message = '<code class="cs1-code">|$1-access=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'param_access_requires_param',
category = 'CS1 errors: param-access',
hidden = false
},
err_param_has_ext_link = {
message = 'External link in <code class="cs1-code">$1</code>', -- $1 is parameter name
anchor = 'param_has_ext_link',
category = 'CS1 errors: external links',
hidden = false
},
err_param_has_twl_url = {
message = 'Wikipedia Library link in <code class="cs1-code">$1</code>', -- $1 is parameter name
anchor = 'param_has_twl_url',
category = 'CS1 errors: URL',
hidden = false
},
err_parameter_ignored = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'parameter_ignored',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_parameter_ignored_suggest = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored (<code class="cs1-code">|$2=</code> suggested)', -- $1 is unknown parameter $2 is suggested parameter name
anchor = 'parameter_ignored_suggest',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_periodical_ignored = {
message = '<code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'periodical_ignored',
category = 'CS1 errors: periodical ignored',
hidden = false
},
err_redundant_parameters = {
message = 'More than one of $1 specified', -- $1 is error message detail
anchor = 'redundant_parameters',
category = 'CS1 errors: redundant parameter',
hidden = false
},
err_script_parameter = {
message = 'Invalid <code class="cs1-code">|$1=</code>: $2', -- $1 is parameter name $2 is script language code or error detail
anchor = 'script_parameter',
category = 'CS1 errors: script parameters',
hidden = false
},
err_ssrn_missing = {
message = '<code class="cs1-code">|ssrn=</code> required',
anchor = 'ssrn_missing',
category = 'CS1 errors: SSRN',
hidden = false
},
err_text_ignored = {
message = 'Text "$1" ignored', -- $1 is ignored text
anchor = 'text_ignored',
category = 'CS1 errors: unrecognized parameter',
hidden = false
},
err_trans_missing_title = {
message = '<code class="cs1-code">|trans-$1=</code> requires <code class="cs1-code">|$1=</code> or <code class="cs1-code">|script-$1=</code>', -- $1 is base parameter name
anchor = 'trans_missing_title',
category = 'CS1 errors: translated title',
hidden = false
},
err_param_unknown_empty = {
message = 'Cite has empty unknown parameter$1: $2', -- $1 is 's' or empty space; $2 is emty unknown param list
anchor = 'param_unknown_empty',
category = 'CS1 errors: empty unknown parameters',
hidden = false
},
err_vancouver = {
message = 'Vancouver style error: $1 in name $2', -- $1 is error detail, $2 is the nth name
anchor = 'vancouver',
category = 'CS1 errors: Vancouver style',
hidden = false
},
err_wikilink_in_url = {
message = 'URL–wikilink conflict', -- uses ndash
anchor = 'wikilink_in_url',
category = 'CS1 errors: URL–wikilink conflict', -- uses ndash
hidden = false
},
--[[--------------------------< M A I N T >-------------------------------------
maint messages do not have a message (message = nil); otherwise the structure
is the same as error messages
]]
maint_archive_origin = {
message = nil,
anchor = 'archive_origin',
category = 'CS1 maint: archive origin',
hidden = true,
},
maint_archived_copy = {
message = nil,
anchor = 'archived_copy',
category = 'CS1 maint: archived copy as title',
hidden = true,
},
maint_bibcode = {
message = nil,
anchor = 'bibcode',
category = 'CS1 maint: bibcode',
hidden = true,
},
maint_location_no_publisher = { -- cite book, conference, encyclopedia; citation as book cite or encyclopedia cite
message = nil,
anchor = 'location_no_publisher',
category = 'CS1 maint: location missing publisher',
hidden = true,
},
maint_bot_unknown = {
message = nil,
anchor = 'bot:_unknown',
category = 'CS1 maint: bot: original URL status unknown',
hidden = true,
},
maint_date_auto_xlated = { -- date auto-translation not supported by en.wiki
message = nil,
anchor = 'date_auto_xlated',
category = 'CS1 maint: date auto-translated',
hidden = true,
},
maint_date_format = {
message = nil,
anchor = 'date_format',
category = 'CS1 maint: date format',
hidden = true,
},
maint_date_year = {
message = nil,
anchor = 'date_year',
category = 'CS1 maint: date and year',
hidden = true,
},
maint_deprecated_archive = {
message = nil,
anchor = 'deprecated_archive',
category = 'CS1 maint: deprecated archival service',
hidden = true,
},
maint_doi_ignore = {
message = nil,
anchor = 'doi_ignore',
category = 'CS1 maint: ignored DOI errors',
hidden = true,
},
maint_doi_inactive = {
message = nil,
anchor = 'doi_inactive',
category = 'CS1 maint: DOI inactive',
hidden = true,
},
maint_doi_inactive_dated = {
message = nil,
anchor = 'doi_inactive_dated',
category = 'CS1 maint: DOI inactive as of $2$3$1', -- $1 is year, $2 is month-name or empty string, $3 is space or empty string
hidden = true,
},
maint_doi_unflagged_free = {
message = nil,
anchor = 'doi_unflagged_free',
category = 'CS1 maint: unflagged free DOI',
hidden = true,
},
maint_extra_punct = {
message = nil,
anchor = 'extra_punct',
category = 'CS1 maint: extra punctuation',
hidden = true,
},
maint_id_limit_load_fail = { -- applies to all cs1|2 templates on a page;
message = nil, -- maint message (category link) never emitted
anchor = 'id_limit_load_fail',
category = 'CS1 maint: ID limit load fail',
hidden = true,
},
maint_isbn_ignore = {
message = nil,
anchor = 'ignore_isbn_err',
category = 'CS1 maint: ignored ISBN errors',
hidden = true,
},
maint_issn_ignore = {
message = nil,
anchor = 'ignore_issn',
category = 'CS1 maint: ignored ISSN errors',
hidden = true,
},
maint_jfm_format = {
message = nil,
anchor = 'jfm_format',
category = 'CS1 maint: JFM format',
hidden = true,
},
maint_location = {
message = nil,
anchor = 'location',
category = 'CS1 maint: location',
hidden = true,
},
maint_missing_class = {
message = nil,
anchor = 'missing_class',
category = 'CS1 maint: missing class',
hidden = true,
},
maint_mr_format = {
message = nil,
anchor = 'mr_format',
category = 'CS1 maint: MR format',
hidden = true,
},
maint_mult_names = {
message = nil,
anchor = 'mult_names',
category = 'CS1 maint: multiple names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_numeric_names = {
message = nil,
anchor = 'numeric_names',
category = 'CS1 maint: numeric names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_others = {
message = nil,
anchor = 'others',
category = 'CS1 maint: others',
hidden = true,
},
maint_others_avm = {
message = nil,
anchor = 'others_avm',
category = 'CS1 maint: others in cite AV media (notes)',
hidden = true,
},
maint_overridden_setting = {
message = nil,
anchor = 'overridden',
category = 'CS1 maint: overridden setting',
hidden = true,
},
maint_page_art_num = {
message = nil,
anchor = 'page_art_num',
category = 'CS1 maint: article number as page number',
hidden = true,
},
maint_pmc_embargo = {
message = nil,
anchor = 'embargo',
category = 'CS1 maint: PMC embargo expired',
hidden = true,
},
maint_pmc_format = {
message = nil,
anchor = 'pmc_format',
category = 'CS1 maint: PMC format',
hidden = true,
},
maint_postscript = {
message = nil,
anchor = 'postscript',
category = 'CS1 maint: postscript',
hidden = true,
},
maint_publisher_location = {
message = nil,
anchor = 'publisher_location',
category = 'CS1 maint: publisher location',
hidden = true,
},
maint_ref_duplicates_default = {
message = nil,
anchor = 'ref_default',
category = 'CS1 maint: ref duplicates default',
hidden = true,
},
maint_shortened_archive_url = {
message = nil,
anchor = 'shortened_archive_url',
category = 'CS1 maint: shortened archive url',
hidden = true,
},
maint_unknown_lang = {
message = nil,
anchor = 'unknown_lang',
category = 'CS1 maint: unrecognized language',
hidden = true,
},
maint_untitled = {
message = nil,
anchor = 'untitled',
category = 'CS1 maint: untitled periodical',
hidden = true,
},
maint_url_status = {
message = nil,
anchor = 'url_status',
category = 'CS1 maint: url-status',
hidden = true,
},
maint_work_isbn = {
message = nil,
anchor = 'work_isbn',
category = 'CS1 maint: work parameter with ISBN',
hidden = true,
},
maint_year= {
message = nil,
anchor = 'year',
category = 'CS1 maint: year',
hidden = true,
},
maint_zbl = {
message = nil,
anchor = 'zbl',
category = 'CS1 maint: Zbl',
hidden = true,
},
}
--[[--------------------------< I D _ L I M I T S _ D A T A _ T >----------------------------------------------
fetch id limits for certain identifiers from c:Data:CS1/Identifier limits.tab. This source is a json tabular
data file maintained at wikipedia commons. Convert the json format to a table of k/v pairs.
The values from <id_limits_data_t> are used to set handle.id_limit.
From 2025-02-21, MediaWiki is broken. Use this link to edit the tablular data file:
https://commons.wikimedia.org/w/index.php?title=Data:CS1/Identifier_limits.tab&action=edit
See Phab:T389105
]]
local id_limits_data_t = {};
local use_commons_data = true; -- set to false if your wiki does not have access to mediawiki commons; then,
if false == use_commons_data then -- update this table from https://commons.wikimedia.org/wiki/Data:CS1/Identifier_limits.tab; last update: 2025-02-21
id_limits_data_t = {['OCLC'] = 10450000000, ['OSTI'] = 23010000, ['PMC'] = 11900000, ['PMID'] = 40400000, ['RFC'] = 9300, ['SSRN'] = 5200000, ['S2CID'] = 276000000}; -- this table must be maintained locally
else -- here for wikis that do have access to mediawiki commons
local load_fail_limit = 99999999999; -- very high number to avoid error messages on load failure
id_limits_data_t = {['OCLC'] = load_fail_limit, ['OSTI'] = load_fail_limit, ['PMC'] = load_fail_limit, ['PMID'] = load_fail_limit, ['RFC'] = load_fail_limit, ['SSRN'] = load_fail_limit, ['S2CID'] = load_fail_limit};
local id_limits_data_load_fail = false; -- flag; assume that we will be successful when loading json id limit tabular data
if mw.ext.data == nil then
id_limits_data_load_fail = true; -- safeguard against Lua errors if mw.ext.data is not available for some reason
else
local tab_data_t = mw.ext.data.get ('CS1/Identifier limits.tab'); -- attempt to load the tabular data from commons into <tab_data_t>
if false == tab_data_t then -- undocumented 'feature': mw.ext.data.get() sometimes returns false
id_limits_data_load_fail = true; -- set the flag so that Module:Citation/CS1 can create an unannotated maint category
else
for _, limit_t in ipairs (tab_data_t.data) do -- overwrite default <load_fail_limit> values from the data table in the tabular data
id_limits_data_t[limit_t[1]] = limit_t[2]; -- <limit[1]> is identifier; <limit[2]> is upper limit for that identifier
end
end
end
end
--[[--------------------------< I D _ H A N D L E R S >--------------------------------------------------------
The following contains a list of values for various defined identifiers. For each
identifier we specify a variety of information necessary to properly render the
identifier in the citation.
parameters: a list of parameter aliases for this identifier; first in the list is the canonical form
link: Wikipedia article name
redirect: a local redirect to a local Wikipedia article name; at en.wiki, 'ISBN (identifier)' is a redirect to 'International Standard Book Number'
q: Wikidata q number for the identifier
label: the label preceding the identifier; label is linked to a Wikipedia article (in this order):
redirect from id_handlers['<id>'].redirect when use_identifier_redirects is true
Wikidata-supplied article name for the local wiki from id_handlers['<id>'].q
local article name from id_handlers['<id>'].link
prefix: the first part of a URL that will be concatenated with a second part which usually contains the identifier
suffix: optional third part to be added after the identifier
encode: true if URI should be percent-encoded; otherwise false
COinS: identifier link or keyword for use in COinS:
for identifiers registered at info-uri.info use: info:.... where '...' is the appropriate identifier label
for identifiers that have COinS keywords, use the keyword: rft.isbn, rft.issn, rft.eissn
for |asin= and |ol=, which require assembly, use the keyword: url
for others make a URL using the value in prefix/suffix and #label, use the keyword: pre (not checked; any text other than 'info', 'rft', or 'url' works here)
set to nil to leave the identifier out of the COinS
separator: character or text between label and the identifier in the rendered citation
id_limit: for those identifiers with established limits, this property holds the upper limit
access: use this parameter to set the access level for all instances of this identifier.
the value must be a valid access level for an identifier (see ['id-access'] in this file).
custom_access: to enable custom access level for an identifier, set this parameter
to the parameter that should control it (normally 'id-access')
]]
local id_handlers = {
['ARXIV'] = {
parameters = {'arxiv', 'eprint'},
link = 'arXiv',
redirect = 'arXiv (identifier)',
q = 'Q118398',
label = 'arXiv',
prefix = 'https://arxiv.org/abs/',
encode = false,
COinS = 'info:arxiv',
separator = ':',
access = 'free', -- free to read
},
['ASIN'] = {
parameters = { 'asin', 'ASIN' },
link = 'Amazon Standard Identification Number',
redirect = 'ASIN (identifier)',
q = 'Q1753278',
label = 'ASIN',
prefix = 'https://www.amazon.',
COinS = 'url',
separator = ' ',
encode = false;
},
['BIBCODE'] = {
parameters = {'bibcode'},
link = 'Bibcode',
redirect = 'Bibcode (identifier)',
q = 'Q25754',
label = 'Bibcode',
prefix = 'https://ui.adsabs.harvard.edu/abs/',
encode = false,
COinS = 'info:bibcode',
separator = ':',
custom_access = 'bibcode-access',
},
['BIORXIV'] = {
parameters = {'biorxiv'},
link = 'bioRxiv',
redirect = 'bioRxiv (identifier)',
q = 'Q19835482',
label = 'bioRxiv',
prefix = 'https://doi.org/',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['CITESEERX'] = {
parameters = {'citeseerx'},
link = 'CiteSeerX',
redirect = 'CiteSeerX (identifier)',
q = 'Q2715061',
label = 'CiteSeerX',
prefix = 'https://citeseerx.ist.psu.edu/viewdoc/summary?doi=',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['DOI'] = { -- Used by InternetArchiveBot
parameters = { 'doi', 'DOI'},
link = 'Digital object identifier',
redirect = 'doi (identifier)',
q = 'Q25670',
label = 'doi',
prefix = 'https://doi.org/',
COinS = 'info:doi',
separator = ':',
encode = true,
custom_access = 'doi-access',
},
['EISSN'] = {
parameters = {'eissn', 'EISSN'},
link = 'International Standard Serial Number#Electronic ISSN',
redirect = 'eISSN (identifier)',
q = 'Q46339674',
label = 'eISSN',
prefix = 'https://search.worldcat.org/issn/',
COinS = 'rft.eissn',
encode = false,
separator = ' ',
},
['HDL'] = {
parameters = { 'hdl', 'HDL' },
link = 'Handle System',
redirect = 'hdl (identifier)',
q = 'Q3126718',
label = 'hdl',
prefix = 'https://hdl.handle.net/',
COinS = 'info:hdl',
separator = ':',
encode = true,
custom_access = 'hdl-access',
},
['ISBN'] = { -- Used by InternetArchiveBot
parameters = {'isbn', 'ISBN'},
link = 'International Standard Book Number',
redirect = 'ISBN (identifier)',
q = 'Q33057',
label = 'ISBN',
prefix = 'Special:BookSources/',
COinS = 'rft.isbn',
separator = ' ',
},
['ISMN'] = {
parameters = {'ismn', 'ISMN'},
link = 'International Standard Music Number',
redirect = 'ISMN (identifier)',
q = 'Q1666938',
label = 'ISMN',
prefix = '', -- not currently used;
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['ISSN'] = {
parameters = {'issn', 'ISSN'},
link = 'International Standard Serial Number',
redirect = 'ISSN (identifier)',
q = 'Q131276',
label = 'ISSN',
prefix = 'https://search.worldcat.org/issn/',
COinS = 'rft.issn',
encode = false,
separator = ' ',
},
['JFM'] = {
parameters = {'jfm', 'JFM'},
link = 'Jahrbuch über die Fortschritte der Mathematik',
redirect = 'JFM (identifier)',
q = '',
label = 'JFM',
prefix = 'https://zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['JSTOR'] = {
parameters = {'jstor', 'JSTOR'},
link = 'JSTOR',
redirect = 'JSTOR (identifier)',
q = 'Q1420342',
label = 'JSTOR',
prefix = 'https://www.jstor.org/stable/',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
custom_access = 'jstor-access',
},
['LCCN'] = {
parameters = {'lccn', 'LCCN'},
link = 'Library of Congress Control Number',
redirect = 'LCCN (identifier)',
q = 'Q620946',
label = 'LCCN',
prefix = 'https://lccn.loc.gov/',
COinS = 'info:lccn',
encode = false,
separator = ' ',
},
['MEDRXIV'] = {
parameters = {'medrxiv'},
link = 'medRxiv',
redirect = 'medRxiv (identifier)',
q = 'Q58465838',
label = 'medRxiv',
prefix = 'https://www.medrxiv.org/content/',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = false,
separator = ' ',
},
['MR'] = {
parameters = {'mr', 'MR'},
link = 'Mathematical Reviews',
redirect = 'MR (identifier)',
q = 'Q211172',
label = 'MR',
prefix = 'https://mathscinet.ams.org/mathscinet-getitem?mr=',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['OCLC'] = {
parameters = {'oclc', 'OCLC'},
link = 'OCLC',
redirect = 'OCLC (identifier)',
q = 'Q190593',
label = 'OCLC',
prefix = 'https://search.worldcat.org/oclc/',
COinS = 'info:oclcnum',
encode = true,
separator = ' ',
id_limit = id_limits_data_t.OCLC or 0,
},
['OL'] = {
parameters = { 'ol', 'OL' },
link = 'Open Library',
redirect = 'OL (identifier)',
q = 'Q1201876',
label = 'OL',
prefix = 'https://openlibrary.org/',
COinS = 'url',
separator = ' ',
encode = true,
custom_access = 'ol-access',
},
['OSTI'] = {
parameters = {'osti', 'OSTI'},
link = 'Office of Scientific and Technical Information',
redirect = 'OSTI (identifier)',
q = 'Q2015776',
label = 'OSTI',
prefix = 'https://www.osti.gov/biblio/',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = id_limits_data_t.OSTI or 0,
custom_access = 'osti-access',
},
['PMC'] = {
parameters = {'pmc', 'PMC'},
link = 'PubMed Central',
redirect = 'PMC (identifier)',
q = 'Q229883',
label = 'PMC',
prefix = 'https://www.ncbi.nlm.nih.gov/pmc/articles/PMC',
suffix = '',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = id_limits_data_t.PMC or 0,
access = 'free', -- free to read
},
['PMID'] = {
parameters = {'pmid', 'PMID'},
link = 'PubMed Identifier',
redirect = 'PMID (identifier)',
q = 'Q2082879',
label = 'PMID',
prefix = 'https://pubmed.ncbi.nlm.nih.gov/',
COinS = 'info:pmid',
encode = false,
separator = ' ',
id_limit = id_limits_data_t.PMID or 0,
},
['RFC'] = {
parameters = {'rfc', 'RFC'},
link = 'Request for Comments',
redirect = 'RFC (identifier)',
q = 'Q212971',
label = 'RFC',
prefix = 'https://tools.ietf.org/html/rfc',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = id_limits_data_t.RFC or 0,
access = 'free', -- free to read
},
['SBN'] = {
parameters = {'sbn', 'SBN'},
link = 'Standard Book Number', -- redirect to International_Standard_Book_Number#History
redirect = 'SBN (identifier)',
label = 'SBN',
prefix = 'Special:BookSources/0-', -- prefix has leading zero necessary to make 9-digit sbn a 10-digit isbn
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['SSRN'] = {
parameters = {'ssrn', 'SSRN'},
link = 'Social Science Research Network',
redirect = 'SSRN (identifier)',
q = 'Q7550801',
label = 'SSRN',
prefix = 'https://papers.ssrn.com/sol3/papers.cfm?abstract_id=',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = id_limits_data_t.SSRN or 0,
custom_access = 'ssrn-access',
},
['S2CID'] = {
parameters = {'s2cid', 'S2CID'},
link = 'Semantic Scholar',
redirect = 'S2CID (identifier)',
q = 'Q22908627',
label = 'S2CID',
prefix = 'https://api.semanticscholar.org/CorpusID:',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = id_limits_data_t.S2CID or 0,
custom_access = 's2cid-access',
},
['USENETID'] = {
parameters = {'message-id'},
link = 'Usenet',
redirect = 'Usenet (identifier)',
q = 'Q193162',
label = 'Usenet:',
prefix = 'news:',
encode = false,
COinS = 'pre', -- use prefix value
separator = ' ',
},
['ZBL'] = {
parameters = {'zbl', 'ZBL' },
link = 'Zentralblatt MATH',
redirect = 'Zbl (identifier)',
q = 'Q190269',
label = 'Zbl',
prefix = 'https://zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
}
--[[--------------------------< E X P O R T S >---------------------------------
]]
return {
use_identifier_redirects = use_identifier_redirects, -- booleans defined in the settings at the top of this module
local_lang_cat_enable = local_lang_cat_enable,
date_name_auto_xlate_enable = date_name_auto_xlate_enable,
date_digit_auto_xlate_enable = date_digit_auto_xlate_enable,
enable_sort_keys = enable_sort_keys,
suppress_archive_today_urls = suppress_archive_today_urls,
-- tables and variables created when this module is loaded
dependencies_t = dependencies_t, -- used to suppress parameters dependent on url-holding parameters holding archive.today urls
enum_needs_xlation = '1' ~= date_names.xlate_digits['1'], -- to avoid unnecessary enumerator translation
global_df = get_date_format (), -- this line can be replaced with "global_df = 'dmy-all'," to have all dates auto translated to dmy format.
global_cs1_config_t = global_cs1_config_t, -- global settings from {{cs1 config}}
id_limits_data_load_fail = id_limits_data_load_fail, -- true when commons tabular identifier-limit data fails to load
known_free_doi_registrants_t = build_free_doi_registrants_table(),
punct_skip = build_skip_table (punct_skip, punct_meta_params),
url_skip = build_skip_table (url_skip, url_meta_params),
archive_today_tlds_t = {['today'] = true, ['ph'] = true, ['is'] = true, ['md'] = true, ['li'] = true, ['fo'] = true, ['vn'] = true}; -- used by is_archive_today_url()
name_space_sort_keys = name_space_sort_keys,
aliases = aliases,
special_case_translation = special_case_translation,
date_names = date_names,
err_msg_supl = err_msg_supl,
error_conditions = error_conditions,
editor_markup_patterns = editor_markup_patterns,
et_al_patterns = et_al_patterns,
extended_registrants_t = extended_registrants_t,
id_handlers = id_handlers,
keywords_lists = keywords_lists,
keywords_xlate = keywords_xlate,
stripmarkers = stripmarkers,
invisible_chars = invisible_chars,
invisible_defs = invisible_defs,
indic_script = indic_script,
emoji_t = emoji_t,
maint_cats = maint_cats,
messages = messages,
presentation = presentation,
prop_cats = prop_cats,
script_lang_codes = script_lang_codes,
lang_tag_remap = lang_tag_remap,
lang_name_remap = lang_name_remap,
this_wiki_code = this_wiki_code,
title_types = title_types,
uncategorized_namespaces = uncategorized_namespaces_t,
uncategorized_subpages = uncategorized_subpages,
templates_using_volume = templates_using_volume,
templates_using_issue = templates_using_issue,
templates_not_using_page = templates_not_using_page,
vol_iss_pg_patterns = vol_iss_pg_patterns,
single_letter_2nd_lvl_domains_t = single_letter_2nd_lvl_domains_t,
url_access_map_t = url_access_map_t,
inter_wiki_map = inter_wiki_map,
mw_languages_by_tag_t = mw_languages_by_tag_t,
mw_languages_by_name_t = mw_languages_by_name_t,
citation_class_map_t = citation_class_map_t,
citation_issue_t = citation_issue_t,
citation_no_volume_t = citation_no_volume_t,
}
ot1uexgsv9fa53fhfrs76kgr0oeg1sy
Module:Citation/CS1/Whitelist
828
15541
167626
147623
2026-04-25T18:40:28Z
Ellenor2000
20768
copiat https://en.wikipedia.org/w/index.php?title=Module:Citation/CS1/Whitelist&action=edit quam part de sincronisation con wikipedia in anglés
167626
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
Franz Liszt
0
16671
167647
149776
2026-04-25T20:44:16Z
Dorlota
13847
167647
wikitext
text/x-wiki
{{Biografie
|nómine = Franz Liszt
|foto = Liszt-kaulbach.jpg
|land = {{AUT}} {{HUN}}
|nascentie = 22-im de octobre 1811
|nasc_loc = Raiding
|morte = 31-im de julí 1886
|mort_loc = Bayreuth
|ocupation = Musico, Compositor, Pianist, Scritor, Dirigente
}}
'''Franz Liszt''' ([[Hungarian]]: Liszt Ferenc) esset un [[Austria|austrian]]-[[Hungaria|hungarian]] compositor, pianist, scritor e diregente e musico. Il nascet li 22-im de octobre 1811 in [[Raiding]] ([[Austria-Hungaria]]) e morit li 31-im de julí 1886 in [[Bayreuth]].
Franz Liszt es un del max famosi e max influential virtuosos de [[piano]] e un del max productiv compositores del 19-im secul. Su ovre have plu quam 1300 pezzes de musica.
{{DEFAULTSORT: Liszt, Franz}}
[[Categorie: Compositores]]
[[Categorie: Musica]]
qkesoemvdcnev0roli1n32o29qk9a5o
Frédéric Chopin
0
18253
167642
153390
2026-04-25T20:42:46Z
Dorlota
13847
167642
wikitext
text/x-wiki
{{Biografie
|nómine = Frédéric Chopin
|foto = Ciągliński_Portret_Chopina_1909.jpg
|land = {{POL}} {{FRA}}
|nascentie = 22-im de februar 1810/1-im de marte 1810
|nasc_loc = Żelazowa Wola
|morte = 17-im de octotre 1849
|mort_loc = Paris
|ocupation = Musico, Compositor, Pianist, Pedagogo
}}
'''Fryderyk Franciszek Chopin''' ([[frances]]: Frédéric François Chopin) esset un [[Polonia|polones]]-[[Francia|frances]] compositor, pianist, pedagogo e musico. Il nascet li 22-im de februar 1810/1-ima de marte 1810 in [[Żelazowa Wola]] ([[Polonia]]) e morit li 17-im de octotre 1849 in [[Paris]].
Li patre de Chopin esset frances e li matre polones. Chopin nascet e adultijat in [[Warszawa]] ([[Polonia]]), ma translocat in li annu 1830 a [[Francia]] pro professional causes. Li vive de Chopin esset dominat per maladies e il ja morit in li etá de 39 annus.
Frédéric Chopin es egardat quam important representante del [[romantica]]. Il composit presc solmen musico por li [[piano]] e su musico esset influentiat per li musico polones del folklore.
Li aeroportu de [[Warszawa]] hodie es nominat segun Frédéric Chopin.
{{DEFAULTSORT: Chopin, Frédéric}}
[[Categorie: Compositores]]
[[Categorie: Musica]]
mflp3xrdzx9s5nmgqaymu7kqlt7rh1s
Wolfgang Amadeus Mozart
0
18373
167661
163083
2026-04-25T20:50:54Z
Dorlota
13847
167661
wikitext
text/x-wiki
{{Biografie
|nómine = Wolfgang Amadeus Mozart
|foto = Wolfgang-amadeus-mozart 1.jpg
|land = {{AUT}}
|nascentie = 27-im de januar 1756
|nasc_loc = Salzburg
|morte = 5-im de decembre 1791
|mort_loc = Vienna
|ocupation = Musico, Compositor
}}
'''Wolfgang Amadeus Mozart''' esset un tre famos austrian compositor de música classic. Il nascet ye li 27-im de januar [[1756]] in [[Salzburg]] [[Austria]] e morit li 5-im de decembre [[1791]] in [[Vienna]] [[Austria]].
Wolfgang Amadeus Mozart es egardat quam un de li max important compositores del historie e su musica es egardat quam max important ovres del arte universal.
{{DEFAULTSORT: Mozart, Wolfgang Amadeus}}
[[Category:Austrianes]]
[[Categorie: Compositores]]
82gulht86bx3rfm6lav4ali6cf3f43l
Kurt Weill
0
18830
167660
157036
2026-04-25T20:47:37Z
Dorlota
13847
167660
wikitext
text/x-wiki
{{Biografie
|nómine = Kurt Weill
|foto = Bundesarchiv Bild 146-2005-0119, Kurt Weill.jpg
|land = {{GER}}, {{USA}}
|nascentie = 2-im de marte 1900
|nasc_loc = Dessau
|morte = 3-im de april 1950
|mort_loc = New York
|ocupation = Compositor
}}
'''Kurt Julian Weill''' esset un [[Germania|german]] compositor. Il nascet li 2-im de marte 1900 in [[Dessau-Roßlau|Dessau]] e morit li 3-im de april 1950 in [[New York]] ([[USA]]). Kurt Weill devenit famosi pro su colaboration con li german poete e dramaturg [[Bertolt Brecht]].
Kurt Weill esset de judeic orígine e pro to il fugit de [[Germania]] a [[Francia]] e plu tard al [[Unit States de America]] pro li anti-semitic politica del [[Nationalsocialisme|nationalsocialist]] guvernament. Il devenit cive del [[USA]] in li annu 1943.
==Ovre==
Li ovre de Weill consiste de [[ópera]]s, [[operette]]s, musica por [[ballette]], musicals e ovre por orchestres e canzones.
Su max famosi ovres esset [[Die Dreigroschenoper]] con [[Bertolt Brecht]] (1928), ''Aufstieg und Fall der Stadt Mahagonny'' (1930) e ''Die sieben Todsünden'' (1933).
{{DEFAULTSORT: Weill, Kurt}}
[[Categorie: Compositores]]
[[Categorie: Musica]]
5iz6b1i2fbrda1kpmswva4opndsar5p
Walter Piston
0
19530
167652
158156
2026-04-25T20:45:36Z
Dorlota
13847
167652
wikitext
text/x-wiki
{{Biografie
|nómine = Walter Piston
|foto =
|land = {{USA}}
|nascentie =20-im de januar 1894
|nasc_loc = Rockland, Maine
|morte = 12-im de novembre 1976
|mort_loc = Belmond, Massachusetts
|ocupation = Compositor
}}
'''Walter Hamor Piston Jr.''' esset un compositor de musica classical de [[USA]]. Il nascet li 20-im de januar 1894 in [[Rockland (Maine)]] e morit li 12-im de novembre 1976 in [[Belmond (Massachusetts)]]. Su musica es egardat quam ligament inter [[Romantica (arte)|romantica]] e [[impressionisme]].
Walter Piston laborat violinst e pianist in diversi capelles. Il studiat musica al [[Universitá de Harvard]]. Inter 1924 e 1926 il habitat in [[Paris]] e visitat [[Italia]]. Quande il retornat a [[USA]] in li annu 1926, il comensat docer musica al [[Universitá de Harvard]] til su tirament in li annu 1960.
Walter Piston esset maritat con li actoressa Kathryn Nason.
==Ovres==
Li max famosi ovres de Walter Piston es li [[ballette]] ''The Incredibil Flutist'' (Li Flutist Incredibil) e su simfonies.
{{DEFAULTSORT: Piston, Walter}}
[[Categorie: Compositores]]
[[Categorie: Musica]]
g10v02wykavbvd74oibpy3dil88q8bs
Richard Wagner
0
19711
167659
159271
2026-04-25T20:47:25Z
Dorlota
13847
167659
wikitext
text/x-wiki
{{Biografie
|nómine = Richard Wagner
|foto = Richard Wagner by Stieler.jpg
|land = {{GER}}
|nascentie = 22-im de may 1813
|nasc_loc = Leipzig, Germania
|morte = 13-im de februar 1883
|mort_loc = Venezia, Italia
|ocupation = Musico, Compositor, Autor
}}
'''Richard Wagner''' esset un famosi [[Germania|german]] compositor, autor e dirigente de classic [[musica]] in li epoca de [[romantica]]. Il nascet ye li 22-im de may 1813 in [[Leipzig]] e morit li 13-im de februar 1883 in [[Venezia]] ([[Italia]]).
Richard Wagner studiat [[musica]] in [[Leipzig]]. Il devenit famosi pro su [[óperas]] e dramas musical. Richard Wagner habitat inter 1842 e 1849 in [[Dresden]], inter 1849 e 1858 in [[Zúrich]] ([[Svissia]]), inter 1866 e 1871 in [[Triebschen]] ([[Svissia]]) e inter 1872 til 1881 in [[Bayreuth]].
Richard Wagner esset maritat inter 1836 e 1866 con [[Minna Wagner]].
==Ovre==
Li max famosi ovres de Richard Wagner es li óperas [[Der Freischütz]] (1821), [[Li Volant Holandano]] (1843), [[Tannhäuser]] (1845), [[Tristan e Isolde]] (1865), [[Die Meistersinger von Nürnberg]] (1868), [[Der Ring des Nibelungen]] (1869) e [[Parsifal]] (1882).
{{DEFAULTSORT: Wagner, Richard}}
[[Categorie: Germania]]
[[Categorie: Compositores]]
[[Categorie: Musica]]
l0a8do04hjiey634pbknje4aw18mem3
Antonín Dvořák
0
19713
167643
159282
2026-04-25T20:43:00Z
Dorlota
13847
167643
wikitext
text/x-wiki
{{Biografie
|nómine = Antonín Dvořák
|foto = Dvorak.jpg
|land = {{CZE}}
|nascentie = 8-im de septembre 1841
|nasc_loc = Nelahozeves
|morte = 1-im de may 1904
|mort_loc = Praha
|ocupation = Musico, Composito
}}
'''Antonín Dvořák''' esset un [[Tchekia|tchek]] compositor de musico in li epoca del romantica . Il nascet li 8-im de septembre 1841 in Nelahovezes e morit li 1-im de may 1904 in [[Praha]].
Antonín Dvořák aprendet luder [[organ]] e [[bassviolin]] e laborat quam professional musico. In li annu 1870 Antonín Dvořák scrit su unesim [[ópera]] ''Alfred'', quel ne esset publicat durant su vive. In li annu 1875 Antonín Dvořák recivet un stipendie del guvernament de [[Austria]].
Inter 1892 e 1895 Antonín Dvořák habitat e laborat in [[USA]].
Antonín Dvořák esset maritat in li annu 1873 [[Anna Čermáková]] e li cuple havet nin infantes.
==Ovre==
Antonín Dvořák composit nin sinfonies, mult ovres por orchestres, [[ópera]]s, cámera-musica e pezzes musical por [[piano]] e [[organ]]. Antonín Dvořák combinat in su ovre elementes del classica e romantica con elementes del popul-musica e folklore. Inter su max famosi ovres es li [[ópera]] [[Rusalka]] e li deci-six slavic dansas.
{{DEFAULTSORT: Dvořák, Antonín}}
[[Categorie: Compositores]]
[[Categorie: Musica]]
oqq0jv7r7wr1zwewrdcfh9bcjeh4sar
Alban Berg
0
19738
167640
163065
2026-04-25T20:41:59Z
Dorlota
13847
167640
wikitext
text/x-wiki
{{Biografie
|nómine = Alban Berg
|foto = Arnold Schönberg Alban Berg 1910.jpg
|land = {{AUT}}
|nascentie = 9-im de februar 1885
|nasc_loc = Vienna, Austria
|morte = 24-im de decembre 1935
|mort_loc = Vienna, Austria
|ocupation = Musico, Compositor
}}
'''Alban Berg''' esset un compositor de [[Austria]]. Il nascet li 9-im de februar 1885 in [[Vienna]] e morit li 24-im de decembre 1935 anc in [[Vienna]].
{{DEFAULTSORT: Berg, Alban}}
[[Categorie:Austrianes]]
[[Categorie:Compositores]]
mnxuxkacewmfg6tpzizuqnin94xul0d
Georg Philipp Telemann
0
20042
167657
161248
2026-04-25T20:46:50Z
Dorlota
13847
167657
wikitext
text/x-wiki
{{Biografie
|nómine = Georg Philipp Telemann
|foto = Telemann.jpg
|land = {{GER}}
|nascentie = 14-im de marte 1681
|nasc_loc = Magdeburg
|morte = 25-im de junio 1767
|mort_loc = Hamburg
|ocupation = Compositor
}}
'''Georg Philipp Telemann''' esset [[Germania|german]] compositor de classic [[musica]] in li epoca de [[baroc]]. Il nascet ye li 14-im de marte 1681 in [[Magdeburg]] e morit li 25-im de junio 1767 in [[Hamburg]].
Georg Philipp Telemann aprendet far musica self. Desde li annu 1697 il adultijat in [[Hildesheim]]. Il studiat [[jurisprudentie]] in [[Leipzig]] e ta il fundat un [[orchestre]]. Telemann directet óperas ta devenit director de musica in li eclesie del universitá in [[Leipzig]].
Georg Philipp Telemann laborat in [[Sorau]] e [[Eisenach]] por curt témpor e esset inter 1712 e 1721 director de musica del cité [[Frankfurt]] e capellmastro de du eclesies. In li annu 1721 Georg Philipp Telemann devenit director de musica del cité [[Hamburg]]. Il anc directet li ópere-dom in [[Hamburg]].
Georg Philipp Telemann creat plu quam 3000 compositiones.
{{DEFAULTSORT: Telemann, Georg Philipp}}
[[Categorie: Germania]]
[[Categorie: Compositores]]
[[Categorie: Musica]]
6h2yra85an39xcw24zzomn074hck11u
Pyotr Ilyich Tchaikovski
0
20517
167656
164983
2026-04-25T20:46:36Z
Dorlota
13847
167656
wikitext
text/x-wiki
{{Biografie
|nómine = Pyotr Ilyich Tchaikovski
|foto = Tchaikovsky 1868.jpg
|land = {{RUS}}
|nascentie = 7-im de may 1840
|nasc_loc = Votkinsk
|morte = 6-im de novembre 1893
|mort_loc = [[Sant Petersburg]]
|ocupation = Musico, Compositor
}}
'''Pyotr Ilyich Tchaikovski''' ([[russ]]: Пётр Ильи́ч Чайко́вский ) esset un [[Russia|russ]] compositor de classic [[musica]] in li 19-im secul. Il nascet li 7-im de may 1840 in [[Votkinsk]] e morit li 6-im de novembre 1893 in [[Sant Petersburg]]). Tchaikovski es egardat max important compositor de [[Russia]] in li 19-im secul e quam important representante del [[romantica]].
Pyotr Tchaikovsi studiat in [[Sant Petersburg]] musica e in li annu 1866 il translocat a [[Moscva]] por continuar su studies. Pyotr Tchaikovski esset homosexual, ma celat su homosexualitá.
==Ovre==
Pyotr Tchaikovski composit li musica por li tri max important ovres de [[ballette]]: [[Li Lago del Cignes]], [[Li Nuce-Cracattor]] e [[Li Dormant Bellitá (Ballette)|Li Dormant Bellitá]]. Anc su [[ópera]] [[Eugen Onedin (Ópera)|Eugen Onedin]] es tre famosi.
Su sinfonies ''Concert de violines'', su ''Unesim Concert de Piano'' e su ''Overtura 1812'' anc devenit famosi.
{{DEFAULTSORT: Tchaikovski, Pyotr Ilyich}}
[[Categorie:Russes]]
[[Categorie:Compositores]]
6m0d3sv0pkosr1ta1aboecvvcxvknnb
Sergei Prokofiev
0
20577
167653
165256
2026-04-25T20:45:53Z
Dorlota
13847
167653
wikitext
text/x-wiki
{{Biografie
|nómine = Sergei Prokofiev
|foto = Sergei Prokofiev 02.jpg
|land = {{RUS}}
|nascentie = 23-im de april 1891
|nasc_loc = Sontsivka
|morte = 5-im de marte 1953
|mort_loc = [[Moscva]]
|ocupation = Musico, Compositor
}}
'''Sergei Sergeyevich Prokofiev''' ([[russ]]: Сергей Сергеевич Прокофьев) esset un famosi [[Russia|russ]] compositor de classic [[musica]], pianist e dirigente in li 20-im secul. Il nascet li 23-im de april 1891 in li village [[Sontsivka]] (hodie: [[Ukraina]] e morit li 5-im de marte 1953 in [[Moscva]]).
Sergei Prokofiev comensat studiar musica ja in li etá de 13 annus al conservatorium in [[Sant Petersburg]]. Pro li [[Revolution del Octobre]] il forlassat [[Russia]] e translocat al [[Unit States de America]] e in li annu 1920 a [[Francia]]. Sergei Prokofiev retornat in li annu 1936 al [[Soviet-Union]].
Sergei Prokofiev esset maritat con li [[Hispania|hispan]] cantatora [[Carolina Codina]] inter 1921 e 1941 e inter 1948 til su morte in li annu 1953 con [[Mira Mendelson]]. Sergei Prokofiev havet du infantes.
==Ovre==
Sergei Prokofiev scrit [[ópera]]s, [[ballette]]s, [[sinfonie]]s, [[piano]]-concertes e ovres de [[musica de camera]].
Su musica-fabul ''Peter e li Lupo'' es un del max ludet pezzes de musica in li 20-im secul. Anc su [[ballette]] [[Romeo e Julia (Ballette)|Romeao e Julia]] es tre famosi.
{{DEFAULTSORT: Prokofiev, Sergei}}
[[Categorie:Russes]]
[[Categorie:Compositores]]
3nclwu9w7b85rq4l1dwwal6xnxntxtf
Jean Sibelius
0
20593
167645
165346
2026-04-25T20:43:50Z
Dorlota
13847
167645
wikitext
text/x-wiki
{{Biografie
|nómine = Jean Sibelius
|foto = Digitoitu_alkuper%C3%A4isest%C3%A4_negatiivista._(d2005_167_6_5)_Suomen_valokuvataiteen_museo.jpg
|land = {{FIN}}
|nascentie = 8-im de decembre 1865
|nasc_loc = Hämeenlinna
|morte = 20-im de septembre 1957
|mort_loc = Järvenpää
|ocupation = Compositor
}}
'''Johann Julius Christian Sibelius''' esset un compositor de [[Finland]]. Il nascet ye li 8-im de decembre 1865 in [[Hämeenlinna]] e morit ye li 20-im de septembre 1957 in [[Järvenpää]] apu [[Helsinki]].
Jean Sibelius es li max famosi compositor de [[Finland]] e su ovre es in li stil de tard [[romantica]] al transition ver li stil de moderne.
Jean Sibelius origina de un [[sved]] parlant nobil familie in [[Finland]]. Il studiat [[jurisprudentie]] e musica in [[Helsinki]]. Jean Sibelius continuat studiar [[musica]] in [[Berlin]] e [[Vienna]].
Jean Sibelius esset desde li annu 1892 maritat con [[Aino Sibelius]] e li cuple havet six filias.
==Ovre==
Li max important ovres de Jean Sibelius es su sett simfonies. Su musica es ligat con li national identitá de [[Finland]].
{{DEFAULTSORT: Sibelius, Jean}}
[[Categorie: Finland]]
[[Categorie: Compositores]]
4qfzjg96on789maut6ixx0een0n5hai
Toivo Kuula
0
20610
167646
165426
2026-04-25T20:44:03Z
Dorlota
13847
167646
wikitext
text/x-wiki
{{Biografie
|nómine = Toivo Kuula
|foto = KuulaT.jpg
|land = {{FIN}}
|nascentie = 7-im de julí 1883
|nasc_loc = Alavus, Vaasa, Finland
|morte = 18-im de may 1918
|mort_loc = Vyborg
|ocupation = Compositor, Conductor
}}
'''Toivo Timoteus Kuula''' es un compositor e conductor de [[Finland]]. Il nascet ye li 7-im de julí 1883 in [[Alavus]] apu [[Vaasa]] in [[Finland]] e morit ye li 18-im de may 1918 in [[Vyborg]] (hodie: [[Russia]]).
Toivo Kuula studiat teorie de [[musica]], [[violine]] e plu tard composition de musica inter altris che [[Jean Sibelius]] in [[Helsinki]]. Toivo Kuula laborat anc in [[Bologna]], [[Leipzig]] e [[Paris]].
Toivo Kuula maritat in li annu 1914 li cantatora [[Alma Silventoinen]] e li cuple havet un filia.
Toivo Kuula esset mortat per un soldate pro un conflicte. Il morit ye li 18-im de may 1918 in [[Vyborg]].
==Ovre==
Li ovre de Toivo Kuula es in li stil del tard [[romantica]] e tost modernisme. Su ovre combinat [[Finland|finlandes]] traditiones con li [[Francia|frances]] [[impressionisme]]. Toivo Kuula creat mult ovres por orchestre e voce.
{{DEFAULTSORT: Kuulu, Toivo}}
[[Categorie: Finland]]
[[Categorie: Compositores]]
tdsgysz5vmv1hvh7bc5wb4p9kxnlr79
Carl Orff
0
20731
167651
166127
2026-04-25T20:45:20Z
Dorlota
13847
167651
wikitext
text/x-wiki
{{Biografie
|nómine = Carl Orff
|foto = Carl Orff profile view.jpg
|land = {{GER}}
|nascentie = 10-im de julí 1895
|nasc_loc = München, Germania
|morte = 29-im de marte 1982
|mort_loc = München, Germania
|ocupation = Compositor, Musica-instructor
}}
'''Carl Heinrich Maria Orff ''' esset un compositor e musica-instructor de [[Germania]]. Il nascet ye li 10-im de julí 1895 in [[München]] e morit ye li 29-im de marte 1982 in [[München]].
Li max famosi ovre de Carl Orff es li scenic cantate [[Carmina Burana]], quel apartene al max populari ovres por cores del 20-im secul.
Carl Orff studiat musica in [[München]]. Il publicat musical versiones de famosi poemas de [[Heinrich Heine]], [[Friedrich Hölderlin]], [[Ludwig Uhland]] e de altri famosi german autores e anc del ovres del [[Filosofie|filosof]] [[Friedrich Nietzsche]].
Carl Orff esset tre activ in li pedagogica de musica. Su idé esset que on deve developar li sentiment por musica ex li movementes del córpor in combination con gimnastica. Li doctrines de Carl Orff por li musica-education porta li nómine [[Schulwerk]]. Su idés have un grand influentie al musical education del infantes. Carf Orff directet diversi musical-pedagogical institutiones in [[Germania]] e [[Austria]].
Carl Orff esset quar vezes maritat e havet un filia.
==Ligamentes extern==
* [https://co-mu.de/carl-orff Informationes pri Carl Orff del Muséo de Carl Orff]
{{DEFAULTSORT:Orff, Carl}}
[[Categorie:Germania]]
[[Categorie:Compositores]]
nv5bqb9326r7i66eed5gwafrqbewii8
Cosmoglotta Comunité
0
20844
167615
167609
2026-04-25T16:57:43Z
Ellenor2000
20768
Modification con conflictes de interesse. Que it usa solmen «occidental» es fals: li comunité circum Cmgt-C usa «occidental» con prominentie ma ne solmen. In plus, por Wikipedia, Discord ne es un font fidibil, e pro to ne es acceptabil usar it por suportar l'idé que Occidental Language vole changes in li form de Interlingue.
167615
wikitext
text/x-wiki
{{Unesim}}
'''''Cosmoglotta Comunité''''' es un revúe in [[Interlingue]] qui comensat esser publicat in 2025 ex un gruppe de occidentalistes circum [[David MacLeod]]<ref>''Nov Iniciative'', in ''[https://archive.org/details/cg-336-2025-2/mode/2up Cosmoglotta 336]''</ref>. Li unesim numeró havet 16 págines.
==Critica==
Cosmoglotta Comunité esset criticat por usar prominentmen li ancian nómine del lingue Occidental. It anc ne es scrit totmen in [[Interlingue]], ma permisse un ''gast-lingue'' presenta se. In li unesim numeró de Cosmoglotta Comunité it esset [[Sambahsa]]<ref>Vide Cosmoglotta Comunité 1, p. 10-11.</ref>. To esset fortmen criticat de Interlinguistes quam [[Dorlota Burdon]] e [[Thomas Schmidt (Interlingueist)|Thomas Schmidt]] <ref> Por li critica de Thomas Schmidt in li Google-Group Interlingue-Occidental vide https://groups.google.com/g/interlingue-occidental/c/Q5vnMUVl7KA</ref>. Cosmoglotta Comunité anc ne permisse li publication de litterari textus e {{fonte manca|resta proxim al poliglott [[filosofie]] gruppe ''Occidental'' che li social-retage [[Discord]], quel anc vole changeamentes in li actual form de lingue|date=april 2026}} <ref>Li chef-redactor de Cosmoglotte Comunité Leo Stief proposit changear e complicar li Regul de De Wahl in su articul ''Un regul alternativ por li derivation'', vide Cosmoglotta 335 (2025), págine 2.</ref>.
== Referenties ==
<references/>
== Ligamentes extern ==
* [https://occidental-lang.com/resources/Cosmoglotta_Comunite_1.pdf Numeró 1]
{{Interlingue}}
[[Categorie:Jurnales e revúes in Interlingue]]
5w662w3iu5y4lui4vkffgt9etofs4i4
167617
167615
2026-04-25T17:02:39Z
Ellenor2000
20768
l'idé que on vole changes es suportat per li dat citation (Cosmoglotta 335 pg. 2)
167617
wikitext
text/x-wiki
{{Unesim}}
'''''Cosmoglotta Comunité''''' es un revúe in [[Interlingue]] qui comensat esser publicat in 2025 ex un gruppe de occidentalistes circum [[David MacLeod]]<ref>''Nov Iniciative'', in ''[https://archive.org/details/cg-336-2025-2/mode/2up Cosmoglotta 336]''</ref>. Li unesim numeró havet 16 págines.
==Critica==
Cosmoglotta Comunité esset criticat por usar prominentmen li ancian nómine del lingue Occidental. It anc ne es scrit totmen in [[Interlingue]], ma permisse un ''gast-lingue'' presenta se. In li unesim numeró de Cosmoglotta Comunité it esset [[Sambahsa]]<ref>Vide Cosmoglotta Comunité 1, p. 10-11.</ref>. To esset fortmen criticat de Interlinguistes quam [[Dorlota Burdon]] e [[Thomas Schmidt (Interlingueist)|Thomas Schmidt]] <ref> Por li critica de Thomas Schmidt in li Google-Group Interlingue-Occidental vide https://groups.google.com/g/interlingue-occidental/c/Q5vnMUVl7KA</ref>. Cosmoglotta Comunité anc ne permisse li publication de litterari textus e {{fonte manca|resta proxim al poliglott [[filosofie]] gruppe ''Occidental'' che li social-retage [[Discord]]|date=april 2026}}, quel anc vole changeamentes in li actual form de lingue <ref>Li chef-redactor de Cosmoglotte Comunité Leo Stief proposit changear e complicar li Regul de De Wahl in su articul ''Un regul alternativ por li derivation'', vide Cosmoglotta 335 (2025), págine 2.</ref>.
== Referenties ==
<references/>
== Ligamentes extern ==
* [https://occidental-lang.com/resources/Cosmoglotta_Comunite_1.pdf Numeró 1]
{{Interlingue}}
[[Categorie:Jurnales e revúes in Interlingue]]
ax94locpeo5v90nnw8ssni7xrqhnqc9
Categorie:Articules con assertiones sin fontes desde april 2026
14
20957
167616
2026-04-25T16:58:44Z
Ellenor2000
20768
Crea li categorie
167616
wikitext
text/x-wiki
Un categorie quam ti-ci posse esser vacui. Administratores e sysops, ples ne deler it. ''A category like this one can be empty. Administrators and sysops, please don't delete it.''
[[Categorie:Articules con assertiones sin fontes]]
lqrmt0nebr2yih2wju6acibg902mc39
Avise:Booland
10
20958
167618
2026-04-25T18:16:50Z
Ellenor2000
20768
Copiar li fonte de https://en.wikipedia.org/wiki/Template:Both
167618
wikitext
text/x-wiki
{{SAFESUBST:<noinclude />#if:{{{1|}}}|{{SAFESUBST:<noinclude />#if:{{{2|}}}|1}}}}<noinclude>
{{documentation}}
</noinclude>
a92g9dgn74wuyygsul02g6cnq29em4t
Avise Discussion:Booland
11
20959
167619
2026-04-25T18:18:52Z
Ellenor2000
20768
jures de autor
167619
wikitext
text/x-wiki
== Jures de autor ==
Yo ha copiat li fonte del modelle chel Wikipedia anglés, [[en:Template:Both|Template:Both]], secun li licentie CC-by-sa 4.0 e GFDL. Su redactores have li jures de autor in ti ci modelle. [[Usator:Ellenor2000|Ellenor2000]] ([[Usator Discussion:Ellenor2000|discussion]]) 18:18, 25 april 2026 (UTC)
0d1w97kwr7r5923a59ak6do7iaem5bn
Pasta de dentes
0
20960
167620
2026-04-25T18:19:28Z
Ellenor2000
20768
Gérmine de un article pri pasta de dentes.
167620
wikitext
text/x-wiki
Li pasta de dentes es un pasta que on usa por nettar li dentes. It sovente contene fluoride de natrium o altri combinationes con fluorin, in quantitás tro micri por causar toxicitá, queles fa plus resilient li dentes e prevenir cavitás.<ref name="Ismail_2008">{{cite journal |vauthors=Ismail AI, Hasson H |title=Fluoride supplements, dental caries and fluorosis: a systematic review |journal=Journal of the American Dental Association |volume=139 |issue=11 |pages=1457–68 |date=novembre 2008 |pmid=18978383 |doi=10.14219/jada.archive.2008.0071|doi-access=free }}. DOI: [https://dx.doi.org/10.14219/jada.archive.2008.0071 10.14219/jada.archive.2008.0071]</ref>
== Referenties ==
<references />
22bm68ou704wep8h3wn3xlamkyzg55l
167629
167620
2026-04-25T18:55:28Z
Ellenor2000
20768
usa li experimental modelle Cite journal CS1
167629
wikitext
text/x-wiki
Li pasta de dentes es un pasta que on usa por nettar li dentes. It sovente contene fluoride de natrium o altri combinationes con fluorin, in quantitás tro micri por causar toxicitá, queles fa plus resilient li dentes e prevenir cavitás.<ref name="Ismail_2008">{{cite journal CS1|vauthors=Ismail AI, Hasson H |title=Fluoride supplements, dental caries and fluorosis: a systematic review |journal=Journal of the American Dental Association |volume=139 |issue=11 |pages=1457–68 |date=novembre 2008 |pmid=18978383 |doi=10.14219/jada.archive.2008.0071|doi-access=free }}</ref>
== Referenties ==
<references />
3jtftnw22tsmgpn0nhgfu38802z78rv
167630
167629
2026-04-25T19:15:31Z
Ellenor2000
20768
conjunctor errosi
167630
wikitext
text/x-wiki
Li pasta de dentes es un pasta quel on usa por nettar li dentes. It sovente contene fluoride de natrium o altri combinationes con fluorin, in quantitás tro micri por causar toxicitá, queles fa plus resilient li dentes e prevenir cavitás.<ref name="Ismail_2008">{{cite journal CS1|vauthors=Ismail AI, Hasson H |title=Fluoride supplements, dental caries and fluorosis: a systematic review |journal=Journal of the American Dental Association |volume=139 |issue=11 |pages=1457–68 |date=novembre 2008 |pmid=18978383 |doi=10.14219/jada.archive.2008.0071|doi-access=free }}</ref>
== Referenties ==
<references />
btfj9eob8zuhp9wlm5ddcowiqhr55rq
167631
167630
2026-04-25T19:19:48Z
Ellenor2000
20768
prevenir (interferentie de cat.) → preventer
167631
wikitext
text/x-wiki
Li pasta de dentes es un pasta quel on usa por nettar li dentes. It sovente contene fluoride de natrium o altri combinationes con fluorin, in quantitás tro micri por causar toxicitá, queles fa plus resilient li dentes e preventer cavitás.<ref name="Ismail_2008">{{cite journal CS1|vauthors=Ismail AI, Hasson H |title=Fluoride supplements, dental caries and fluorosis: a systematic review |journal=Journal of the American Dental Association |volume=139 |issue=11 |pages=1457–68 |date=novembre 2008 |pmid=18978383 |doi=10.14219/jada.archive.2008.0071|doi-access=free }}</ref>
== Referenties ==
<references />
pbec8l5f6q1ss0cmf85y5yj68pyjwn0
167632
167631
2026-04-25T19:20:06Z
Ellenor2000
20768
errós témpor verbal
167632
wikitext
text/x-wiki
Li pasta de dentes es un pasta quel on usa por nettar li dentes. It sovente contene fluoride de natrium o altri combinationes con fluorin, in quantitás tro micri por causar toxicitá, queles fa plus resilient li dentes e prevente cavitás.<ref name="Ismail_2008">{{cite journal CS1|vauthors=Ismail AI, Hasson H |title=Fluoride supplements, dental caries and fluorosis: a systematic review |journal=Journal of the American Dental Association |volume=139 |issue=11 |pages=1457–68 |date=novembre 2008 |pmid=18978383 |doi=10.14219/jada.archive.2008.0071|doi-access=free }}</ref>
== Referenties ==
<references />
93wsrzvw6o52fexwoggejvz2ftlng5x
167669
167632
2026-04-26T09:30:50Z
Dorlota
13847
167669
wikitext
text/x-wiki
[[File:Toothpaste.jpg|280px|thumb|right|Pasta de dentes]]
'''Pasta de dentes''' es un pasta, quel on usa por nettar li dentes. It sovente contene fluoride de natrium o altri combinationes con fluorin, in quantitás tro micri por causar toxicitá, queles fa plus resilient li dentes e prevente cavitás.<ref name="Ismail_2008">{{cite journal CS1|vauthors=Ismail AI, Hasson H |title=Fluoride supplements, dental caries and fluorosis: a systematic review |journal=Journal of the American Dental Association |volume=139 |issue=11 |pages=1457–68 |date=novembre 2008 |pmid=18978383 |doi=10.14219/jada.archive.2008.0071|doi-access=free }}</ref>
== Referenties ==
<references />
[[Categorie: Higiene]]
ht4ytw8kgcvwkn2xd6fakrb39yamwtl
Avise:Cite journal CS1
10
20961
167621
2026-04-25T18:25:12Z
Ellenor2000
20768
Copiat de https://en.wikipedia.org/w/index.php?title=Template:Cite_journal . Fórsan it es un error usar un semblant modelle, pro to yo no ha surscrit Cite_journal.
167621
wikitext
text/x-wiki
<includeonly>{{#invoke:Citation/CS1|citation
|CitationClass=journal
}}</includeonly><noinclude>
{{documentation}}</noinclude>
d00msvjtg9qgnpqky9imd57sjmvwoqo
Module:Citation/CS1/Utilities
828
20962
167622
2026-04-25T18:28:00Z
Ellenor2000
20768
Code copiat de https://en.wikipedia.org/w/index.php?title=Module:Citation/CS1/Utilities&action=edit
167622
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;', {['–'] = '–', ['—'] = '—'}); -- replace — and – entities with their characters; semicolon mucks up the text.split
str = str:gsub ('-', '-'); -- replace HTML numeric entity with hyphen character
str = str:gsub (' ', ' '); -- replace 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
Module:Citation/CS1/Identifiers
828
20963
167624
2026-04-25T18:34:43Z
Ellenor2000
20768
copiat de https://en.wikipedia.org/wiki/Module:Citation/CS1/Identifiers
167624
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 ' ',
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 ' ', -- 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
Module:Citation/CS1/COinS
828
20964
167625
2026-04-25T18:35:19Z
Ellenor2000
20768
copiat de https://en.wikipedia.org/w/index.php?title=Module:Citation/CS1/COinS&action=edit
167625
Scribunto
text/plain
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local has_accept_as_written, is_set, in_array, remove_wiki_link, strip_apostrophe_markup; -- functions in Module:Citation/CS1/Utilities
local cfg; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
--[[--------------------------< M A K E _ C O I N S _ T I T L E >----------------------------------------------
Makes a title for COinS from Title and / or ScriptTitle (or any other name-script pairs)
Apostrophe markup (bold, italics) is stripped from each value so that the COinS metadata isn't corrupted with strings
of %27%27...
]]
local function make_coins_title (title, script)
title = has_accept_as_written (title);
if is_set (title) then
title = strip_apostrophe_markup (title); -- strip any apostrophe markup
else
title = ''; -- if not set, make sure title is an empty string
end
if is_set (script) then
script = script:gsub ('^%l%l%s*:%s*', ''); -- remove language prefix if present (script value may now be empty string)
script = strip_apostrophe_markup (script); -- strip any apostrophe markup
else
script = ''; -- if not set, make sure script is an empty string
end
if is_set (title) and is_set (script) then
script = ' ' .. script; -- add a space before we concatenate
end
return title .. script; -- return the concatenation
end
--[[--------------------------< E S C A P E _ L U A _ M A G I C _ C H A R S >----------------------------------
Returns a string where all of Lua's magic characters have been escaped. This is important because functions like
string.gsub() treat their pattern and replace strings as patterns, not literal strings.
]]
local function escape_lua_magic_chars (argument)
argument = argument:gsub("%%", "%%%%"); -- replace % with %%
argument = argument:gsub("([%^%$%(%)%.%[%]%*%+%-%?])", "%%%1"); -- replace all other Lua magic pattern characters
return argument;
end
--[[--------------------------< G E T _ C O I N S _ P A G E S >------------------------------------------------
Extract page numbers from external wikilinks in any of the |page=, |pages=, or |at= parameters for use in COinS.
]]
local function get_coins_pages (pages)
local pattern;
if not is_set (pages) then return pages; end -- if no page numbers then we're done
while true do
pattern = pages:match("%[(%w*:?//[^ ]+%s+)[%w%d].*%]"); -- pattern is the opening bracket, the URL and following space(s): "[url "
if nil == pattern then break; end -- no more URLs
pattern = escape_lua_magic_chars (pattern); -- pattern is not a literal string; escape Lua's magic pattern characters
pages = pages:gsub(pattern, ""); -- remove as many instances of pattern as possible
end
pages = pages:gsub("[%[%]]", ""); -- remove the brackets
pages = pages:gsub("–", "-" ); -- replace endashes with hyphens
pages = pages:gsub("&%w+;", "-" ); -- and replace HTML entities (– etc.) with hyphens; do we need to replace numerical entities like   and the like?
pages = pages:gsub ('%b<>', ''); -- remove html-like tags; spans are added to <Pages> by utilities.hyphen_to_dash() which should not appear in COinS metadata
return pages;
end
--[=[-------------------------< C O I N S _ R E P L A C E _ M A T H _ S T R I P M A R K E R >------------------
There are three options for math markup rendering that depend on the editor's math preference settings. These
settings are at [[Special:Preferences#mw-prefsection-rendering]] and are
PNG images
TeX source
MathML with SVG or PNG fallback
All three are heavy with HTML and CSS which doesn't belong in the metadata.
Without this function, the metadata saved in the raw wikitext contained the rendering determined by the settings
of the last editor to save the page.
This function gets the rendered form of an equation according to the editor's preference before the page is saved. It
then searches the rendering for the text equivalent of the rendered equation and replaces the rendering with that so
that the page is saved without extraneous HTML/CSS markup and with a reasonably readable text form of the equation.
When a replacement is made, this function returns true and the value with replacement; otherwise false and the initial
value. To replace multipe equations it is necessary to call this function from within a loop.
]=]
local function coins_replace_math_stripmarker (value)
local stripmarker = cfg.stripmarkers['math'];
local rendering = value:match (stripmarker); -- is there a math stripmarker
if not rendering then -- when value doesn't have a math stripmarker, abandon this test
return false, value;
end
rendering = mw.text.unstripNoWiki (rendering); -- convert stripmarker into rendered value (or nil? ''? when math render error)
if rendering:match ('alt="[^"]+"') then -- if PNG math option
rendering = rendering:match ('alt="([^"]+)"'); -- extract just the math text
elseif rendering:match ('$%s+.+%s+%$') then -- if TeX math option; $ is legit character that is escapes as \$
rendering = rendering:match ('$%s+(.+)%s+%$') -- extract just the math text
elseif rendering:match ('<annotation[^>]+>.+</annotation>') then -- if MathML math option
rendering = rendering:match ('<annotation[^>]+>(.+)</annotation>') -- extract just the math text
else
return false, value; -- had math stripmarker but not one of the three defined forms
end
return true, value:gsub (stripmarker, rendering, 1);
end
--[[--------------------------< C O I N S _ C L E A N U P >----------------------------------------------------
Cleanup parameter values for the metadata by removing or replacing invisible characters and certain HTML entities.
2015-12-10: there is a bug in mw.text.unstripNoWiki (). It replaces math stripmarkers with the appropriate content
when it shouldn't. See https://phabricator.wikimedia.org/T121085 and Wikipedia_talk:Lua#stripmarkers_and_mw.text.unstripNoWiki.28.29
TODO: move the replacement patterns and replacement values into a table in /Configuration similar to the invisible
characters table?
]]
local function coins_cleanup (value)
local replaced = true; -- default state to get the do loop running
while replaced do -- loop until all math stripmarkers replaced
replaced, value = coins_replace_math_stripmarker (value); -- replace math stripmarker with text representation of the equation
end
value = value:gsub (cfg.stripmarkers['math'], "MATH RENDER ERROR"); -- one or more couldn't be replaced; insert vague error message
value = mw.text.unstripNoWiki (value); -- replace nowiki stripmarkers with their content
value = value:gsub ('<span class="nowrap" style="padding%-left:0%.1em;">'(s?)</span>', "'%1"); -- replace {{'}} or {{'s}} with simple apostrophe or apostrophe-s
value = value:gsub (' ', ' '); -- replace entity with plain space
value = value:gsub ('\226\128\138', ' '); -- replace hair space with plain space
if not mw.ustring.find (value, cfg.indic_script) then -- don't remove zero-width joiner characters from indic script
value = value:gsub ('‍', ''); -- remove ‍ entities
value = mw.ustring.gsub (value, '[\226\128\141\226\128\139\194\173]', ''); -- remove zero-width joiner, zero-width space, soft hyphen
end
value = value:gsub ('[\009\010\013 ]+', ' '); -- replace horizontal tab, line feed, carriage return with plain space
return value;
end
--[[--------------------------< C O I N S >--------------------------------------------------------------------
COinS metadata (see <http://ocoins.info/>) allows automated tools to parse the citation information.
]]
local function COinS(data, class)
if 'table' ~= type(data) or nil == next(data) then
return '';
end
for k, v in pairs (data) do -- spin through all of the metadata parameter values
if 'ID_list' ~= k and 'Authors' ~= k then -- except the ID_list and Author tables (author nowiki stripmarker done when Author table processed)
data[k] = coins_cleanup (v);
end
end
local ctx_ver = "Z39.88-2004";
-- treat table strictly as an array with only set values.
local OCinSoutput = setmetatable( {}, {
__newindex = function(self, key, value)
if is_set(value) then
rawset( self, #self+1, table.concat{ key, '=', mw.uri.encode( remove_wiki_link( value ) ) } );
end
end
});
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn', 'journal', 'news', 'magazine'}) or
(in_array (class, {'conference', 'interview', 'map', 'press release', 'web'}) and is_set(data.Periodical)) or
('citation' == class and is_set(data.Periodical) and not is_set (data.Encyclopedia)) then
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal"; -- journal metadata identifier
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) then -- set genre according to the type of citation template we are rendering
OCinSoutput["rft.genre"] = "preprint"; -- cite arxiv, cite biorxiv, cite citeseerx, cite medrxiv, cite ssrn
elseif 'conference' == class then
OCinSoutput["rft.genre"] = "conference"; -- cite conference (when Periodical set)
elseif 'web' == class then
OCinSoutput["rft.genre"] = "unknown"; -- cite web (when Periodical set)
else
OCinSoutput["rft.genre"] = "article"; -- journal and other 'periodical' articles
end
OCinSoutput["rft.jtitle"] = data.Periodical; -- journal only
OCinSoutput["rft.atitle"] = data.Title; -- 'periodical' article titles
-- these used only for periodicals
OCinSoutput["rft.ssn"] = data.Season; -- keywords: winter, spring, summer, fall
OCinSoutput["rft.quarter"] = data.Quarter; -- single digits 1->first quarter, etc.
OCinSoutput["rft.chron"] = data.Chron; -- free-form date components
OCinSoutput["rft.volume"] = data.Volume; -- does not apply to books
OCinSoutput["rft.issue"] = data.Issue;
OCinSoutput['rft.artnum'] = data.ArticleNumber; -- {{cite journal}} only
OCinSoutput["rft.pages"] = data.Pages; -- also used in book metadata
elseif 'thesis' ~= class then -- all others except cite thesis are treated as 'book' metadata; genre distinguishes
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"; -- book metadata identifier
if 'report' == class or 'techreport' == class then -- cite report and cite techreport
OCinSoutput["rft.genre"] = "report";
elseif 'conference' == class then -- cite conference when Periodical not set
OCinSoutput["rft.genre"] = "conference";
OCinSoutput["rft.atitle"] = data.Chapter; -- conference paper as chapter in proceedings (book)
elseif in_array (class, {'book', 'citation', 'encyclopaedia', 'interview', 'map'}) then
if is_set (data.Chapter) then
OCinSoutput["rft.genre"] = "bookitem";
OCinSoutput["rft.atitle"] = data.Chapter; -- book chapter, encyclopedia article, interview in a book, or map title
else
if 'map' == class or 'interview' == class then
OCinSoutput["rft.genre"] = 'unknown'; -- standalone map or interview
else
OCinSoutput["rft.genre"] = 'book'; -- book and encyclopedia
end
end
else -- {'audio-visual', 'AV-media-notes', 'DVD-notes', 'episode', 'interview', 'mailinglist', 'map', 'newsgroup', 'podcast', 'press release', 'serial', 'sign', 'speech', 'web'}
OCinSoutput["rft.genre"] = "unknown";
end
OCinSoutput["rft.btitle"] = data.Title; -- book only
OCinSoutput["rft.place"] = data.PublicationPlace; -- book only
OCinSoutput["rft.series"] = data.Series; -- book only
OCinSoutput["rft.pages"] = data.Pages; -- book, journal
OCinSoutput["rft.edition"] = data.Edition; -- book only
OCinSoutput["rft.pub"] = data.PublisherName; -- book and dissertation
else -- cite thesis
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:dissertation"; -- dissertation metadata identifier
OCinSoutput["rft.title"] = data.Title; -- dissertation (also patent but that is not yet supported)
OCinSoutput["rft.degree"] = data.Degree; -- dissertation only
OCinSoutput['rft.inst'] = data.PublisherName; -- book and dissertation
end
-- NB. Not currently supported are "info:ofi/fmt:kev:mtx:patent", "info:ofi/fmt:kev:mtx:dc", "info:ofi/fmt:kev:mtx:sch_svc", "info:ofi/fmt:kev:mtx:ctx"
-- and now common parameters (as much as possible)
OCinSoutput["rft.date"] = data.Date; -- book, journal, dissertation
for k, v in pairs( data.ID_list ) do -- what to do about these? For now assume that they are common to all?
if k == 'ISBN' then v = v:gsub( "[^-0-9X]", "" ); end
local id = cfg.id_handlers[k].COinS;
if string.sub( id or "", 1, 4 ) == 'info' then -- for ids that are in the info:registry
OCinSoutput["rft_id"] = table.concat{ id, "/", v };
elseif string.sub (id or "", 1, 3 ) == 'rft' then -- for isbn, issn, eissn, etc. that have defined COinS keywords
OCinSoutput[ id ] = v;
elseif 'url' == id then -- for urls that are assembled in ~/Identifiers; |asin= and |ol=
OCinSoutput["rft_id"] = table.concat ({data.ID_list[k], "#id-name=", cfg.id_handlers[k].label});
elseif id then -- when cfg.id_handlers[k].COinS is not nil so urls created here
OCinSoutput["rft_id"] = table.concat{ cfg.id_handlers[k].prefix, v, cfg.id_handlers[k].suffix or '', "#id-name=", cfg.id_handlers[k].label }; -- others; provide a URL and indicate identifier name as #fragment (human-readable, but transparent to browsers)
end
end
local last, first;
for k, v in ipairs( data.Authors ) do
last, first = coins_cleanup (v.last), coins_cleanup (v.first or ''); -- replace any nowiki stripmarkers, non-printing or invisible characters
if k == 1 then -- for the first author name only
if is_set(last) and is_set(first) then -- set these COinS values if |first= and |last= specify the first author name
OCinSoutput["rft.aulast"] = last; -- book, journal, dissertation
OCinSoutput["rft.aufirst"] = first; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation -- otherwise use this form for the first name
end
else -- for all other authors
if is_set(last) and is_set(first) then
OCinSoutput["rft.au"] = table.concat{ last, ", ", first }; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation
end
-- TODO: At present we do not report "et al.". Add anything special if this condition applies?
end
end
OCinSoutput.rft_id = data.URL;
OCinSoutput.rfr_id = table.concat{ "info:sid/", mw.site.server:match( "[^/]*$" ), ":", data.RawPage };
-- TODO: Add optional extra info:
-- rfr_dat=#REVISION<version> (referrer private data)
-- ctx_id=<data.RawPage>#<ref> (identifier for the context object)
-- ctx_tim=<ts> (timestamp in format yyyy-mm-ddThh:mm:ssTZD or yyyy-mm-dd)
-- ctx_enc=info:ofi/enc:UTF-8 (character encoding)
OCinSoutput = setmetatable( OCinSoutput, nil );
-- sort with version string always first, and combine.
-- table.sort( OCinSoutput );
table.insert( OCinSoutput, 1, "ctx_ver=" .. ctx_ver ); -- such as "Z39.88-2004"
return table.concat(OCinSoutput, "&");
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)
cfg = cfg_table_ptr;
has_accept_as_written = utilities_page_ptr.has_accept_as_written; -- import functions from selected Module:Citation/CS1/Utilities module
is_set = utilities_page_ptr.is_set;
in_array = utilities_page_ptr.in_array;
remove_wiki_link = utilities_page_ptr.remove_wiki_link;
strip_apostrophe_markup = utilities_page_ptr.strip_apostrophe_markup;
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
make_coins_title = make_coins_title,
get_coins_pages = get_coins_pages,
COinS = COinS,
set_selected_modules = set_selected_modules,
}
2eba9cn0u4yseyeujt1vmrglxrgcllo
Module:Citation/CS1/styles.css
828
20965
167628
2026-04-25T18:54:43Z
Ellenor2000
20768
copia de https://en.wikipedia.org/w/index.php?title=Module:Citation/CS1/styles.css&oldid=1333433106&action=edit
167628
sanitized-css
text/css
/* Protection icon
the following line controls the page-protection icon in the upper right corner
it must remain within this comment
{{sandbox other||{{pp-template}}}}
*/
/* Overrides
Some wikis do not override user agent default styles for HTML <cite> and <q>,
unlike en.wp. On en.wp, keep these the same as [[MediaWiki:Common.css]].
The word-wrap and :target styles were moved here from Common.css.
On en.wp, keep these the same as [[Template:Citation/styles.css]].
*/
cite.citation {
font-style: inherit; /* Remove italics for <cite> */
/* Break long urls, etc., rather than overflowing box */
word-wrap: break-word;
}
.citation q {
quotes: '"' '"' "'" "'"; /* Straight quote marks for <q> */
}
/* Highlight linked elements (such as clicked references) in blue */
.citation:target {
/* ignore the linter - all browsers of interest implement this */
background-color: rgba(0, 127, 255, 0.133);
}
/* ID and URL access
Both core and Common.css have selector .mw-parser-output a[href$=".pdf"].external
for PDF pages. All TemplateStyles pages are hoisted to .mw-parser-output. We need
to have specificity equal to a[href$=".pdf"].external for locks to override PDF icon.
That's essentially 2 classes and 1 element.
the .id-lock-... selectors are for use by non-citation templates like
{{Catalog lookup link}}
bg-size `contain` in Minerva and Timeless is too large, so we set a size for them
and then exclude them later
*/
.id-lock-free.id-lock-free a {
background: url(//upload.wikimedia.org/wikipedia/commons/6/65/Lock-green.svg)
right 0.1em center/9px no-repeat;
}
.id-lock-limited.id-lock-limited a,
.id-lock-registration.id-lock-registration a {
background: url(//upload.wikimedia.org/wikipedia/commons/d/d6/Lock-gray-alt-2.svg)
right 0.1em center/9px no-repeat;
}
.id-lock-subscription.id-lock-subscription a {
background: url(//upload.wikimedia.org/wikipedia/commons/a/aa/Lock-red-alt-2.svg)
right 0.1em center/9px no-repeat;
}
/* Wikisource
Wikisource icon when |chapter= or |title= is wikilinked to Wikisource
as in cite wikisource
*/
.cs1-ws-icon a {
background: url(//upload.wikimedia.org/wikipedia/commons/4/4c/Wikisource-logo.svg)
right 0.1em center/12px no-repeat;
}
body:not(.skin-timeless):not(.skin-minerva) .id-lock-free a,
body:not(.skin-timeless):not(.skin-minerva) .id-lock-limited a,
body:not(.skin-timeless):not(.skin-minerva) .id-lock-registration a,
body:not(.skin-timeless):not(.skin-minerva) .id-lock-subscription a,
body:not(.skin-timeless):not(.skin-minerva) .cs1-ws-icon a {
background-size: contain;
/* Common.css has a padding set for PDF URLs. bg-contain expands to the
* size of the padding which makes the icons very large. we "reset" the
* padding here. 1em picked out of a hat based on console having a similar
* rule from elsewhere
*/
padding: 0 1em 0 0;
}
/* Errors and maintenance */
.cs1-code {
/* <code>...</code> style override: mediawiki's css definition is specified here:
https://git.wikimedia.org/blob/mediawiki%2Fcore.git/
69cd73811f7aadd093050dbf20ed70ef0b42a713/skins%2Fcommon%2FcommonElements.css#L199
*/
color: inherit;
background: inherit;
border: none;
padding: inherit;
}
.cs1-hidden-error {
display: none;
color: var(--color-error, #bf3c2c);
}
.cs1-visible-error {
color: var(--color-error, #bf3c2c);
}
.cs1-maint {
display: none;
color: #085;
margin-left: 0.3em;
}
/* kerning */
.cs1-kern-left {
padding-left: 0.2em;
}
.cs1-kern-right {
padding-right: 0.2em;
}
/* selflinks – avoid bold font style when cs1|2 template links to the current page */
.citation .mw-selflink {
font-weight: inherit;
}
@media screen {
/* Small text size
Set small text size in one place. 0.95 (here) * 0.9 (from references list) is
~0.85, which is the lower bound for size for accessibility. Old styling for this
was just 0.85. We could write the rule so that when this template is inside
references/reflist, only then does it multiply by 0.95; else multiply by 0.85 */
.cs1-format {
font-size: 95%;
}
html.skin-theme-clientpref-night .cs1-maint {
color: #18911f;
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .cs1-maint {
color: #18911f;
}
}
2wrho6o1q12cvwhaslan5n9g140q3wl
Giacomo Puccini
0
20966
167635
2026-04-25T20:29:41Z
Dorlota
13847
Creat págine contenente «{{Biografie |nómine = Giacomo Puccini |foto = GiacomoPuccini.jpg |land = {{ITA}} |nascentie = 12-im de decembre 1858 |nasc_loc = Lucca, Italia |morte = 29-im de novembre 1924 |mort_loc = Bruxelles, Belgia |ocupation = Musico, Compositor }} '''Giacomo Antonio Domenico Michele Secondo Maria Puccini''' esset un framos [[Italia|italian]] [[compositor]] del [[ópera]]s. Il nascet li 12-im de decembre 1858 in [[Lucca]] e morit li 29-im de novembre 1924 in Bruxel...»
167635
wikitext
text/x-wiki
{{Biografie
|nómine = Giacomo Puccini
|foto = GiacomoPuccini.jpg
|land = {{ITA}}
|nascentie = 12-im de decembre 1858
|nasc_loc = Lucca, Italia
|morte = 29-im de novembre 1924
|mort_loc = Bruxelles, Belgia
|ocupation = Musico, Compositor
}}
'''Giacomo Antonio Domenico Michele Secondo Maria Puccini''' esset un framos [[Italia|italian]] [[compositor]] del [[ópera]]s.
Il nascet li 12-im de decembre 1858 in [[Lucca]] e morit li 29-im de novembre 1924 in [[Bruxelles]] ([[Belgia]]).
== Famos óperas de Verdi ==
* 1896 La bohème (1896)
* 1900 Tosca
* 1904 Madama Butterfly (1904)
* 1926 Turandot (pos li morte de Puccini finit de [[Franco Alfano]])
{{DEFAULTSORT: Pucccini, Giacomo}}
[[Categorie:Italianes]]
[[Categorie:Compositores]]
pfifi6bqldx3yeb1ect24uhgt2f7ttp
167637
167635
2026-04-25T20:31:15Z
Dorlota
13847
167637
wikitext
text/x-wiki
{{Biografie
|nómine = Giacomo Puccini
|foto = GiacomoPuccini.jpg
|land = {{ITA}}
|nascentie = 12-im de decembre 1858
|nasc_loc = Lucca, Italia
|morte = 29-im de novembre 1924
|mort_loc = Bruxelles, Belgia
|ocupation = Musico, Compositor
}}
'''Giacomo Antonio Domenico Michele Secondo Maria Puccini''' esset un framos [[Italia|italian]] [[compositor]] del [[ópera]]s.
Il nascet li 12-im de decembre 1858 in [[Lucca]] e morit li 29-im de novembre 1924 in [[Bruxelles]] ([[Belgia]]).
== Famosi óperas de Verdi ==
* 1893 Manon Lescaut
* 1896 La bohème
* 1900 Tosca
* 1904 Madama Butterfly
* 1926 Turandot (pos li morte de Puccini finit de [[Franco Alfano]])
{{DEFAULTSORT: Pucccini, Giacomo}}
[[Categorie:Italianes]]
[[Categorie:Compositores]]
4gu6z9jy7sa6rmbsbs7ps3e11hdxq95
167638
167637
2026-04-25T20:40:43Z
Dorlota
13847
167638
wikitext
text/x-wiki
{{Biografie
|nómine = Giacomo Puccini
|foto = GiacomoPuccini.jpg
|land = {{ITA}}
|nascentie = 12-im de decembre 1858
|nasc_loc = Lucca, Italia
|morte = 29-im de novembre 1924
|mort_loc = Bruxelles, Belgia
|ocupation = Musico, Compositor
}}
'''Giacomo Antonio Domenico Michele Secondo Maria Puccini''' esset un framos [[Italia|italian]] [[compositor]] del [[ópera]]s.
Il nascet li 12-im de decembre 1858 in [[Lucca]] e morit li 29-im de novembre 1924 in [[Bruxelles]] ([[Belgia]]).
Giacomo Puccini studiat musica al conservatorium in [[Milano]]. Il anc laborat quam organist. In li annu 1884 Giacomo Puccini creat su unesim ópera ''Le Vili''.
In li annu 1904 Giacomo Puccini maritat Elvira Gemignani e li cuple havet un comun filio.
== Famosi óperas de Verdi ==
* 1893 Manon Lescaut
* 1896 La bohème
* 1900 Tosca
* 1904 Madama Butterfly
* 1926 Turandot (pos li morte de Puccini finit de [[Franco Alfano]])
{{DEFAULTSORT: Pucccini, Giacomo}}
[[Categorie:Italianes]]
[[Categorie:Compositores]]
l8mlorhe6no5kwzsd7yiishmb051jqo
Usator:Otavio F. Lima
2
20967
167667
2026-04-26T00:47:54Z
Otavio F. Lima
21747
Creat págine contenente «.»
167667
wikitext
text/x-wiki
.
6t9fg2gmch401ldtk8m7pyzz632ixbb