Módulo:Iucn

Documentação do módulo[ver] [editar] [histórico] [purgar]

Uso

{{#invoke:Iucn|cite}} – para {{citar iucn}}

{{#invoke:Iucn|make_cite_iucn}} – para {{make citar iucn}}


Informação antecedente

Estilo antigo e estilo novo dos urls da IUCN

Até ao final de 2018, as avaliações da IUCN usaram urls na forma

http://www.iucnredlist.org/details/15955/0
onde 15955 é o ID do táxon e o sufico “0” indica a avaliação global (outro código de algarismos únicos para as diversas avaliações regionais).

A partir de setembro de 2018, a IUCN mudou para um novo formato para a url, do formulário

https://www.iucnredlist.org/species/15955/50659951
onde o 15955 é o ID de táxon e o sufio único identifica a versão da avaliação. Isso deixou todos os links da Wikipédia para avaliações da IUCN como links mortos.

Pouco tempo depois, a IUCN produziu um backup do antigo sistema com ligações da forma

http://oldredlist.iucnredlist.org/details/15955/0
que utiliza o estilo antigo de url na forma do subdomínio oldredlist. Muitas citações mudaram para este url. No entanto, este subdomínio foi encerrado perto do final de 2019, deixando muitos links mortos gerando erros 502 Bad Gateway.

Citações atuais da IUCN

Uma citação típica da IUCN, como indicado nas suas páginas de avaliação, é agora da forma:

Goodrich, J., Lynam, A., Miquelle, D., Wibisono, H., Kawanishi, K., Pattanavibool, A., Htun, S., Tempa, T., Karki, J., Jhala, Y. & Karanth, U. 2015. Panthera tigris. The IUCN Red List of Threatened Species 2015: e.T15955A50659951. https://dx.doi.org/10.2305/IUCN.UK.2015-2.RLTS.T15955A50659951.en. Downloaded on 19 December 2019.
onde o número de página eletrónico e.T15955A50659951 contem o ID do táxon (entre o T e A) e o ID da avaliação (depois de A). Estes dois números de identificação também estão contidos no doi.

Quando há uma alteração a uma avaliação, Um novo número de avaliação é atribuído, o que provoca uma alteração no número da página eletrônica e o url da página.

O comportamento do doi é incomum. Uma nova avaliação não causa uma nova referência doi, mantém o número de avaliação original. Se isto for usado por um modelo para construir uma url, será para a versão original da avaliação. No entanto, se o url do doi é seguido, a IUCN resolve redirecionar para a última avaliação. O alvo do doi mudou para a versão revista da avaliação da IUCN. Assim, se o modelo usar o url doi, a página vinculada irá mudar a partir do visualização pelo editor que adicionou a citação.

Portanto, este módulo irá criar um url com a seguinte ordem de precedência:

  1. Utilizar o número da página electrónica definido pelo parâmetro |page= para gerar o url.
  2. Utilize o parâmetro |id= para gera o url se é um dos dois novos estilos da forma em duas partes, m.q. ID_TÁXON/ID_AVALIAÇÃO (m.q. 15955/50659951)
  3. Utilize o parâmetro |doi= para gerar o url. Trata-se da última opção, uma vez que utiliza o número da avaliação inicial, mesmo quando esta foi alterada.

Quando nenhuma das opções acima estiver disponível, e quando |url= tiver a forma antiga, este módulo irá mudar o esquema de http:// para https:// numa tentativa de fazer uma ligação de trabalho (ver secção seguinte).

Edição do legado com urls antigos

Ainda há uma edição do legado com urls da antiga IUCN, que ainda são usados em muitas citações da Wikipédia.

Alguns meses após a mudança para os urls de novo estilo, a IUCN introduziu redirecionamentos para os urls de velho estilo que ligam para as páginas apropriadas endereçadas pelo novo URL de estilo. Na maioria dos casos, estas redirecções funcionarão. Então o antigo url de estilo para o tigre https://www.iucnredlist.org/details/15955/0 ligações correctas com a avaliação em https://www.iucnredlist.org/species/15955/50659951 (ver tigre).

No entanto, nem todas as avaliações redirecionam. Por exemplo, o antigo url de estilo para a enguia-de-lama de Bengala http://www.iucnredlist.org/details/166410/0 liga a página inicial (ver Enguia-de-lama).

Esta falha de algum antigo URL de estilo a ser redirecionado é inesperada, como a função redirecionar da API da IUCN faz link para a página correta. Um url do formulário

https://apiv3.iucnredlist.org/api/v3/taxonredirect/166410
irá ligar para a página correta, mesmo nos casos em que o redirecionamento automático falhou, m.q. the Bengal mud eel.

No entanto, redirecionamentos não estão disponíveis quando o ID do táxon foi substituído e um erro no formato JSON é retornado (m.q. for house sparrow).

IDs de táxons novos

Há outro caso em que os urls antigos dão links mortos, quando o ID do táxon mudou. Por exemplo, o pardal italiano foi separado do pardal da casa como uma nova espécie e ambos atribuíram novas identificações de táxons. Isto deixou quaisquer urls de estilo antigo para a avaliação original como ligações mortas.

  • url estilo antigo http://www.iucnredlist.org/details/149100/0 para house sparrow (link morto para o id de táxon antigo 149100)
  • url estilo nov https://www.iucnredlist.org/species/103818789/155522130 for house sparrow (Passer domesticus), utilizar o novo ID do táxon e o número de avaliação 103818789/155522130.
  • url estilo novo https://www.iucnredlist.org/species/103819014/132196181 para Italian sparrow (Passer italiae), utilizar o novo ID do táxon e o número de avaliação 103819014/132196181.

Neste caso, não há nenhuma ação que o modelo/módulo possa tomar para resolver o problema. É necessária a intervenção activa de um editor.

require('strict') local getArgs = require ('Module:Arguments').getArgs;  local amendment_pattern = '%s*%(amended version of (%d%d%d%d) assessment%)'; local errata_pattern = '%s*%(errata version published in (%d%d%d%d)%)';   --[[--------------------------< 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 other then the template is attempting to cite multiple sources.  This function evaluates the identifier portions of these parameters. 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     local page = args.page or args['página']     if page then         page_taxon_ID, page_assesment_ID = 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= mismatch'             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= mismatch'             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= mismatch'             end         end     end      if msg then         msg = '<span class="error" style="font-size:100%">{{citar iucn}}: erro: ' .. msg .. ' ([[Predefinição:Citar iucn|ajuda]])</span>'     end          return doi_taxon_ID, doi_assesment_ID, page_taxon_ID, page_assesment_ID, msg end   --[[--------------------------< 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 or args.data or args.ano;     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= mismatch' or msg     end     if vol and doi then         msg = ((vol ~= doi) and not args.amends) and '|volume= / |doi= mismatch' or msg     end     if date and doi then         msg = ((doi ~= date) and not args.amends) and '|date= / |doi= mismatch' or msg     end          return msg end   --[[--------------------------< 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 or args.titulo or args['título']                                       -- 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      if args.title and (args.title:match (errata_pattern) or args.title:match (amendment_pattern)) then         table.insert (maint_msgs, 'title has extraneous text');                    -- announce that this template has has errata or amendment text     end      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 mismatched 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, 'old-form url')                            -- 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, '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         else             table.insert (maint_msgs, 'unknown url')                            -- 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, 'no identifier')                            -- 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'] and not args['periódico'] then         args['journal'] = "[[Lista Vermelha da IUCN|Lista Vermelha de Espécies Ameaçadas]]"     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     local date = args.year or args.ano or args.date or args.data      if not args.volume and date then         args.volume = date     end          if args.errata then         args['orig-year'] = 'errata version of ' .. (date or args.volume) .. ' assessment';         args.date = args.errata;                                                -- update publication data to errata year         args.year = nil;                                                        -- unset these as no longer needed     args.ano = nil         args.errata = nil;     elseif args.amends then         args['orig-year'] = 'amended version of ' .. args.amends .. ' assessment';         args.amends = nil;                                                        -- unset as no longer needed     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 = 'citar periódico', args = args } ..                            -- the template --        (((0 == #error_msgs) and missing_title) and ('[[Categoria:!Erros citar 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 ('[[Categoria:!Erros citar 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 ('[[Categoria:!Manutenção citar iucn]]') or '')        -- maint category when in mainspace end   --[[--------------------------< 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.  names must 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>     names = names:gsub ('(%.%u),', '%1.|');                                        -- special case for when last initial is missing its trailing dot     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     end end   --[[--------------------------< 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 parentheses  TODO: 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= parameter end   --[[--------------------------< 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 substing  automatic substing by User:AnomieBOT/docs/TemplateSubster  ]]  local function make_cite_iucn (frame)     local args = getArgs (frame);     local raw_iucn_cite = args[1];          local template = {'{{citar 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     accessdate = raw_iucn_cite:match ('Accessed on (.-)%.?$') or raw_iucn_cite:match ('Downloaded on (.-)%.?$');    -- 'Downloaded' → 'Accessed' change occured December 2021;     accessdate = accessdate: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);     local errata = title:match (errata_pattern);                                -- nil unless IUCN citation has errata annotation; else year that this errata published (|date=)     if errata then         table.insert (template, table.concat ({' |errata=', errata}));            -- add formatted errata         title = title:gsub (errata_pattern, '');                                -- remove errata annotation     end     local amends = title:match (amendment_pattern);                                -- nil unless IUCN citation has amendment annotation; else year that this assessment amends (|orig-year=)     if amends then         table.insert (template, table.concat ({' |amends=', amends}));            -- add year of assessment that this assessment amends         title = title:gsub (amendment_pattern, '');                                -- remove amendment annotation     end      table.insert (template, title);                                                -- 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 version end   --[[--------------------------< 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,     }