https://en.wikipedia.org/w/index.php?action=history&feed=atom&title=Module%3ACite_IUCN%2FsandboxModule:Cite IUCN/sandbox - Revision history2025-05-30T09:59:59ZRevision history for this page on the wikiMediaWiki 1.45.0-wmf.3https://en.wikipedia.org/w/index.php?title=Module:Cite_IUCN/sandbox&diff=1167162715&oldid=prevElli: Elli moved page Module:Cite iucn/sandbox to Module:Cite IUCN/sandbox without leaving a redirect: per RM2023-07-26T02:28:50Z<p>Elli moved page <a href="/w/index.php?title=Module:Cite_iucn/sandbox&action=edit&redlink=1" class="new" title="Module:Cite iucn/sandbox (page does not exist)">Module:Cite iucn/sandbox</a> to <a href="/wiki/Module:Cite_IUCN/sandbox" title="Module:Cite IUCN/sandbox">Module:Cite IUCN/sandbox</a> without leaving a redirect: per <a href="/wiki/Special:PermanentLink/1167162175#Requested_move_16_July_2023" title="Special:PermanentLink/1167162175">RM</a></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<tr class="diff-title" lang="en">
<td colspan="1" style="background-color: #fff; color: #202122; text-align: center;">← Previous revision</td>
<td colspan="1" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 02:28, 26 July 2023</td>
</tr><tr><td colspan="2" class="diff-notice" lang="en"><div class="mw-diff-empty">(No difference)</div>
</td></tr></table>Ellihttps://en.wikipedia.org/w/index.php?title=Module:Cite_IUCN/sandbox&diff=1117367233&oldid=prevWOSlinker: use require('strict') instead of require('Module:No globals')2022-10-21T09:59:52Z<p>use require('strict') instead of require('Module:No globals')</p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Previous revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 09:59, 21 October 2022</td>
</tr><tr>
<td colspan="2" class="diff-lineno">Line 1:</td>
<td colspan="2" class="diff-lineno">Line 1:</td>
</tr>
<tr>
<td class="diff-marker" data-marker="−"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>require('<del style="font-weight: bold; text-decoration: none;">Module:No globals</del>');</div></td>
<td class="diff-marker" data-marker="+"></td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>require('<ins style="font-weight: bold; text-decoration: none;">strict</ins>');</div></td>
</tr>
<tr>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>local getArgs = require ('Module:Arguments').getArgs;</div></td>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>local getArgs = require ('Module:Arguments').getArgs;</div></td>
</tr>
<tr>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br /></td>
<td class="diff-marker"></td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br /></td>
</tr>
</table>WOSlinkerhttps://en.wikipedia.org/w/index.php?title=Module:Cite_IUCN/sandbox&diff=972526525&oldid=prevJts1882: create sandbox to test new param for make cite iucn2020-08-12T14:47:47Z<p>create sandbox to test new param for make cite iucn</p>
<p><b>New page</b></p><div>require('Module:No globals');<br />
local getArgs = require ('Module:Arguments').getArgs;<br />
<br />
<br />
--[[--------------------------< I U C N _ I D E N T I F I E R S _ G E T >--------------------------------------<br />
<br />
cs1|2 templates cite single sources; when the identifiers in |doi=, |id=, and |page= are different from each other<br />
then the template is attempting to cite multiple sources. This function evaluates the identifier portions of these<br />
parameters. returns seven values: identifyier parts (or nil when parameter not used) and a message (nil on success,<br />
error message else)<br />
<br />
the identifier portions of the several parameters must be properly formed<br />
<br />
]]<br />
<br />
local function iucn_identifiers_get (args)<br />
local doi_taxon_ID, doi_assesment_ID<br />
local page_taxon_ID, page_assesment_ID<br />
local id_taxon_ID, id_assesment_ID<br />
local url_taxon_ID, url_assesment_ID<br />
local msg<br />
<br />
if args.doi then<br />
doi_taxon_ID, doi_assesment_ID = args.doi:match ('[Tt](%d+)[Aa](%d+)%.en$')<br />
if not doi_taxon_ID then<br />
msg = 'malformed |doi= identifier'<br />
end<br />
end<br />
if args.page then<br />
page_taxon_ID, page_assesment_ID = args.page:match ('^[eE]%.[Tt](%d+)[Aa](%d+)$')<br />
if not page_taxon_ID then<br />
msg = 'malformed |page= identifier'<br />
end<br />
end<br />
if args.id then<br />
id_taxon_ID, id_assesment_ID = args.id:match ('^(%d+)/(%d+)$')<br />
if not id_taxon_ID then<br />
msg = 'malformed |id= identifier'<br />
end<br />
end<br />
if args.url then<br />
if args.url:match ('https://www.iucnredlist.org/species/') then -- must be a 'new-form' url<br />
url_taxon_ID, url_assesment_ID = args.url:match ('/species/(%d+)/(%d+)')<br />
if not url_taxon_ID then<br />
msg = 'malformed |url= identifier'<br />
end<br />
end<br />
end<br />
<br />
if not msg then<br />
if doi_taxon_ID and page_taxon_ID then<br />
if not (doi_taxon_ID == page_taxon_ID and doi_assesment_ID == page_assesment_ID) then<br />
msg = '|doi= / |page= mismatch'<br />
end<br />
end<br />
if doi_taxon_ID and id_taxon_ID then<br />
if not (doi_taxon_ID == id_taxon_ID and doi_assesment_ID == id_assesment_ID) then<br />
msg = '|doi= / |id= mismatch'<br />
end<br />
end<br />
if doi_taxon_ID and url_taxon_ID then<br />
if not (doi_taxon_ID == url_taxon_ID and doi_assesment_ID == url_assesment_ID) then<br />
msg = '|doi= / |url= mismatch'<br />
end<br />
end<br />
<br />
if page_taxon_ID and id_taxon_ID then<br />
if not (page_taxon_ID == id_taxon_ID and page_assesment_ID == id_assesment_ID) then<br />
msg = '|page= / |id= mismatch'<br />
end<br />
end<br />
if page_taxon_ID and url_taxon_ID then<br />
if not (page_taxon_ID == url_taxon_ID and page_assesment_ID == url_assesment_ID) then<br />
msg = '|page= / |url= mismatch'<br />
end<br />
end<br />
<br />
if id_taxon_ID and url_taxon_ID then<br />
if not (id_taxon_ID == url_taxon_ID and id_assesment_ID == url_assesment_ID) then<br />
msg = '|id= / |url= mismatch'<br />
end<br />
end<br />
end<br />
<br />
if msg then<br />
msg = '<span class="error" style="font-size:100%">{{cite iucn}}: error: ' .. msg .. ' ([[Template:Cite iucn|help]])</span>'<br />
end<br />
<br />
return doi_taxon_ID, doi_assesment_ID, page_taxon_ID, page_assesment_ID, id_taxon_ID, id_assesment_ID, msg<br />
end<br />
<br />
<br />
--[[--------------------------< I U C N _ V O L U M E _ C H E C K >--------------------------------------------<br />
<br />
compares volume in |volume= (if present) against year in |date= or |year= (if present) against volume in |doi= (if present)<br />
<br />
returns nil if all that are present are correct; message else<br />
<br />
]]<br />
<br />
local function iucn_volume_check (args)<br />
local vol = args.volume;<br />
local date = args.date or args.year;<br />
local doi = args.doi and args.doi:match ('[Ii][Uu][Cc][Nn]%.[Uu][Kk]%.(%d%d%d%d)')<br />
local msg<br />
<br />
if vol and date then<br />
msg = (vol ~= date) and '|volume= / |date= mismatch' or msg<br />
end<br />
if vol and doi then<br />
msg = (vol ~= doi) and '|volume= / |doi= mismatch' or msg<br />
end<br />
if date and doi then<br />
msg = (doi ~= date) and '|date= / |doi= mismatch' or msg<br />
end<br />
<br />
return msg<br />
end<br />
<br />
<br />
--[[--------------------------< C I T E >----------------------------------------------------------------------<br />
<br />
Wraps {{cite journal}}:<br />
takes cite journal parameters but updates old style url using electronic page number<br />
page should be in format e.T13922A45199653<br />
the url uses 13922/45199653<br />
so we need to extract the number between T and A (taxon ID) and the number after A (assessment ID)<br />
the target url is https://www.iucnredlist.org/species/13922/45199653<br />
usage: {{#invoke:iucn|cite}}<br />
template: {{Template:Cite iucn}}<br />
<br />
]]<br />
<br />
local function cite (frame)<br />
local error_msgs = {}; -- holds error messages for rendering<br />
local maint_msgs = {}; -- holds hidden maint messages for rendering<br />
local namespace = mw.title.getCurrentTitle().namespace; -- used for categorization<br />
local args = getArgs (frame); -- local copy of template arguments<br />
<br />
local missing_title = not args.title -- special case that results from script writing {{cite iucn}} template from bare iucn url<br />
-- don't duplicate cs1|2 error message; don't duplicate {{cite iucn}} error cat<br />
-- TODO: remove this when the error category has been cleared of missing title errors<br />
<br />
local doi_taxon_ID, doi_assesment_ID -- all of these contain the same identifying info in slightly<br />
local page_taxon_ID, page_assesment_ID -- different forms. when any combination of these is present,<br />
local id_taxon_ID, id_assesment_ID -- they must all agree<br />
local msg -- this holds error messages; nil on success<br />
<br />
doi_taxon_ID, doi_assesment_ID, page_taxon_ID, page_assesment_ID, id_taxon_ID, id_assesment_ID, msg = iucn_identifiers_get (args);<br />
if msg then<br />
table.insert (error_msgs, msg); -- malformed or mismatched identifiers<br />
end<br />
args.id = nil -- unset; no longer needed if it was set<br />
<br />
local url_taxon_ID = page_taxon_ID or id_taxon_ID or doi_taxon_ID; -- select for use in url that we will create<br />
local url_assesment_ID = page_assesment_ID or id_assesment_ID or doi_assesment_ID<br />
<br />
local url = args.url<br />
if url then<br />
if url:find ('iucnredlist.org/details/', 1, true) then -- old-form url<br />
if url_taxon_ID then -- when there is an identifier<br />
url = nil -- unset; we'll create new url below<br />
else -- here when old-form but no identifier that we can use to create new url<br />
args.url = args.url:gsub ("http:", "https:") -- sometimes works with redirect on iucn site<br />
end<br />
table.insert (maint_msgs, 'old-form url') -- announce that this template has has an old-form url<br />
elseif url:find ('iucnredlist.org/species/', 1, true) then -- new-form url<br />
-- table.insert (maint_msgs, 'new-form url') --TODO: restore this line when most new-form urls have been removed from article space -- announce that this template has has an new-form url<br />
else<br />
table.insert (maint_msgs, 'unknown url') -- announce that this template has has some sort of url we don't recognize<br />
end<br />
end<br />
<br />
if not url then -- when no url or unset old-form url<br />
if url_taxon_ID then<br />
args.url = "https://www.iucnredlist.org/species/" .. url_taxon_ID .. '/' .. url_assesment_ID<br />
else<br />
table.insert (maint_msgs, 'no identifier') -- TODO: raise this to error status?<br />
end<br />
end<br />
<br />
-- add journal if not provided (TODO decide if this should override provided value)<br />
if not args['journal'] and not args['work'] then<br />
args['journal'] = "[[IUCN Red List|IUCN Red List of Threatened Species]]"<br />
end<br />
<br />
msg = iucn_volume_check (args); -- |volume=, |year= (|date=), |doi= must all refer to the same volume<br />
if msg then<br />
table.insert (maint_msgs, msg);<br />
end<br />
<br />
if not args.volume and (args.year or args.date) then<br />
args.volume = args.year or args.date<br />
end<br />
-- add free-to-read icon to mark a correctly formed doi<br />
args['doi-access'] = args.doi and args.doi:match ('10%.2305/[Ii][Uu][Cc][Nn].+[Tt]%d+[Aa]%d+%.[Ee][Nn]') and 'free' or nil<br />
<br />
return frame:expandTemplate{ title = 'cite journal', args = args } .. -- the template<br />
(((0 == #error_msgs) and missing_title) and ('[[Category:cite iucn errors]]') or '') .. -- special case to not duplicate cs1|2 err msg or cite iucn error cat<br />
((0 < #error_msgs) and table.concat (error_msgs, ', ') or '') .. -- the error messages<br />
(((0 < #error_msgs) and (0 == namespace)) and ('[[Category:cite iucn errors]]') or '') .. -- error category when in mainspace<br />
((0 < #maint_msgs) and ('<span class="citation-comment" style="display: none; color: #33aa33; margin-left: 0.3em;">' .. table.concat (maint_msgs, ', ') .. '</span>') or '') .. -- the maint messages<br />
(((0 < #maint_msgs) and (0 == namespace)) and ('[[Category:cite iucn maint]]') or '') -- maint category when in mainspace<br />
end<br />
<br />
<br />
--[[--------------------------< A U T H O R _ L I S T _ M A K E >----------------------------------------------<br />
<br />
creates a list of individual |authorn= parameters from the list of names provided in the raw iucn citation. names<br />
must have the form: Surname, I. (more than one 'I.' pair allowed but no spaces between I. pairs)<br />
<br />
assumes that parenthetical text at the end of the author-name-list is a collaboration<br />
Name, I.I., & Name, I.I. (Colaboration name)<br />
<br />
]]<br />
<br />
local function author_names_get (raw_iucn_cite)<br />
local list = {}; -- table that holds name list parts<br />
local author_names = raw_iucn_cite:match ('^([^%d]-)%s+%d%d%d%d'); -- extract author name-list from raw iucn citation<br />
local collaboration = author_names:match ('%s*(%b())$'); -- get collaboration name if it exists<br />
<br />
if collaboration then -- when there is a colaboration<br />
collaboration = collaboration:gsub ('[%(%)]', ''); -- remove bounding parentheses<br />
author_names = author_names:gsub ('%s*(%b())$', ''); -- and remove collaboration from author-name-list<br />
end<br />
<br />
local names = author_names:gsub ('%.?,?%s+&%s+', '.|'):gsub ('%.,%s+', '.|'); -- replace 'separators' (<dot><comma><space> and <opt. dot><opt. comma><space><ampersand><space>) with <dot><pipe><br />
list = mw.text.split (names, '|'); -- split the string on the pipes into entries in list{}<br />
<br />
if 0 == #list then<br />
return table.concat ({'|author=', author_names}) -- no 'names' of the proper form; return the original as a single |author= parameter<br />
else<br />
for i, name in ipairs (list) do -- spin through the list and <br />
-- list[i] = table.concat ({'|author', i, '=', name}); -- add |authorn= parameter names<br />
list[i] = table.concat ({'|author', (i == 1) and '' or i, '=', name}); -- add |authorn= parameter names; create |author= instead of |author1=<br />
end<br />
if collaboration then<br />
table.insert (list, table.concat ({'|collaboration', '=', collaboration})); -- add |collaboration= parameter<br />
end<br />
return table.concat (list, ' '); -- make a big string and return that<br />
end<br />
end<br />
<br />
<br />
--[[--------------------------< T I T L E _ G E T >------------------------------------------------------------<br />
<br />
extract and format citation title; attempts to get the italic right<br />
<br />
''binomen'' (amended or errata title)<br />
''binomen''<br />
''binomen'' ssp. ''subspecies''<br />
''binomen'' subsp. ''subspecies''<br />
''binomen'' var. ''variety''<br />
''binomen'' subvar. ''subvariety''<br />
<br />
all of the above may have trailing amended or errata text in parentheses<br />
<br />
TODO: are there others?<br />
<br />
]]<br />
<br />
local function title_get (raw_iucn_cite)<br />
local title = raw_iucn_cite:match ('%d%d%d%d%.%s+(.-)%s*%. The IUCN Red List of Threatened Species');<br />
<br />
local patterns = { -- tables of string.match patterns [1] and string.gsub patterns [2]<br />
{'(.-)%sssp%.%s+(.-)%s(%b())$', "''%1'' ssp. ''%2'' %3"}, -- binomen ssp. subspecies (zoology) with errata or amended text<br />
{'(.-)%sssp%.%s+(.+)', "''%1'' ssp. ''%2''"}, -- binomen ssp. subspecies (zoology)<br />
{'(.-)%ssubsp%.%s+(.-)%s(%b())$', "''%1'' subsp. ''%2'' %3"}, -- binomen subsp. subspecies (botany) with errata or amended text<br />
{'(.-)%ssubsp%.%s+(.+)', "''%1'' subsp. ''%2''"}, -- binomen subsp. subspecies (botany)<br />
{'(.-)%svar%.%s+(.-)%s+(%b())$', "''%1'' var. ''%2'' %3"}, -- binomen var. variety (botany) with errata or amended text<br />
{'(.-)%svar%.%s+(.+)', "''%1'' var. ''%2''"}, -- binomen var. variety (botany)<br />
{'(.-)%ssubvar%.%s+(.-)%s(%b())$', "''%1'' subvar. ''%2'' %3"}, -- binomen subvar. subvariety (botany) with errata or amended text<br />
{'(.-)%ssubvar%.%s+(.+)', "''%1'' subvar. ''%2''"}, -- binomen subvar. subvariety (botany)<br />
{'(.-)%s*(%b())$', "''%1'' %2"}, -- binomen with errata or amended text<br />
{'(.+)', "''%1''"}, -- binomen<br />
}<br />
<br />
for i, v in ipairs (patterns) do -- spin through the patterns<br />
if title:match (v[1]) then -- when a match<br />
title = title:gsub (v[1], v[2]); -- add italics <br />
break; -- and done<br />
end<br />
end<br />
<br />
return table.concat ({' |title=', title}); -- return the |title= parameter<br />
end<br />
<br />
<br />
--[[--------------------------< M A K E _ C I T E _ I U C N >--------------------------------------------------<br />
<br />
parses apart an iucn-format citation copied from their webpage and reformats that into a {{cite iucn}} template for substing<br />
<br />
automatic substing by User:AnomieBOT/docs/TemplateSubster<br />
<br />
]]<br />
<br />
local function make_cite_iucn (frame)<br />
local args = getArgs (frame);<br />
local raw_iucn_cite = args[1];<br />
<br />
local template = {'{{cite iucn '}; -- table that holds the {{cite iucn}} template as it is being assembled<br />
local year, volume, page, doi, accessdate;<br />
<br />
year = raw_iucn_cite:match ('^%D+(%d%d%d%d)');<br />
volume, page = raw_iucn_cite:match ('(%d%d%d%d):%s+(e%.T%d+A+%d+)%.%s');<br />
doi = raw_iucn_cite:match ('10%.2305/IUCN%.UK%.[%d%-]+%.RLTS%.T%d+A%d+%.en');<br />
<br />
accessdate = raw_iucn_cite:match ('Downloaded on (.-)%.?$'):gsub ('^0', ''); -- strips leading 0 in day 01 January 2020 -> 1 January 2020<br />
<br />
table.insert (template, author_names_get (raw_iucn_cite)); -- add string of author name parameters<br />
table.insert (template, table.concat ({' |year=', year})); -- add formatted year<br />
table.insert (template, title_get (raw_iucn_cite)); -- add formatted title<br />
table.insert (template, table.concat ({' |volume=', volume})); -- add formatted volume<br />
table.insert (template, table.concat ({' |page=', page})); -- add formatted page<br />
table.insert (template, table.concat ({' |doi=', doi})); -- add formatted doi<br />
table.insert (template, table.concat ({' |access-date=', accessdate})); -- add formatted access-date<br />
table.insert (template, '}}'); -- close the template<br />
<br />
if args[2] then -- if anything in args[2], write a nowiki'd version that editors can copy into <ref> tags<br />
return table.concat ({'<code>', frame:callParserFunction ('#tag:nowiki', table.concat (template)), '</code>'})<br />
end<br />
if args['ref'] then<br />
return '<ref name=' .. args['ref'] .. '>' .. table.concat (template) .. '</ref>'<br />
end<br />
return table.concat (template); -- the subst'd version<br />
end<br />
<br />
<br />
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------<br />
]]<br />
<br />
return {<br />
cite = cite,<br />
make_cite_iucn = make_cite_iucn,<br />
}</div>Jts1882