Mô đun:Cite IUCN
Giao diện
require('strict');local getArgs = require ('Module:Arguments').getArgs;--[[--------------------------< I U C N _ I D E N T I F I E R S _ G E T >--------------------------------------cs1|2 templates cite single sources; when the identifiers in |doi=, |id=, and |page= are different from each otherthen the template is attempting to cite multiple sources. This function evaluates the identifier portions of theseparameters. returns seven values: identifyier parts (or nil when parameter not used) and a message (nil on success,error message else)the identifier portions of the several parameters must be properly formed]]local function iucn_identifiers_get (args) local doi_taxon_ID, doi_assesment_ID local page_taxon_ID, page_assesment_ID local url_taxon_ID, url_assesment_ID local msg if args.doi then doi_taxon_ID, doi_assesment_ID = args.doi:match ('[Tt](%d+)[Aa](%d+)%.en$') if not doi_taxon_ID then msg = 'malformed |doi= identifier' end end if args.page then page_taxon_ID, page_assesment_ID = args.page:match ('^[eE]%.[Tt](%d+)[Aa](%d+)$') if not page_taxon_ID then msg = 'malformed |page= identifier' end end if args.url then if args.url:match ('https://www.iucnredlist.org/species/') then -- must be a 'new-form' url url_taxon_ID, url_assesment_ID = args.url:match ('/species/(%d+)/(%d+)') if not url_taxon_ID then msg = 'malformed |url= identifier' end end end if not msg then if doi_taxon_ID and page_taxon_ID then if (doi_taxon_ID ~= page_taxon_ID or ((doi_assesment_ID ~= page_assesment_ID) and not args.errata)) then msg = '|doi= / |page= không tương xứng' end end if doi_taxon_ID and url_taxon_ID then if (doi_taxon_ID ~= url_taxon_ID or ((doi_assesment_ID ~= url_assesment_ID) and not args.errata)) then msg = '|doi= / |url= không tương xứng' end end if page_taxon_ID and url_taxon_ID then if (page_taxon_ID ~= url_taxon_ID or ((page_assesment_ID ~= url_assesment_ID) and not args.errata)) then msg = '|page= / |url= không tương xứng' end end end if msg then msg = '<span class="error" style="font-size:100%">{{cite iucn}}: error: ' .. msg .. ' ([[Template:Cite iucn|help]])</span>' end return doi_taxon_ID, doi_assesment_ID, page_taxon_ID, page_assesment_ID, msgend--[[--------------------------< I U C N _ V O L U M E _ C H E C K >--------------------------------------------compares volume in |volume= (if present) against year in |date= or |year= (if present) against volume in |doi= (if present)returns nil if all that are present are correct; message else]]local function iucn_volume_check (args) local vol = args.volume; local date = args.date or args.year; local doi = args.doi and args.doi:match ('[Ii][Uu][Cc][Nn]%.[Uu][Kk]%.(%d%d%d%d)') local msg if vol and date then msg = (vol ~= date) and '|volume= / |date= không tương xứng' or msg end if vol and doi then msg = (vol ~= doi) and '|volume= / |doi= không tương xứng' or msg end if date and doi then msg = (doi ~= date) and '|date= / |doi= không tương xứng' or msg end return msgend--[[--------------------------< C I T E >----------------------------------------------------------------------Wraps {{cite journal}}: takes cite journal parameters but updates old style url using electronic page number page should be in format e.T13922A45199653 the url uses 13922/45199653 so we need to extract the number between T and A (taxon ID) and the number after A (assessment ID) the target url is https://www.iucnredlist.org/species/13922/45199653 usage: {{#invoke:iucn|cite}} template: {{Template:Cite iucn}}]]local function cite (frame) local error_msgs = {}; -- holds error messages for rendering local maint_msgs = {}; -- holds hidden maint messages for rendering local namespace = mw.title.getCurrentTitle().namespace; -- used for categorization local args = getArgs (frame); -- local copy of template arguments local missing_title = not args.title -- special case that results from script writing {{cite iucn}} template from bare iucn url -- don't duplicate cs1|2 error message; don't duplicate {{cite iucn}} error cat -- TODO: remove this when the error category has been cleared of missing title errors local doi_taxon_ID, doi_assesment_ID -- all of these contain the same identifying info in slightly local page_taxon_ID, page_assesment_ID -- different forms. when any combination of these is present, local msg -- this holds error messages; nil on success doi_taxon_ID, doi_assesment_ID, page_taxon_ID, page_assesment_ID, msg = iucn_identifiers_get (args); if msg then table.insert (error_msgs, msg); -- malformed or không tương xứnged identifiers end args.id = nil -- unset; not supported local url_taxon_ID = page_taxon_ID or doi_taxon_ID; -- select for use in url that we will create local url_assesment_ID = page_assesment_ID or doi_assesment_ID local url = args.url if url then if url:find ('iucnredlist.org/details/', 1, true) then -- old-form url if url_taxon_ID then -- when there is an identifier url = nil -- unset; we'll create new url below else -- here when old-form but no identifier that we can use to create new url args.url = args.url:gsub ("http:", "https:") -- sometimes works with redirect on iucn site end table.insert (maint_msgs, 'url dạng cũ') -- announce that this template has has an old-form url elseif url:find ('iucnredlist.org/species/', 1, true) then -- new-form url-- table.insert (maint_msgs, 'url dạng mới') --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 else table.insert (maint_msgs, 'url không xác định') -- announce that this template has has some sort of url we don't recognize end end if not url then -- when no url or unset old-form url if url_taxon_ID then args.url = "https://www.iucnredlist.org/species/" .. url_taxon_ID .. '/' .. url_assesment_ID else table.insert (maint_msgs, 'không có định danh') -- TODO: raise this to error status? end end -- add journal if not provided (TODO decide if this should override provided value) if not args['journal'] and not args['work'] then args['journal'] = "[[Sách đỏ IUCN|Sách đỏ IUCN về các loài bị đe dọa]]" end msg = iucn_volume_check (args); -- |volume=, |year= (|date=), |doi= must all refer to the same volume if msg then table.insert (maint_msgs, msg); end if not args.volume and (args.year or args.date) then args.volume = args.year or args.date end if args.errata then args['orig-date'] = args.year or args.date; args.date = args.errata; -- update publication data to errata year args.year = nil; -- unset these as no longer needed args.errata = nil; end -- add free-to-read icon to mark a correctly formed doi 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 return frame:expandTemplate{ title = 'cite journal', args = args } .. -- the template (((0 == #error_msgs) and missing_title) and ('[[Thể loại:Lỗi chú thích IUCN]]') or '') .. -- special case to not duplicate cs1|2 err msg or cite iucn error cat ((0 < #error_msgs) and table.concat (error_msgs, ', ') or '') .. -- the error messages (((0 < #error_msgs) and (0 == namespace)) and ('[[Thể loại:Lỗi chú thích IUCN]]') or '') .. -- error category when in mainspace ((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 (((0 < #maint_msgs) and (0 == namespace)) and ('[[Thể loại:Quản lý chú thích IUCN]]') or '') -- maint category when in mainspaceend--[[--------------------------< A U T H O R _ L I S T _ M A K E >----------------------------------------------creates a list of individual |authorn= parameters from the list of names provided in the raw iucn citation. namesmust have the form: Surname, I. (more than one 'I.' pair allowed but no spaces between I. pairs)assumes that parenthetical text at the end of the author-name-list is a collaboration Name, I.I., & Name, I.I. (Colaboration name)]]local function author_names_get (raw_iucn_cite) local list = {}; -- table that holds name list parts local author_names = raw_iucn_cite:match ('^([^%d]-)%s+%d%d%d%d'); -- extract author name-list from raw iucn citation local collaboration = author_names:match ('%s*(%b())$'); -- get collaboration name if it exists if collaboration then -- when there is a colaboration collaboration = collaboration:gsub ('[%(%)]', ''); -- remove bounding parentheses author_names = author_names:gsub ('%s*(%b())$', ''); -- and remove collaboration from author-name-list end 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> list = mw.text.split (names, '|'); -- split the string on the pipes into entries in list{} if 0 == #list then return table.concat ({'|author=', author_names}) -- no 'names' of the proper form; return the original as a single |author= parameter else for i, name in ipairs (list) do -- spin through the list and -- list[i] = table.concat ({'|author', i, '=', name}); -- add |authorn= parameter names list[i] = table.concat ({'|author', (i == 1) and '' or i, '=', name}); -- add |authorn= parameter names; create |author= instead of |author1= end if collaboration then table.insert (list, table.concat ({'|collaboration', '=', collaboration})); -- add |collaboration= parameter end return table.concat (list, ' '); -- make a big string and return that endend--[[--------------------------< T I T L E _ G E T >------------------------------------------------------------extract and format citation title; attempts to get the italic right''binomen'' (amended or errata title)''binomen''''binomen'' ssp. ''subspecies''''binomen'' subsp. ''subspecies''''binomen'' var. ''variety''''binomen'' subvar. ''subvariety''all of the above may have trailing amended or errata text in parenthesesTODO: are there others?]]local function title_get (raw_iucn_cite) local title = raw_iucn_cite:match ('%d%d%d%d%.%s+(.-)%s*%. The IUCN Red List of Threatened Species'); local patterns = { -- tables of string.match patterns [1] and string.gsub patterns [2] {'(.-)%sssp%.%s+(.-)%s(%b())$', "''%1'' ssp. ''%2'' %3"}, -- binomen ssp. subspecies (zoology) with errata or amended text {'(.-)%sssp%.%s+(.+)', "''%1'' ssp. ''%2''"}, -- binomen ssp. subspecies (zoology) {'(.-)%ssubsp%.%s+(.-)%s(%b())$', "''%1'' subsp. ''%2'' %3"}, -- binomen subsp. subspecies (botany) with errata or amended text {'(.-)%ssubsp%.%s+(.+)', "''%1'' subsp. ''%2''"}, -- binomen subsp. subspecies (botany) {'(.-)%svar%.%s+(.-)%s+(%b())$', "''%1'' var. ''%2'' %3"}, -- binomen var. variety (botany) with errata or amended text {'(.-)%svar%.%s+(.+)', "''%1'' var. ''%2''"}, -- binomen var. variety (botany) {'(.-)%ssubvar%.%s+(.-)%s(%b())$', "''%1'' subvar. ''%2'' %3"}, -- binomen subvar. subvariety (botany) with errata or amended text {'(.-)%ssubvar%.%s+(.+)', "''%1'' subvar. ''%2''"}, -- binomen subvar. subvariety (botany) {'(.-)%s*(%b())$', "''%1'' %2"}, -- binomen with errata or amended text {'(.+)', "''%1''"}, -- binomen } for i, v in ipairs (patterns) do -- spin through the patterns if title:match (v[1]) then -- when a match title = title:gsub (v[1], v[2]); -- add italics break; -- and done end end return table.concat ({' |title=', title}); -- return the |title= parameterend--[[--------------------------< M A K E _ C I T E _ I U C N >--------------------------------------------------parses apart an iucn-format citation copied from their webpage and reformats that into a {{cite iucn}} template for substingautomatic substing by User:AnomieBOT/docs/TemplateSubster]]local function make_cite_iucn (frame) local args = getArgs (frame); local raw_iucn_cite = args[1]; local template = {'{{cite iucn '}; -- table that holds the {{cite iucn}} template as it is being assembled local year, volume, page, doi, accessdate; year = raw_iucn_cite:match ('^%D+(%d%d%d%d)'); volume, page = raw_iucn_cite:match ('(%d%d%d%d):%s+(e%.T%d+A+%d+)%.%s'); doi = raw_iucn_cite:match ('10%.2305/IUCN%.UK%.[%d%-]+%.RLTS%.T%d+A%d+%.en'); accessdate = raw_iucn_cite:match ('Downloaded on (.-)%.?$'):gsub ('^0', ''); -- strips leading 0 in day 01 January 2020 -> 1 January 2020 table.insert (template, author_names_get (raw_iucn_cite)); -- add string of author name parameters table.insert (template, table.concat ({' |year=', year})); -- add formatted year local title = title_get (raw_iucn_cite); table.insert (template, title); -- add formatted title local errata = title:match ('%(errata version published in (%d%d%d%d)%)'); if errata then table.insert (template, table.concat ({' |errata=', errata})); -- add formatted errata end-- table.insert (template, title_get (raw_iucn_cite)); -- add formatted title table.insert (template, table.concat ({' |volume=', volume})); -- add formatted volume table.insert (template, table.concat ({' |page=', page})); -- add formatted page table.insert (template, table.concat ({' |doi=', doi})); -- add formatted doi table.insert (template, table.concat ({' |access-date=', accessdate})); -- add formatted access-date table.insert (template, '}}'); -- close the template if args[2] then -- if anything in args[2], write a nowiki'd version that editors can copy into <ref> tags return table.concat ({'<code>', frame:callParserFunction ('#tag:nowiki', table.concat (template)), '</code>'}) end if args['ref'] then -- enable subst of ref tags with name return '<ref name=' .. args['ref'] .. '>' .. table.concat (template) .. '</ref>' end return table.concat (template); -- the subst'd versionend--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------]]return { cite = cite, make_cite_iucn = make_cite_iucn, }