|
|
Line 1: |
Line 1: |
| if nil_or_not then
| |
| x = nil_or_not.abc -- always OK
| |
| else
| |
| -- do somethink if nil_or_not is nil.
| |
| end
| |
| local z = { | | local z = { |
| error_categories = {}; | | error_categories = {}; |
Line 221: |
Line 216: |
| label=handler.label , prefix="//www.amazon."..domain.."/dp/",id=id, | | label=handler.label , prefix="//www.amazon."..domain.."/dp/",id=id, |
| encode=handler.encode, separator = handler.separator}) | | encode=handler.encode, separator = handler.separator}) |
| end
| |
|
| |
| --[[
| |
| Formats a PMC and checks for embargoed articles. The embargo parameter takes a date for a value. If the embargo date is in the futue
| |
| the PMC identifier will not be linked to the article. If the embargo specifies a date 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'].link.
| |
|
| |
| The {{citation/core}} version of {{cite journal}} links the citation title (if url parameter is empty) when embargo date is in the past
| |
| or when embargo parameter is missing or empty. That behavior is inconsistent with the behavior of other identifiers used in CS1 and is
| |
| not supported here.
| |
| ]]
| |
| function pmc(id, embargo)
| |
| local handler = cfg.id_handlers['PMC'];
| |
|
| |
| local text;
| |
|
| |
| if is_set(embargo) then
| |
| local lang = mw.getContentLanguage();
| |
| local good1, embargo_date, good2, todays_date;
| |
| good1, embargo_date = pcall( lang.formatDate, lang, 'U', embargo );
| |
| good2, todays_date = pcall( lang.formatDate, lang, 'U' );
| |
|
| |
| if good1 and good2 and tonumber( embargo_date ) < tonumber( todays_date ) then --if embargo date is in the past then
| |
| text = externallinkid({link = handler.link, label = handler.label, --ok to link to article
| |
| prefix=handler.prefix,id=id,separator=handler.separator, encode=handler.encode})
| |
| else
| |
| text="[[" .. handler.link .. "|" .. handler.label .. "]]:" .. handler.separator .. id; --still embargoed so no external link
| |
| end
| |
| else
| |
| text = externallinkid({link = handler.link, label = handler.label, --no embargo date, ok to link to article
| |
| prefix=handler.prefix,id=id,separator=handler.separator, encode=handler.encode})
| |
| end
| |
| return text
| |
| end | | end |
|
| |
|
Line 300: |
Line 262: |
| end | | end |
| end | | end |
|
| |
| --[[
| |
| 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: [http://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.
| |
| ]]
| |
| function issn(id)
| |
| local clean_issn;
| |
| local issn_copy = id; -- save a copy of unadulterated issn; use this version for display if issn does not validate
| |
| local handler = cfg.id_handlers['ISSN'];
| |
| local temp = 0;
| |
| local text;
| |
| local valid_issn = true;
| |
|
| |
| id=id:gsub( "[%s-–]", "" ); -- strip spaces, hyphens, and ndashes from the issn
| |
| clean_issn=string.sub( id, 1, 4 ) .. "-" .. string.sub( id, 5 ); -- make a copy with a hyphen after 4 digits; use this version for display if issn validates
| |
|
| |
| if 8 ~= id:len() or nil == id:match( "^%d*X?$" ) then -- validate the issn: 8 didgits long, containing only 0-9 or X in the last position
| |
| valid_issn=false; -- wrong length or improper character
| |
| else
| |
| id = { id:byte(1, 8) }; -- table of individual bytes
| |
| for i, v in ipairs( id ) do -- loop through all of the byte an calculate the checksum
| |
| if v == string.byte( "X" ) then -- if checkdigit is X
| |
| temp = temp + 10*( 9 - i ); -- it represents 10 decimal
| |
| else
| |
| temp = temp + tonumber( string.char(v) )*(9-i);
| |
| end
| |
| end
| |
| valid_issn = temp % 11 == 0; -- checksum must be zero for valid issn
| |
| end
| |
|
| |
| if true == valid_issn then
| |
| id = clean_issn; -- if valid, use the cleaned-up version for the display
| |
| else
| |
| id = issn_copy; -- if not valid, use the show the invalid issn with error message
| |
| end
| |
|
| |
| text = externallinkid({link = handler.link, label = handler.label,
| |
| prefix=handler.prefix,id=id,separator=handler.separator, encode=handler.encode})
| |
|
| |
| if false == valid_issn then
| |
| text = text .. ' ' .. seterror( 'bad_issn' ) -- add an error message if the issn is invalid
| |
| end
| |
|
| |
| return text
| |
| end
| |
|
| |
|
| |
|
| --[[ | | --[[ |
Line 535: |
Line 445: |
| local lang = mw.getContentLanguage(); | | local lang = mw.getContentLanguage(); |
| local good, result; | | local good, result; |
| good, result = pcall( lang.formatDate, lang, 'Y', str ); | | good, result = pcall( lang.formatDate, lang, 'Y', str ) |
| if good then | | if good then |
| return result; | | return result; |
| else | | else |
| -- extract year if the date uses seasons | | -- Can't make sense of this input, return blank. |
| str=string.lower (str);
| | return ""; |
| local seasons={"winter", "spring", "summer", "fall", "autumn"};
| | end |
| local date_string_split=mw.text.split (str, "[%s%-/–]"); -- split date string into parts; white space, hyphen, forward slash, and ndash are allowed separators
| | end |
| local has_season=false;
| | end |
|
| |
| for n,season_value in ipairs(seasons) do -- for each season ...
| |
| for n,split_value in ipairs(date_string_split) do -- ... loop through date string values
| |
| if split_value == season_value then -- does the split value match the season value?
| |
| if has_season==false then -- found one. if this one is the first we've found ...
| |
| has_season=true; -- ... remember that we found a season
| |
| end
| |
| elseif has_season==true then -- if split_value isn't a season, and we've previously found a season ...
| |
| num = tonumber( split_value ); -- ... convert current split value to a number if we can
| |
| if num ~= nil and num > 0 and num < 2100 and num == math.floor(num) then -- if it's a suitable number
| |
| return tostring( num ); -- return it as a string
| |
| end -- if num
| |
| end -- if string.find
| |
| end -- for split value loop
| |
| end -- season value loop
| |
| end -- if good | |
| end -- if num | |
| end -- selectyear | |
|
| |
|
| -- Attempts to convert names to initials. | | -- Attempts to convert names to initials. |
Line 696: |
Line 588: |
| elseif k == 'OL' then | | elseif k == 'OL' then |
| table.insert( new_list, {handler.label, openlibrary( v ) } ); | | table.insert( new_list, {handler.label, openlibrary( v ) } ); |
| elseif k == 'PMC' then
| |
| table.insert( new_list, {handler.label, pmc( v, options.Embargo ) } );
| |
| elseif k == 'ISSN' then
| |
| table.insert( new_list, {handler.label, issn( v ) } );
| |
| elseif k == 'ISBN' then | | elseif k == 'ISBN' then |
| local ISBN = internallinkid( handler ); | | local ISBN = internallinkid( handler ); |
Line 960: |
Line 848: |
| | | |
| local PublisherName = A['PublisherName']; | | local PublisherName = A['PublisherName']; |
| local RegistrationRequired = A['RegistrationRequired'];
| |
| local SubscriptionRequired = A['SubscriptionRequired']; | | local SubscriptionRequired = A['SubscriptionRequired']; |
| local Via = A['Via']; | | local Via = A['Via']; |
Line 975: |
Line 862: |
| local ASINTLD = A['ASINTLD']; | | local ASINTLD = A['ASINTLD']; |
| local IgnoreISBN = A['IgnoreISBN']; | | local IgnoreISBN = A['IgnoreISBN']; |
| local Embargo = A['Embargo'];
| |
|
| |
|
| local ID_list = extractids( args ); | | local ID_list = extractids( args ); |
Line 991: |
Line 877: |
|
| |
|
| local use_lowercase = ( sepc ~= '.' ); | | local use_lowercase = ( sepc ~= '.' ); |
| local this_page = mw.title.getCurrentTitle(); --Also used for COinS and for language | | local this_page = mw.title.getCurrentTitle(); --Also used for COinS |
| | | |
| if not is_set(no_tracking_cats) then | | if not is_set(no_tracking_cats) then |
Line 998: |
Line 884: |
| no_tracking_cats = "true"; | | no_tracking_cats = "true"; |
| break; | | break; |
| | end |
| | end |
| | end |
| | |
| | if ( config.CitationClass == "journal" ) then |
| | if not is_set(URL) and is_set(ID_list['PMC']) then |
| | local Embargo = A['Embargo']; |
| | if is_set(Embargo) then |
| | local lang = mw.getContentLanguage(); |
| | local good1, result1, good2, result2; |
| | good1, result1 = pcall( lang.formatDate, lang, 'U', Embargo ); |
| | good2, result2 = pcall( lang.formatDate, lang, 'U' ); |
| | |
| | if good1 and good2 and tonumber( result1 ) < tonumber( result2 ) then |
| | URL = "http://www.ncbi.nlm.nih.gov/pmc/articles/PMC" .. ID_list['PMC']; |
| | URLorigin = cfg.id_handlers['PMC'].parameters[1]; |
| | end |
| | else |
| | URL = "http://www.ncbi.nlm.nih.gov/pmc/articles/PMC" .. ID_list['PMC']; |
| | URLorigin = cfg.id_handlers['PMC'].parameters[1]; |
| end | | end |
| end | | end |
Line 1,101: |
Line 1,007: |
| Authors = listpeople(control, a) | | Authors = listpeople(control, a) |
| end | | end |
|
| |
| if not is_set(Authors) and is_set(Coauthors) then -- coauthors aren't displayed if one of authors=, authorn=, or lastn= isn't specified
| |
| table.insert( z.message_tail, { seterror('coauthors_missing_author', {}, true) } ); -- emit error message
| |
| end
| |
|
| |
|
| local EditorCount | | local EditorCount |
Line 1,378: |
Line 1,280: |
| At = At .. Section .. Inset; | | At = At .. Section .. Inset; |
| end | | end |
| | | |
| --[[Look in the list of iso639-1 language codes to see if the value provided in the language parameter matches one of them. If a match is found,
| |
| use that value; if not, then use the value that was provided with the language parameter.
| |
|
| |
| Categories are assigned in a manner similar to the {{xx icon}} templates - categorizes only mainspace citations and only when the language code is not 'en' (English).
| |
| ]]
| |
| if is_set (Language) then
| |
| local name = cfg.iso639_1[Language:lower()]; -- get the language name if Language parameter has a valid iso 639-1 code
| |
| if nil == name then
| |
| Language=" " .. wrap( 'language', Language ); -- no match, use parameter's value
| |
| else
| |
| if 0 == this_page.namespace and 'en' ~= Language:lower() then --found a match; is this page main / article space and English not the language?
| |
| Language=" " .. wrap( 'language', name .. '[[Category:Articles with ' .. name .. '-language external links]]' ); -- in main space and not English: categorize
| |
| else
| |
| Language=" " .. wrap( 'language', name ); --not in mainspace or language is English so don't categorize
| |
| end
| |
| end
| |
| else
| |
| Language=""; -- language not specified so make sure this is an empty string;
| |
| end
| |
| | |
| Others = is_set(Others) and (sepc .. " " .. Others) or ""; | | Others = is_set(Others) and (sepc .. " " .. Others) or ""; |
| TitleType = is_set(TitleType) and (" (" .. TitleType .. ")") or ""; | | TitleType = is_set(TitleType) and (" (" .. TitleType .. ")") or ""; |
| TitleNote = is_set(TitleNote) and (sepc .. " " .. TitleNote) or ""; | | TitleNote = is_set(TitleNote) and (sepc .. " " .. TitleNote) or ""; |
| | Language = is_set(Language) and (" " .. wrap( 'language', Language )) or ""; |
| Edition = is_set(Edition) and (" " .. wrap( 'edition', Edition )) or ""; | | Edition = is_set(Edition) and (" " .. wrap( 'edition', Edition )) or ""; |
| Issue = is_set(Issue) and (" (" .. Issue .. ")") or ""; | | Issue = is_set(Issue) and (" (" .. Issue .. ")") or ""; |
Line 1,416: |
Line 1,299: |
| | | |
| ------------------------------------ totally unrelated data | | ------------------------------------ totally unrelated data |
| --[[ Loosely mimic {{subscription required}} template; Via parameter identifies a delivery source that is not the publisher; these sources often, but not always, exist | | -- Mimic {{subscription required}} template; |
| behind a registration or paywall. So here, we've chosen to decouple via from subscription (via has never been part of the registration required template).
| |
|
| |
| Subscription implies paywall; Registration does not. If both are used in a citation, the subscription required link note is displayed. There are no error messages for this condition.
| |
| ]]
| |
| if is_set(Via) then | | if is_set(Via) then |
| Via = " " .. wrap( 'via', Via ); | | Via = " " .. wrap( 'via', Via ); |
| end
| | SubscriptionRequired = sepc .. " " .. cfg.messages['subscription']; --citation always requires subscription if 'via' parameter is used |
| | | elseif is_set(SubscriptionRequired) then |
| if is_set(SubscriptionRequired) then
| | SubscriptionRequired = sepc .. " " .. cfg.messages['subscription_no_via']; --here when 'via' parameter not used but 'subscription' is |
| SubscriptionRequired = sepc .. " " .. cfg.messages['subscription']; --here when 'via' parameter not used but 'subscription' is | |
| elseif is_set(RegistrationRequired) then | |
| SubscriptionRequired = sepc .. " " .. cfg.messages['registration']; --here when 'via' and 'subscription' parameters not used but 'registration' is | |
| end | | end |
|
| |
|
Line 1,440: |
Line 1,316: |
| if is_set(ID) then ID = sepc .." ".. ID; end | | if is_set(ID) then ID = sepc .." ".. ID; end |
| | | |
| ID_list = buildidlist( ID_list, {DoiBroken = DoiBroken, ASINTLD = ASINTLD, IgnoreISBN = IgnoreISBN, Embargo=Embargo} ); | | ID_list = buildidlist( ID_list, {DoiBroken = DoiBroken, ASINTLD = ASINTLD, IgnoreISBN = IgnoreISBN} ); |
|
| |
|
| if is_set(URL) then | | if is_set(URL) then |