Module:Citation/CS1/Identifiers#L-1081

--[[--------------------------< 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 ::

when has an
for ; nil else

for identifiers that do not have q, returns nil

for wikis that do not have mw.wikibase installed, returns nil

]]

local function wikidata_article_name_get (q)

if not is_set (q) or (q and not mw.wikibase) then -- when no q number or when a q number but mw.wikibase not installed on this wiki

return nil; -- abandon

end

local wd_article;

local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org

wd_article = mw.wikibase.getSitelink (q, this_wiki_code .. 'wiki'); -- fetch article title from WD; nil when no title available at this wiki

if wd_article then

wd_article = table.concat ({':', this_wiki_code, ':', wd_article}); -- interwiki-style link without brackets if taken from WD; leading colon required

end

return wd_article; -- article title from WD; nil else

end

--[[--------------------------< L I N K _ L A B E L _ M A K E >------------------------------------------------

common function to create identifier link label from handler table or from Wikidata

returns the first available of

1. redirect from local wiki's handler table (if enabled)

2. Wikidata (if there is a Wikidata entry for this identifier in the local wiki's language)

3. label specified in the local wiki's handler table

]]

local function link_label_make (handler)

local wd_article;

if not (cfg.use_identifier_redirects and is_set (handler.redirect)) then -- redirect has priority so if enabled and available don't fetch from Wikidata because expensive

wd_article = wikidata_article_name_get (handler.q); -- if Wikidata has an article title for this wiki, get it;

end

return (cfg.use_identifier_redirects and is_set (handler.redirect) and handler.redirect) or wd_article or handler.link;

end

--[[--------------------------< E X T E R N A L _ L I N K _ I D >----------------------------------------------

Formats a wiki-style external link

]]

local function external_link_id (options)

local url_string = options.id;

local ext_link;

local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org

local wd_article; -- article title from Wikidata

if options.encode == true or options.encode == nil then

url_string = mw.uri.encode (url_string, 'PATH');

end

if options.auto_link and is_set (options.access) then

auto_link_urls[options.auto_link] = table.concat ({options.prefix, url_string, options.suffix});

end

ext_link = mw.ustring.format ('[%s%s%s %s]', options.prefix, url_string, options.suffix or "", mw.text.nowiki (options.id));

if is_set (options.access) then

ext_link = substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[options.access].class, cfg.presentation[options.access].title, ext_link}); -- add the free-to-read / paywall lock

end

return table.concat ({

make_wikilink (link_label_make (options), options.label), -- redirect, Wikidata link, or locally specified link (in that order)

options.separator or ' ',

ext_link

});

end

--[[--------------------------< I N T E R N A L _ L I N K _ I D >----------------------------------------------

Formats a wiki-style internal link

TODO: Does not currently need to support options.access, options.encode, auto-linking and COinS (as in external_link_id),

but may be needed in the future for :m:Interwiki_map custom-prefixes like :arxiv:, :bibcode:, :DOI:, :hdl:, :ISSN:,

:JSTOR:, :Openlibrary:, :PMID:, :RFC:.

]]

local function internal_link_id (options)

local id = mw.ustring.gsub (options.id, '%d', cfg.date_names.local_digits); -- translate 'local' digits to Western 0-9

return table.concat (

{

make_wikilink (link_label_make (options), options.label), -- wiki-link the identifier label

options.separator or ' ', -- 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

is the date provided in those |biorxiv= parameter values that are dated and in |medrxiv= parameter values at time 00:00:00 UTC

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:

, , – year, month, day parts of the date from the birxiv or medrxiv identifier