Module:Citation/CS1: திருத்தங்களுக்கு இடையிலான வேறுபாடு
உள்ளடக்கம் நீக்கப்பட்டது உள்ளடக்கம் சேர்க்கப்பட்டது
Fix sandbox oversight; |
Sync from sandbox; Bug fixes; streamlined deprecated parameter detection; Year and PublicationDate promotion to Date consolidation; Change pmc/url handling; Modify parameter handling for cite encyclopedia; |
||
வரிசை 1:
--[[
History of changes since last sync 2013-11-09
2013-11-13: Fix Script Error bug that occured when |doi_brokendate= did not contain a year value;
2013-11-13: Fix doi() so that dois with invalid doi_brokendate categorize to "Pages with inactive DOIs" and not to "Pages with DOIs inactive since";
2013-11-14: Change deprecated_parameter() to emit a single error message;
2013-11-15: Fix bug in checkisbn() that stripped-out non-isbn character before validation; declared good as long as the stripped version of the isbn passed the remaining tests;
2013-11-21: Year and PublicationDate promotion to Date consolidation;
2013-11-22: Change validate() and the whitelist to recognize deprecated parameters;
2013-11-30: Change pmc/url handling;
2013-12-05: Modify |encyclopedia, |title and |article parameter handling for cite encyclopedia;
]]
local z = {
error_categories = {};
வரி 39 ⟶ 52:
end
--[[
Categorize and emit an error message when the citation contains one or more deprecated parameters. Because deprecated parameters (currently |day=, |month=,
|coauthor=, and |coauthors=) aren't related to each other and because these parameters may be concatenated into the variables used by |date= and |author#= (and aliases)
details of which parameter caused the error message are not provided. Only one error message is emitted regarless of the number of deprecated parameters in the citation.
]]
function deprecated_parameter()
if true ~= Page_in_deprecated_cat then -- if we haven't been here before then set a
Page_in_deprecated_cat=true; -- sticky flag so that if there are more than one deprecated parameter the category is added only once
table.insert( z.
end
end
வரி 113 ⟶ 130:
end
--[[
Looks for a parameter's name in the whitelist.
Parameters in the whitelist can have three valuse:
true - active, supported parameters
false - deprecated, supported parameters
nil - unsupported parameters
]]
function validate( name )
local state = whitelist.basic_arguments[ name ];
-- Normal arguments
if true == state
if false == state then
deprecated_parameter (); -- parameter is deprecated but still supported
return true;
end
-- Arguments with numbers in them
name = name:gsub( "%d+", "#" ); -- replace digit(s) with # (last25 becomes last#
state = whitelist.numbered_arguments[ name ];
if true == state
if false == state then
deprecated_parameter (); -- parameter is deprecated but still supported
return true;
end
return false; -- Not supported because not found or name is set to nil
end
வரி 227 ⟶ 256:
--[[
in the future, returns true; otherwse, returns false because the embargo has expired or |embargo= not set in this cite.
]]
function
if is_set(embargo) then
local lang = mw.getContentLanguage();
வரி 245 ⟶ 265:
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 )
return true; -- still embargoed
end
end
return false; -- embargo expired or |embargo= not set
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 future
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'].prefix.
]]
function pmc(id, embargo)
local handler = cfg.id_handlers['PMC'];
local text;
if is_embargoed(embargo) then
text="[[" .. handler.link .. "|" .. handler.label .. "]]:" .. handler.separator .. id; --still embargoed so no external link
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
வரி 265 ⟶ 298:
local text;
local inactive_year = inactive:match("%d%d%d%d") or ''; -- try to get the year portion from the inactive date
text = "[[" .. handler.link .. "|" .. handler.label .. "]]:" .. id;
if is_set(inactive_year) then
table.insert( z.error_categories, "Pages with DOIs inactive since " .. inactive_year );
else
table.insert( z.error_categories, "Pages with inactive DOIs" ); -- when inactive doesn't contain a recognizable year
end
inactive = " (" .. cfg.messages['inactive'] .. " " .. inactive .. ")"
else
text = externallinkid({link = handler.link, label = handler.label,
prefix=handler.prefix,id=id,separator=handler.separator, encode=handler.encode})
end
if ( string.sub(id,1,3) ~= "10." ) then
cat = seterror( 'bad_doi' );
end
return text .. inactive .. cat
end
வரி 344 ⟶ 382:
end
--[[
This function sets default title types (equivalent to the citation including |type=<default value>) for those citations that have defaults.
Also handles the special case where it is desireable to omit the title type from the rendered citation (|type=none).
]]
function set_titletype(cite_class, title_type)
if is_set(title_type) then
if "none" == title_type then
title_type = ""; -- if |type=none then type parameter not displayed
end
return title_type; -- if |type= has been set to any other value use that value
end
if "pressrelease" == cite_class then -- if this citation is cite press release
return "Press release"; -- display press release annotation
elseif "speech" == cite_class then -- if this citation is cite speech
return "Speech"; -- display speech annotation
elseif "techreport" == cite_class then -- if this citation is cite techreport
return "Technical report"; -- display techreport annotation
elseif "thesis" == cite_class then -- if this citation is cite thesis (degree option handled after this function returns)
return "Thesis"; -- display simple thesis annotation (without |degree= modification)
end
end
-- returns a number according to the month in a date: 1 for January, etc. If not a valid month, returns 0
function get_month_number (month)
local long_months = {['january']=1, ['february']=2, ['march']=3, ['april']=4, ['may']=5, ['june']=6, ['july']=7, ['august']=8, ['september']=9, ['october']=10, ['november']=11, ['december']=12};
வரி 350 ⟶ 414:
local temp;
temp=long_months[month:lower()];
if temp then return temp; end -- if month is the long-form name
temp=short_months[month:lower()];
if temp then return temp; end -- if month is the short-form name
return 0;
end
வரி 373 ⟶ 437:
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
local month_length;
if (2==month) then -- if February
month_length = 28; -- then 28 days unless
if 1582 > tonumber(year) then -- Julian calendar
if 0==(year%4) then
month_length = 29;
end
else -- Gregorian calendar
if (0==(year%4) and (0~=(year%100) or 0==(year%400))) then --
month_length = 29; -- if leap year then 29 days in February
end
end
வரி 395 ⟶ 459:
--Check a pair of months or seasons to see if both are valid members of a month or season pair.
--TODO: Check order to make sure that the left month/season properly precedes the right month/season
function is_valid_month_season_range(range_start, range_end)
வரி 408 ⟶ 473:
return true;
end
--[[
வரி 425 ⟶ 489:
true, anchor_year, COinS_date
anchor_year can be used in CITEREF anchors
COinS_date is date_string without anchor_year
]]
function check_date (date_string)
வரி 463 ⟶ 527:
end
elseif date_string:match("^%a+%s*%d%d%d%d%a?$") then
coins_date = date_string:match("%a+%s*%d%d%d%d");
month, anchor_year, year=string.match(date_string, "(%a+)%s*((%d%d%d%d)%a?)");
வரி 510 ⟶ 574:
for k, v in pairs(date_parameters_list) do -- for each date-holding parameter in the list
if is_set(v) then -- if the parameter has a value
if v:match("^c%.%s%d%d%d%d?%a?$") then
if 'date'==k then
good_date, anchor_year, COinS_date = true, v:match("((c%.%s%d%d%d%d?)%a?)"); -- anchor year and COinS_date only from |date= parameter
வரி 520 ⟶ 584:
good_date = true;
end
elseif 'date'==k then
if v:match("n%.d%.%a?") then -- if |date=n.d. with or without a CITEREF disambiguator
good_date, anchor_year, COinS_date = true, v:match("((n%.d%.)%a?)"); --"n.d.";
elseif v:match("nd%a?$") then -- if |date=nd with or without a CITEREF disambiguator
good_date, anchor_year, COinS_date = true, v:match("((nd)%a?)"); --"nd";
else
good_date, anchor_year, COinS_date = check_date (v); -- go test the date
வரி 531 ⟶ 595:
good_date = check_date (v); -- go test the date
end
if false==good_date then -- assemble one error message so we don't add the tracking category multiple times
if is_set(error_message) then -- once we've added the first portion of the error message ...
error_message=error_message .. ", "; -- ... add a comma space separator
வரி 547 ⟶ 611:
--[[
Determines whether
At present the only check is whether the string appears to
வரி 566 ⟶ 630:
--[[
ISBN-10 and ISSN validator code calculates checksum across all isbn/issn digits including the check digit.
If the number is valid the result will be 0. Before calling this function, issbn/issn must be checked for length and stripped of dashes,
spaces and other non-isxn characters.
]]
function is_valid_isxn (isxn_str, len)
வரி 573 ⟶ 638:
isxn_str = { isxn_str:byte(1, len) }; -- make a table of bytes
len = len+1; -- adjust to be a loop counter
for i, v in ipairs( isxn_str ) do
if v == string.byte( "X" ) then -- if checkdigit is X
temp = temp + 10*( len - i ); -- it represents 10 decimal
வரி 585 ⟶ 650:
-- Determines whether an ISBN string is valid
function checkisbn( isbn_str )
if nil ~= isbn_str:match("[^%s-0-9X]") then return false; end -- fail if isbn_str contains anything but digits, hyphens, or the uppercase X
isbn_str = isbn_str:gsub( "-", "" ):gsub( " ", "" ); -- remove hyphens and spaces
local len = isbn_str:len();
return is_valid_isxn(isbn_str, 10);
end
வரி 723 ⟶ 789:
return str;
end
-- Attempts to convert names to initials.
வரி 893 ⟶ 938:
end
function comp( a, b ) -- used in following table.sort()
return a[1] < b[1];
end
வரி 1,043 ⟶ 1,088:
--[[
This is the main function
formatting.
]]
வரி 1,095 ⟶ 1,140:
local ConferenceURLorigin = A:ORIGIN('ConferenceURL');
local Periodical = A['Periodical'];
--[[
Parameter remapping for cite encyclopedia:
When the citation has these parameters:
|encyclopedia and |title then map |title to |article and |encyclopedia to |title
|encyclopedia and |article then map |encyclopedia to |title
|encyclopedia then map |encyclopedia to |title
|trans_title maps to |trans_chapter when |title is re-mapped
All other combinations of |encyclopedia, |title, and |article are not modified
]]
if ( config.CitationClass == "encyclopaedia" ) then
if is_set(Periodical) then -- Periodical is set when |encyclopedia is set
if is_set(Title) then
if not is_set(Chapter) then
Chapter = Title; -- |encyclopedia and |title are set so map |title to |article and |encyclopedia to |title
TransChapter = TransTitle;
Title = Periodical;
Periodical = ''; -- redundant so unset
TransTitle = ''; -- redundant so unset
end
else -- |title not set
Title = Periodical; -- |encyclopedia set and |article set or not set so map |encyclopedia to |title
Periodical = ''; -- redundant so unset
end
end
end
local Series = A['Series'];
local Volume = A['Volume'];
local Issue = A['Issue'];
வரி 1,160 ⟶ 1,219:
local ID = A['ID'];
if (config.CitationClass == "techreport") then -- special case for cite techreport
if is_set(Issue) then -- cite techreport uses 'number', which
if not is_set(ID) then -- can we use ID for the "number"?
ID = Issue; -- yes, use it
வரி 1,201 ⟶ 1,260:
local anchor_year; -- used in the CITEREF identifier
local COinS_date; -- used in the COinS metadata
-- legacy: promote concatenation of |day=, |month=, and |year= to Date if Date not set; or, promote PublicationDate to Date if neither Date nor Year are set.
if not is_set(Date) then
Date = Year; -- promote Year to Date
Year = nil; -- make nil so Year as empty string isn't used for CITEREF
if is_set(Date) then
local Month = A['Month'];
if is_set(Month) then
Date = Month .. " " .. Date;
local Day = A['Day']
if is_set(Day) then Date = Day .. " " .. Date end
end
elseif is_set(PublicationDate) then -- use PublicationDate when |date= and |year= are not set
Date = PublicationDate; -- promonte PublicationDate to Date
PublicationDate = ''; -- unset, no longer needed
end
end
if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation
-- Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates.
வரி 1,207 ⟶ 1,285:
['embargo']=Embargo, ['laydate']=LayDate, ['publicationdate']=PublicationDate, ['year']=Year});
-- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
--Account for the oddity that is {{cite journal}} with |pmc= set and |url= not set
if config.CitationClass == "journal" and not is_set(URL) and is_set(ID_list['PMC']) then
if not is_embargoed(Embargo) then
URL=cfg.id_handlers['PMC'].prefix .. ID_list['PMC']; -- set url to be the same as the PMC external link if not embargoed
end
end
-- Account for the oddity that is {{cite conference}}, before generation of COinS data.
if is_set(BookTitle) then
வரி 1,260 ⟶ 1,339:
['Title'] = Title,
['PublicationPlace'] = PublicationPlace,
['Date'] = first_set(COinS_date, Date), --
['Series'] = Series,
['Volume'] = Volume,
வரி 1,308 ⟶ 1,387:
control.lastauthoramp = nil;
control.maximum = #a + 1;
end
வரி 1,316 ⟶ 1,394:
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
வரி 1,359 ⟶ 1,436:
end
end
if not is_set(URL) and
வரி 1,617 ⟶ 1,672:
-- handle type parameter for those CS1 citations that have default values
if inArray(config.CitationClass, {"pressrelease","techreport","thesis", "speech"}) then
if is_set(Degree) and "Thesis" == TitleType then -- special case for cite thesis
TitleType = Degree .. " thesis";
end
end
if is_set(TitleType) then -- if type parameter is specified
TitleType = " (" .. TitleType .. ")"; -- display it in parentheses
வரி 1,903 ⟶ 1,940:
-- Now enclose the whole thing in a <span/> element
local options = {};
| |||