fbpx
Wikipedia

Módulo:Citas

Documentación del módulo[ver] [editar] [historial] [purgar]

A continuación se muestra la documentación transcluida desde la subpágina /doc. [salta a la caja de código]


Uso

Este módulo permite generar citas de libros, noticias, notas de álbumes y DVD, etc.

Módulos auxiliares
Funciones

Esta documentación está transcluida desde Módulo:Citas/doc.
Por favor, añade las categorías en la subpágina de documentación y los interwikis en Wikidata. Subpáginas de este módulo.
local z = {  error_categories = {};  error_ids = {};  message_tail = {}; } -- Include translation message hooks, ID and error handling configuration settings. --local cfg = mw.loadData( 'Mdódulo:Citas/Configuración/pruebas' );  -- Contains a list of all recognized parameters --local whitelist = mw.loadData( 'Módulo:Citas/Whitelist/pruebas' ); --local dates = require('Módulo:Citas/ValidaciónFechas/pruebas').dates -- location of date validation code  --Módulo para formatear las fechas local DateModule = require('Módulo:Date')._Date  -- Whether variable is set or not function is_set( var )  return not (var == nil or var == ''); end  -- First set variable or nil if none function first_set(...)  local list = {...};  for _, var in pairs(list) do  if is_set( var ) then  return var;  end  end end  -- Whether needle is in haystack function inArray( needle, haystack )  if needle == nil then  return false;  end  for n,v in ipairs( haystack ) do  if v == needle then  return n;  end  end  return false; end  --[[ Formatea una fecha para que se devuelva de la siguiente forma: "1 de enero de 2020" Formats a date so it is returned as follows: "1 de enero de 2020" ]]  function format_date(date_string)  function dateFormatter(text)  return DateModule(text):text('%-d de %B de %-Y')  end   local stat, res = pcall(dateFormatter, date_string)   if stat then  return res  else  return date_string  end 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( name ) -- table.insert( z.message_tail, { seterror( 'deprecated_params', {error_message}, true ) } ); -- add error message  table.insert( z.message_tail, { seterror( 'deprecated_params', { name }, true ) } ); -- add error message end  -- Populates numbered arguments in a message string using an argument table. function substitute( msg, args ) -- return args and tostring( mw.message.newRawMessage( msg, args ) ) or msg;  return args and mw.message.newRawMessage( msg, args ):plain() or msg; end  --[[ Apply kerning to open the space between the quote mark provided by the Module and a leading or trailing quote mark contained in a |title= or |chapter= parameter's value. This function will positive kern either single or double quotes:  "'Unkerned title with leading and trailing single quote marks'"  " 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example) ]] function kern_quotes (str)  local left='<span style="padding-left:0.2em;">%1</span>'; -- spacing to use when title contains leading single or double quote mark  local right='<span style="padding-right:0.2em;">%1</span>'; -- spacing to use when title contains trailing single or double quote mark   if str:match ("^[\"\'][^\']") then  str = string.gsub( str, "^[\"\']", left, 1 ); -- replace (captured) leading single or double quote with left-side <span>  end  if str:match ("[^\'][\"\']$") then  str = string.gsub( str, "[\"\']$", right, 1 ); -- replace (captured) trailing single or double quote with right-side <span>  end  return str; end  -- Wraps a string using a message_list configuration taking one argument function wrap( key, str, lower )  if not is_set( str ) then  return "";  elseif inArray( key, { 'italic-title', 'trans-italic-title' } ) then  str = safeforitalics( str );  end  if lower == true then  return substitute( cfg.messages[key]:lower(), {str} );  else  return substitute( cfg.messages[key], {str} );  end end  --[[ Argument wrapper. This function provides support for argument  mapping defined in the configuration file so that multiple names can be transparently aliased to single internal variable. ]] function argument_wrapper( args )  local origin = {};   return setmetatable({  ORIGIN = function( self, k )  local dummy = self[k]; --force the variable to be loaded.  return origin[k];  end  },  {  __index = function ( tbl, k )  if origin[k] ~= nil then  return nil;  end   local args, list, v = args, cfg.aliases[k];   if type( list ) == 'table' then  v, origin[k] = selectone( args, list, 'redundant_parameters' );  if origin[k] == nil then  origin[k] = ''; -- Empty string, not nil  end  elseif list ~= nil then  v, origin[k] = args[list], list;  else  -- maybe let through instead of raising an error?  -- v, origin[k] = args[k], k;  error( cfg.messages['unknown_argument_map'] );  end   -- Empty strings, not nil;  if v == nil then  v = cfg.defaults[k] or '';  origin[k] = '';  end   tbl = rawset( tbl, k, v );  return v;  end,  }); end  --[[ Looks for a parameter's name in the whitelist.  Parameters in the whitelist can have three values:  true - active, supported parameters  false - deprecated, supported parameters  nil - unsupported parameters ]] function validate( name )  local name = tostring( name );  local state = whitelist.basic_arguments[ name ];   -- Normal arguments  if true == state then return true; end -- valid actively supported parameter  if false == state then  deprecated_parameter ( name ); -- 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 then return true; end -- valid actively supported parameter  if false == state then  deprecated_parameter ( name ); -- parameter is deprecated but still supported  return true;  end   return false; -- Not supported because not found or name is set to nil end  -- Formats a comment for error trapping function errorcomment( content, hidden )  return wrap( hidden and 'hidden-error' or 'visible-error', content ); end  --[[ Sets an error condition and returns the appropriate error message. The actual placement of the error message in the output is the responsibility of the calling function. ]] function seterror( error_id, arguments, raw, prefix, suffix )  local error_state = cfg.error_conditions[ error_id ];   prefix = prefix or "";  suffix = suffix or "";   if error_state == nil then  error( cfg.messages['undefined_error'] );  elseif is_set( error_state.category ) then  table.insert( z.error_categories, error_state.category );  end   local message = substitute( error_state.message, arguments );   message = message .. " ([[" .. cfg.messages['help page link'] ..  "#" .. error_state.anchor .. "|" ..  cfg.messages['help page label'] .. "]])";   z.error_ids[ error_id ] = true;  if inArray( error_id, { 'bare_url_missing_title', 'trans_missing_title' } )  and z.error_ids['citation_missing_title'] then  return '', false;  end   message = table.concat({ prefix, message, suffix });   if raw == true then  return message, error_state.hidden;  end   return errorcomment( message, error_state.hidden ); end  -- Formats a wiki style external link function externallinkid(options)  local url_string = options.id;  if options.encode == true or options.encode == nil then  url_string = mw.uri.encode( url_string );  end  return wrap( 'id', internallink(options.link, options.label) ..  (options.separator or "&nbsp;") .. mw.ustring.format( '[%s%s%s %s]',  options.prefix, url_string, options.suffix or "",  mw.text.nowiki(options.id)  )); end  -- Formats a wiki style internal link function internallinkid(options)  return wrap( 'id', internallink(options.link, options.label) ..  (options.separator or "&nbsp;") .. mw.ustring.format( '[[%s%s%s|%s]]',  options.prefix, options.id, options.suffix or "",  mw.text.nowiki(options.id)  )); end  -- Format an internal link, if link is really set function internallink( link, label )  if link and link ~= '' then  return mw.ustring.format( '[[%s|%s]]', link, label )  else  return label  end end  -- Format an external link with error checking function externallink( URL, label, source )  local error_str = "";  if not is_set( label ) then  label = URL;  if is_set( source ) then  error_str = seterror( 'bare_url_missing_title', { wrap( 'parameter', source ) }, false, " " );  else  error( cfg.messages["bare_url_no_origin"] );  end  end  if not checkurl( URL ) then  error_str = seterror( 'bad_url', {}, false, " " ) .. error_str;  elseif mw.title.getCurrentTitle():inNamespaces(0, 100, 104) and  not mw.title.getCurrentTitle().text:match('Wikipedia') and  URL:match('//[%a%.%-]+%.wikipedia%.org') then  error_str = seterror( 'bad_url_autorreferencia', {}, false, " " ) .. error_str;  end  return table.concat({ "[", URL, " ", safeforurl( label ), "]", error_str }); end --[[--------------------------< N O R M A L I Z E _ L C C N >--------------------------------------------------  lccn normalization (http://www.loc.gov/marc/lccn-namespace.html#normalization) 1. Remove all blanks. 2. If there is a forward slash (/) in the string, remove it, and remove all characters to the right of the forward slash. 3. If there is a hyphen in the string:  a. Remove it.  b. Inspect the substring following (to the right of) the (removed) hyphen. Then (and assuming that steps 1 and 2 have been carried out):  1. All these characters should be digits, and there should be six or less. (not done in this function)  2. If the length of the substring is less than 6, left-fill the substring with zeroes until the length is six.  Returns a normalized lccn for lccn() to validate. There is no error checking (step 3.b.1) performed in this function. ]]  local function normalize_lccn (lccn)  lccn = lccn:gsub ("%s", ""); -- 1. strip whitespace   if nil ~= string.find (lccn,'/') then  lccn = lccn:match ("(.-)/"); -- 2. remove forward slash and all character to the right of it  end   local prefix  local suffix  prefix, suffix = lccn:match ("(.+)%-(.+)"); -- 3.a remove hyphen by splitting the string into prefix and suffix   if nil ~= suffix then -- if there was a hyphen  suffix=string.rep("0", 6-string.len (suffix)) .. suffix; -- 3.b.2 left fill the suffix with 0s if suffix length less than 6  lccn=prefix..suffix; -- reassemble the lccn  end   return lccn;  end --[[ Format LCCN link and do simple error checking. LCCN is a character string 8-12 characters long. The length of the LCCN dictates the character type of the first 1-3 characters; the rightmost eight are always digits. http://info-uri.info/registry/OAIHandler?verb=GetRecord&metadataPrefix=reg&identifier=info:lccn/  length = 8 then all digits length = 9 then lccn[1] is alpha length = 10 then lccn[1] and lccn[2] are both alpha or both digits length = 11 then lccn[1] is alpha, lccn[2] and lccn[3] are both alpha or both digits length = 12 then lccn[1] and lccn[2] are both alpha  ]] function lccn(id)  local handler = cfg.id_handlers['LCCN'];  local err_cat = ''; -- presume that LCCN is valid   id = normalize_lccn (id);   local len = id:len(); -- get the length of the lccn   if 8 == len then  if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits)  err_cat = ' ' .. seterror( 'bad_lccn' ); -- set an error message  end  elseif 9 == len then -- LCCN should be adddddddd  if nil == id:match("%a%d%d%d%d%d%d%d%d") then -- does it match our pattern?  err_cat = ' ' .. seterror( 'bad_lccn' ); -- set an error message  end  elseif 10 == len then -- LCCN should be aadddddddd or dddddddddd  if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits) ...  if nil == id:match("^%a%a%d%d%d%d%d%d%d%d") then -- ... see if it matches our pattern  err_cat = ' ' .. seterror( 'bad_lccn' ); -- no match, set an error message  end  end  elseif 11 == len then -- LCCN should be aaadddddddd or adddddddddd  if not (id:match("^%a%a%a%d%d%d%d%d%d%d%d") or id:match("^%a%d%d%d%d%d%d%d%d%d%d")) then -- see if it matches one of our patterns  err_cat = ' ' .. seterror( 'bad_lccn' ); -- no match, set an error message  end  elseif 12 == len then -- LCCN should be aadddddddddd  if not id:match("^%a%a%d%d%d%d%d%d%d%d%d%d") then -- see if it matches our pattern  err_cat = ' ' .. seterror( 'bad_lccn' ); -- no match, set an error message  end  else  err_cat = ' ' .. seterror( 'bad_lccn' ); -- wrong length, set an error message  end   return externallinkid({link = handler.link, label = handler.label,  prefix=handler.prefix,id=id,separator=handler.separator, encode=handler.encode}) .. err_cat; end  --[[ Format PMID and do simple error checking. PMIDs are sequential numbers beginning at 1 and counting up. This code checks the PMID to see that it contains only digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically as more PMIDs are issued. ]] function pmid(id)  local test_limit = 36000000; -- update this value as PMIDs approach  local handler = cfg.id_handlers['PMID'];  local err_cat = ''; -- presume that PMID is valid   if id:match("[^%d]") then -- if PMID has anything but digits  err_cat = ' ' .. seterror( 'bad_pmid' ); -- set an error message  else -- PMID is only digits  local id_num = tonumber(id); -- convert id to a number for range testing  if 1 > id_num or test_limit < id_num then -- if PMID is outside test limit boundaries  err_cat = ' ' .. seterror( 'bad_pmid' ); -- set an error message  end  end   return externallinkid({link = handler.link, label = handler.label,  prefix=handler.prefix,id=id,separator=handler.separator, encode=handler.encode}) .. err_cat; end  --[[ Determines if a PMC identifier's online version is embargoed. Compares the date in |embargo= against today's date. If embargo date is in the future, returns true; otherwse, returns false because the embargo has expired or |embargo= not set in this cite. ]] function is_embargoed(embargo)  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 --is embargo date is in the future?  return true; -- still embargoed  end  end  return false; -- embargo expired or |embargo= not set end  --[[ Format a PMC, do simple error checking, and check 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.  PMCs are sequential numbers beginning at 1 and counting up. This code checks the PMC to see that it contains only digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically as more PMCs are issued. ]] function pmc(id, embargo)  local test_limit = 10000000; -- update this value as PMCs approach  local handler = cfg.id_handlers['PMC'];  local err_cat = ''; -- presume that PMC is valid   local text;   if id:match("[^%d]") then -- if PMC has anything but digits  err_cat = ' ' .. seterror( 'bad_pmc' ); -- set an error message  else -- PMC is only digits  local id_num = tonumber(id); -- convert id to a number for range testing  if 1 > id_num or test_limit < id_num then -- if PMC is outside test limit boundaries  err_cat = ' ' .. seterror( 'bad_pmc' ); -- set an error message  end  end   if is_embargoed(embargo) then  text="[[" .. handler.link .. "|" .. handler.label .. "]]:" .. handler.separator .. id .. err_cat; --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}) .. err_cat;  end  return text; end  -- Formats a DOI and checks for DOI errors.  -- DOI names contain two parts: prefix and suffix separated by a forward slash. -- Prefix: directory indicator '10.' followed by a registrant code -- Suffix: character string of any length chosen by the registrant  -- This function checks a DOI name for: prefix/suffix. If the doi name contains spaces or endashes, -- or, if it ends with a period or a comma, this function will emit a bad_doi error message.  -- DOI names are case-insensitive and can incorporate any printable Unicode characters so the test for spaces, endash, -- and terminal punctuation may not be technically correct but it appears, that in practice these characters are rarely if ever used in doi names.  function doi(id, inactive)  local cat = ""  local handler = cfg.id_handlers['DOI'];   local text;  if is_set(inactive) then  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, "Wikipedia:Páginas con DOI inactivos desde " .. inactive_year );  else  table.insert( z.error_categories, "Wikipedia:Páginas con DOI inactivos" ); -- 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})  inactive = ""  end   if nil == id:match("^10%.[^%s–]-/[^%s–]-[^%.,]$") then -- doi must begin with '10.', must contain a fwd slash, must not contain spaces or endashes, and must not end with period or comma  cat = ' ' .. seterror( 'bad_doi' );  end  return text .. inactive .. cat end  -- Formats an OpenLibrary link, and checks for associated errors. function openlibrary(id)  local code = id:sub(-1,-1)  local handler = cfg.id_handlers['OL'];  if ( code == "A" ) then  return externallinkid({link=handler.link, label=handler.label,  prefix="http://openlibrary.org/authors/OL",id=id, separator=handler.separator,  encode = handler.encode})  elseif ( code == "M" ) then  return externallinkid({link=handler.link, label=handler.label,  prefix="http://openlibrary.org/books/OL",id=id, separator=handler.separator,  encode = handler.encode})  elseif ( code == "W" ) then  return externallinkid({link=handler.link, label=handler.label,  prefix= "http://openlibrary.org/works/OL",id=id, separator=handler.separator,  encode = handler.encode})  else  return externallinkid({link=handler.link, label=handler.label,  prefix= "http://openlibrary.org/OL",id=id, separator=handler.separator,  encode = handler.encode}) ..  ' ' .. seterror( 'bad_ol' );  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 ModuloIdentificadores = require('Módulo:Identificadores')  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 text;  local valid_issn = true;   id=id:gsub( "[%s-–]", "" ); -- strip spaces, hyphens, and ndashes from the issn   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  valid_issn=ModuloIdentificadores.esValidoISXN(id, 8); -- validate issn  end   if true == valid_issn then  id = string.sub( id, 1, 4 ) .. "-" .. string.sub( id, 5 ); -- if valid, display correctly formatted version  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  --[[ 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 "AV media notes" == cite_class or "DVD notes" == cite_class then -- if this citation is cite AV media notes or cite DVD notes  if "notas audiovisual" == cite_class or "notas de DVD" == cite_class then -- if this citation is cite AV media notes or cite DVD notes   return "Media notes"; -- display AV media notes / DVD media notes annotation -- Falta traducir   elseif "podcast" == cite_class then -- if this citation is cite podcast  return "Podcast"; -- display podcast annotation   elseif "pressrelease" == cite_class then -- if this citation is cite press release  return "Press release"; -- display press release annotation   elseif "techreport" == cite_class then -- if this citation is cite techreport  return "Technical report"; -- display techreport annotation   elseif "tesis" == cite_class then -- if this citation is cite thesis (degree option handled after this function returns)  return "Tesis"; -- display simple thesis annotation (without |degree= modification)   end end  --[[ Determines whether a URL string is valid  At present the only check is whether the string appears to  be prefixed with a URI scheme. It is not determined whether  the URI scheme is valid or whether the URL is otherwise well  formed. ]] function checkurl( url_str )  -- Protocol-relative or URL scheme  return url_str:sub(1,2) == "//" or url_str:match( "^[^/]*:" ) ~= nil; end  -- Removes irrelevant text and dashes from ISBN number -- Similar to that used for Special:BookSources function cleanisbn( isbn_str )  return isbn_str:gsub( "[^-0-9X]", "" ); end  -- Extract page numbers from external wikilinks in any of the |page=, |pages=, or |at= parameters for use in COinS. function get_coins_pages (pages)  if not is_set (pages) then return pages; end -- if no page numbers then we're done   while true do  pattern = pages:match("%[([%w/:\.]+%s+)[%w%d].*%]"); -- pattern is the opening bracket, the url and following space(s): "[url "  if nil == pattern then break; end -- no more urls  pages = pages:gsub(pattern, ""); -- remove as many instances of pattern as possible  end  pages = pages:gsub("[%[%]]", ""); -- remove the brackets  pages = pages:gsub("–", "-" ); -- replace endashes with hyphens  pages = pages:gsub("&%w+;", "-" ); -- and replace html entities (&ndash; etc) with hyphens; do we need to replace numerical entities like &#32; and the like?  return pages; end  -- Gets the display text for a wikilink like [[A|B]] or [[B]] gives B function removewikilink( str )  return (str:gsub( "%[%[([^%[%]]*)%]%]", function(l)  return l:gsub( "^[^|]*|(.*)$", "%1" ):gsub("^%s*(.-)%s*$", "%1");  end)); end  -- Escape sequences for content that will be used for URL descriptions function safeforurl( str )  if str:match( "%[%[.-%]%]" ) ~= nil then  table.insert( z.message_tail, { seterror( 'wikilink_in_url', {}, true ) } );  end   return str:gsub( '[%[%]\n]', {  ['['] = '&#91;',  [']'] = '&#93;',  ['\n'] = ' ' } ); end  -- Convierte un guión largo (signo de negativo) en un guión corto. function dashtohyphen( str )  if not is_set(str) or str:match( "[%[%]{}<>]" ) ~= nil then  return str;  end  return str:gsub( '–', '-' ); end  -- Protects a string that will be wrapped in wiki italic markup '' ... '' function safeforitalics( str )  --[[ Note: We can not use <i> for italics, as the expected behavior for  italics specified by ''...'' in the title is that they will be inverted  (i.e. unitalicized) in the resulting references. In addition, <i> and ''  tend to interact poorly under Mediawiki's HTML tidy. ]]   if not is_set(str) then  return str;  else  if str:sub(1,1) == "'" then str = "<span></span>" .. str; end  if str:sub(-1,-1) == "'" then str = str .. "<span></span>"; end   -- Remove newlines as they break italics.  return str:gsub( '\n', ' ' );  end end  --[[ Joins a sequence of strings together while checking for duplicate separation characters. ]] function safejoin( tbl, duplicate_char )  --[[  Note: we use string functions here, rather than ustring functions.    This has considerably faster performance and should work correctly as   long as the duplicate_char is strict ASCII. The strings  in tbl may be ASCII or UTF8.  ]]   local str = '';  local comp = '';  local end_chr = '';  local trim;  for _, value in ipairs( tbl ) do  if value == nil then value = ''; end   if str == '' then  str = value;  elseif value ~= '' then  if value:sub(1,1) == '<' then  -- Special case of values enclosed in spans and other markup.  comp = value:gsub( "%b<>", "" );  else  comp = value;  end   if comp:sub(1,1) == duplicate_char then  trim = false;  end_chr = str:sub(-1,-1);  -- str = str .. "<HERE(enchr=" .. end_chr.. ")"  if end_chr == duplicate_char then  str = str:sub(1,-2);  elseif end_chr == "'" then  if str:sub(-3,-1) == duplicate_char .. "''" then  str = str:sub(1, -4) .. "''";  elseif str:sub(-5,-1) == duplicate_char .. "]]''" then  trim = true;  elseif str:sub(-4,-1) == duplicate_char .. "]''" then  trim = true;  end  elseif end_chr == "]" then  if str:sub(-3,-1) == duplicate_char .. "]]" then  trim = true;  elseif str:sub(-2,-1) == duplicate_char .. "]" then  trim = true;  end  elseif end_chr == " " then  if str:sub(-2,-1) == duplicate_char .. " " then  str = str:sub(1,-3);  end  end   if trim then  if value ~= comp then  local dup2 = duplicate_char;  if dup2:match( "%A" ) then dup2 = "%" .. dup2; end   value = value:gsub( "(%b<>)" .. dup2, "%1", 1 )  else  value = value:sub( 2, -1 );  end  end  end  str = str .. value;  end  end  return str; end  -- Attempts to convert names to initials. function reducetoinitials(first)  local initials = {}  for word in string.gmatch(first, "%S+") do  table.insert(initials, string.sub(word,1,1)) -- Vancouver format does not include full stops.  end  return table.concat(initials) -- Vancouver format does not include spaces. end  -- Formats a list of people (e.g. authors / editors)  function listpeople(control, people)  local sep = control.sep;  local namesep = control.namesep  local format = control.format  local maximum = control.maximum  local lastauthoramp = control.lastauthoramp;  local text = {}  local etal = false;   if sep:sub(-1,-1) ~= " " then sep = sep .. " " end  if maximum ~= nil and maximum < 1 then return "", 0; end   for i,person in ipairs(people) do  if is_set(person.last) then  local mask = person.mask  local one  local sep_one = sep;  if maximum ~= nil and i > maximum then  etal = true;  break;  elseif (mask ~= nil) then  local n = tonumber(mask)  if (n ~= nil) then  one = string.rep("&mdash;",n)  else  one = mask;  sep_one = " ";  end  else  one = person.last  local first = person.first  if is_set(first) then  if ( "vanc" == format ) then first = reducetoinitials(first) end  one = one .. namesep .. first  end  if is_set(person.link) then one = "[[" .. person.link .. "|" .. one .. "]]" end  if is_set(person.link) and nil ~= person.link:find("//") then one = one .. " " .. seterror( 'bad_authorlink' ) end -- check for url in author link;  end  table.insert( text, one )  table.insert( text, sep_one )  end  end   local count = #text / 2;  if count > 0 then  if count > 1 and is_set(lastauthoramp) and not etal then  text[#text-2] = " & ";  end  text[#text] = nil;  end   local result = table.concat(text) -- construct list  if etal then  local etal_text = cfg.messages['et al'];  result = result .. " " .. etal_text;  end   -- if necessary wrap result in <span> tag to format in Small Caps  if ( "scap" == format ) then result =  '<span class="smallcaps" style="font-variant:small-caps">' .. result .. '</span>';  end  return result, count end  -- Generates a CITEREF anchor ID. function anchorid( options )  return "CITAREF" .. table.concat( options ); --return "CITEREF" .. table.concat( options ); end  -- Gets name list from the input arguments function extractnames(args, list_name)  local names = {};  local i = 1;  local last;   while true do  last = selectone( args, cfg.aliases[list_name .. '-Last'], 'redundant_parameters', i );  if not is_set(last) then  -- just in case someone passed in an empty parameter  break;  end  names[i] = {  last = last,  first = selectone( args, cfg.aliases[list_name .. '-First'], 'redundant_parameters', i ),  link = selectone( args, cfg.aliases[list_name .. '-Link'], 'redundant_parameters', i ),  mask = selectone( args, cfg.aliases[list_name .. '-Mask'], 'redundant_parameters', i )  };  i = i + 1;  end  return names; end  -- Populates ID table from arguments using configuration settings function extractids( args )  local id_list = {};  for k, v in pairs( cfg.id_handlers ) do  v = selectone( args, v.parameters, 'redundant_parameters' );  if is_set(v) then id_list[k] = v; end  end  return id_list; end  -- Takes a table of IDs and turns it into a table of formatted ID outputs. function buildidlist( id_list, options )  local new_list, handler = {};   function fallback(k) return { __index = function(t,i) return cfg.id_handlers[k][i] end } end;   for k, v in pairs( id_list ) do  -- fallback to read-only cfg  handler = setmetatable( { ['id'] = v }, fallback(k) );   if handler.mode == 'external' then  table.insert( new_list, {handler.label, externallinkid( handler ) } );  elseif handler.mode == 'internal' then  table.insert( new_list, {handler.label, internallinkid( handler ) } );  elseif handler.mode ~= 'manual' then  error( cfg.messages['unknown_ID_mode'] );  elseif k == 'DOI' then  table.insert( new_list, {handler.label, doi( v, options.DoiBroken ) } );  elseif k == 'LCCN' then  table.insert( new_list, {handler.label, lccn( v ) } );  elseif k == 'OL' then  table.insert( new_list, {handler.label, openlibrary( v ) } );  elseif k == 'PMC' then  table.insert( new_list, {handler.label, pmc( v, options.Embargo ) } );  elseif k == 'PMID' then  table.insert( new_list, {handler.label, pmid( v ) } );  elseif k == 'ISSN' then  table.insert( new_list, {handler.label, issn( v:upper() ) } );  elseif k == 'ISBN' then  --local ISBN = internallinkid( handler );  --if not checkisbn( v ) and not is_set(options.IgnoreISBN) then  -- ISBN = ISBN .. seterror( 'bad_isbn', {}, false, " ", "" );  --end   local ISBN  if options.ISBNCorrecto or options.ISBNSugerido or is_set(options.IgnoreISBN) then  ISBN = internallinkid( handler );  else -- ISBN incorrecto.  ISBN = internallinkid( handler ) .. seterror( 'bad_isbn', {}, false, " ", "" );  end   table.insert( new_list, {handler.label, ISBN } );  else  error( cfg.messages['unknown_manual_ID'] );  end  end   function comp( a, b ) -- used in following table.sort()  return a[1] < b[1];  end   table.sort( new_list, comp );  for k, v in ipairs( new_list ) do  new_list[k] = v[2];  end   return new_list; end  function CorregirISBN(ISBNIncorrecto)  local ModuloIdentificadores = require('Módulo:Identificadores')  local ISBNCorregido  -- Convertir mayúsculas   ISBNCorregido = ISBNIncorrecto:upper()  -- Corregir guiones  ISBNCorregido = ISBNCorregido:gsub("%–","-");  -- Eliminar ISBN del principio  ISBNCorregido =ISBNCorregido:match("ISBN (.*)") or ISBNCorregido;  -- Eliminar separadores como "." y "," del final  ISBNCorregido = ISBNCorregido:gsub("[%.,]","");   if ModuloIdentificadores.esValidoISBN(ISBNCorregido) then  return ISBNCorregido  end  -- Ver si se trata de un ISBN de 13   local ISBNCorregidoSin978  ISBNCorregidoSin978 = ISBNCorregido:match("^978[%s-]*(.*)")  if ISBNCorregidoSin978 and ModuloIdentificadores.esValidoISBN(ISBNCorregidoSin978) then -- "978" + ISBN10  return ISBNCorregidoSin978  end  -- ISBN de 13 al que se ha quitado 978   if ModuloIdentificadores.esValidoISBN('978'..ISBNCorregido) then  if ISBNCorregido:match('-') then  return '978-' .. ISBNCorregido  elseif ISBNCorregido:match(' ') then  return '978 ' .. ISBNCorregido  else  return '978' .. ISBNCorregido  end  end  -- 13 ISBN o 13: ISBN  local ISBNCorregidoSi13  ISBNCorregidoSin13 = ISBNCorregido:match("^13:?[%s]+(.*)")  if ISBNCorregidoSin13 and ModuloIdentificadores.esValidoISBN(ISBNCorregidoSin13) then  return ISBNCorregidoSin13  end end  function CorregirISBNs(ISBNIncorrecto1, ISBNIncorrecto2) -- Tomar aquel de los dos ISBNs correctos si uno de ellos es un ISBN10 y el -- otro el correspondiente ISBN13   local ISBN1Corregido = CorregirISBN(ISBNIncorrecto1)  local ISBN2Corregido = CorregirISBN(ISBNIncorrecto2)   if ISBN1Corregido and ISBN2Corregido then -- Ambos son correctos.  if ISBN1Corregido == ISBN2Corregido then -- Ambos son iguales (tras corregirse)  return ISBN1Corregido  end  -- Ver si uno de ellos es un ISBN10 y el otro un ISBN13   local ISBNSinDigitoControl  ISBNSinDigitoControl = ISBN1Corregido:match("(.*).")  if ISBNSinDigitoControl and ISBN2Corregido:match("978[%s-]*" .. ISBNSinDigitoControl) then  return ISBN2Corregido  end   ISBNSinDigitoControl = ISBN2Corregido:match("(.*).")  if ISBNSinDigitoControl and ISBN1Corregido:match("978[%s-]*" .. ISBNSinDigitoControl) then  return ISBN1Corregido  end   elseif ISBN1Corregido then  return ISBN1Corregido  elseif ISBN2Corregido then  return ISBN1Corregido  end end  function SugerirISBN(ISBNIncorrecto)  local ISBNSugerido  -- Ejemplos:  -- 0 88254 165 x --> 0 88254 165 X -- 0-7153-5734-4. --> 0-7153-5734-4 -- 0–313–31807–7 --> 0-313-31807-7 -- ISBN(13): 9788495379092  -- 978-0-7432-9302-0 y 0-7432-9302-0 -- 9788430948949 8430948945  -- 8496702057 9788496702059 -- 0198152213, 978019815221 -- 13 978-0-511-41399-5  -- 13: 9788432238406  -- ISBN con caracteres incorrectos.  ISBNSugerido=CorregirISBN(ISBNIncorrecto)  if ISBNSugerido then  return ISBNSugerido  end  -- ISBN10, ISBN13 o ISBN13, ISBN10  local ISBN1, ISBN2  ISBN1, ISBN2 = ISBNIncorrecto:match("(.*),%s*(.*)")  if is_set(ISBN1) and is_set(ISBN2) then  ISBNSugerido = CorregirISBNs(ISBN1, ISBN2)   if ISBNSugerido then  return ISBNSugerido  end  end  -- ISBN10 y ISBN13 o ISBN13 y ISBN10  ISBN1, ISBN2 = ISBNIncorrecto:match("(.*)%s+y%s+(.*)")  if is_set(ISBN1) and is_set(ISBN2) then  ISBNSugerido = CorregirISBNs(ISBN1, ISBN2)   if ISBNSugerido then  return ISBNSugerido  end  end  -- ISBN10 ISBN13 o ISBN13 ISBN10  ISBN1, ISBN2 = ISBNIncorrecto:match("(.*)%s+(.*)")  if is_set(ISBN1) and is_set(ISBN2) then  ISBNSugerido = CorregirISBNs(ISBN1, ISBN2)   if ISBNSugerido then  return ISBNSugerido  end  end end  -- Chooses one matching parameter from a list of parameters to consider -- Generates an error if more than one match is present. function selectone( args, possible, error_condition, index )  local value = nil;  local selected = '';  local error_list = {};   if index ~= nil then index = tostring(index); end   -- Handle special case of "#" replaced by empty string  if index == '1' then  for _, v in ipairs( possible ) do  v = v:gsub( "#", "" );  if is_set(args[v]) then  if value ~= nil and selected ~= v then  table.insert( error_list, v );  else  value = args[v];  selected = v;  end  end  end  end   for _, v in ipairs( possible ) do  if index ~= nil then  v = v:gsub( "#", index );  end  if is_set(args[v]) then  if value ~= nil and selected ~= v then  table.insert( error_list, v );  else  value = args[v];  selected = v;  end  end  end   if #error_list > 0 then  local error_str = "";  for _, k in ipairs( error_list ) do  if error_str ~= "" then error_str = error_str .. cfg.messages['parameter-separator'] end  error_str = error_str .. wrap( 'parameter', k );  end  if #error_list > 1 then  error_str = error_str .. cfg.messages['parameter-final-separator'];  else  error_str = error_str .. cfg.messages['parameter-pair-separator'];  end  error_str = error_str .. wrap( 'parameter', selected );  table.insert( z.message_tail, { seterror( error_condition, {error_str}, true ) } );  end   return value, selected; end  -- COinS metadata (see <http://ocoins.info/>) allows automated tools to parse -- the citation information. function COinS(data)  if 'table' ~= type(data) or nil == next(data) then  return '';  end   local ctx_ver = "Z39.88-2004";   -- treat table strictly as an array with only set values.  local OCinSoutput = setmetatable( {}, {  __newindex = function(self, key, value)  if is_set(value) then  rawset( self, #self+1, table.concat{ key, '=', mw.uri.encode( removewikilink( value ) ) } );  end  end  });   if is_set(data.Chapter) then  OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book";  OCinSoutput["rft.genre"] = "bookitem";  OCinSoutput["rft.btitle"] = data.Chapter;  OCinSoutput["rft.atitle"] = data.Title;  elseif is_set(data.Periodical) then  OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal";  OCinSoutput["rft.genre"] = "article";  OCinSoutput["rft.jtitle"] = data.Periodical;  OCinSoutput["rft.atitle"] = data.Title;  else  OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book";  OCinSoutput["rft.genre"] = "book"  OCinSoutput["rft.btitle"] = data.Title;  end   OCinSoutput["rft.place"] = data.PublicationPlace;  OCinSoutput["rft.date"] = data.Date;  OCinSoutput["rft.series"] = data.Series;  OCinSoutput["rft.volume"] = data.Volume;  OCinSoutput["rft.issue"] = data.Issue;  OCinSoutput["rft.pages"] = data.Pages;  OCinSoutput["rft.edition"] = data.Edition;  OCinSoutput["rft.pub"] = data.PublisherName;   for k, v in pairs( data.ID_list ) do  local id, value = cfg.id_handlers[k].COinS;  if k == 'ISBN' then value = cleanisbn( v ); else value = v; end  if string.sub( id or "", 1, 4 ) == 'info' then  OCinSoutput["rft_id"] = table.concat{ id, "/", v };  else  OCinSoutput[ id ] = value;  end  end   local last, first;  for k, v in ipairs( data.Authors ) do  last, first = v.last, v.first;  if k == 1 then  if is_set(last) then  OCinSoutput["rft.aulast"] = last;  end  if is_set(first) then  OCinSoutput["rft.aufirst"] = first;  end  end  if is_set(last) and is_set(first) then  OCinSoutput["rft.au"] = table.concat{ last, ", ", first };  elseif is_set(last) then  OCinSoutput["rft.au"] = last;  end  end   OCinSoutput.rft_id = data.URL;  OCinSoutput.rfr_id = table.concat{ "info:sid/", mw.site.server:match( "[^/]*$" ), ":", data.RawPage };  OCinSoutput = setmetatable( OCinSoutput, nil );   -- sort with version string always first, and combine.  table.sort( OCinSoutput );  table.insert( OCinSoutput, 1, "ctx_ver=" .. ctx_ver ); -- such as "Z39.88-2004"  return table.concat(OCinSoutput, "&"); end  --[[ This is the main function doing the majority of the citation formatting. ]] function citation0( config, args)  local ModuloIdentificadores = require('Módulo:Identificadores')  --[[   Load Input Parameters  The argment_wrapper facillitates the mapping of multiple  aliases to single internal variable.  ]]  local A = argument_wrapper( args );   local i  local PPrefix = A['PPrefix']  local PPPrefix = A['PPPrefix']  if is_set( A['NoPP'] ) then PPPrefix = "" PPrefix = "" end   -- Pick out the relevant fields from the arguments. Different citation templates  -- define different field names for the same underlying things.   local Authors = A['Authors'];  local a = extractnames( args, 'AuthorList' );   local Coauthors = A['Coauthors'];   local Editors = A['Editors'];  local e = extractnames( args, 'EditorList' );   local Year = A['Year'];  local wYear=Year;  local PublicationDate = A['PublicationDate'];  local OrigYear = A['OrigYear'];  local Date = A['Date'];  local wfecha = Date;  local LayDate = A['LayDate'];  ------------------------------------------------- Get title data  local Title = A['Title'];  local BookTitle = A['BookTitle'];  local Conference = A['Conference'];  local TransTitle = A['TransTitle'];  local TitleNote = A['TitleNote'];  local TitleLink = A['TitleLink'];  local Chapter = A['Chapter'];  local ChapterLink = A['ChapterLink'];  local TransChapter = A['TransChapter'];  local TitleType = A['TitleType'];  local Degree = A['Degree'];  local Docket = A['Docket'];  local ArchiveURL = A['ArchiveURL'];  local URL = A['URL']  local URLorigin = A:ORIGIN('URL');  local ChapterURL = A['ChapterURL'];  local ChapterURLorigin = A:ORIGIN('ChapterURL');  local ConferenceURL = A['ConferenceURL'];  local ConferenceURLorigin = A:ORIGIN('ConferenceURL');  local SinURL = false;  local Periodical = A['Periodical'];   local Series = A['Series'];  local Volume = A['Volume'];  local Issue = A['Issue'];  local Position = '';  local Page = A['Page'];  local Pages = dashtohyphen( A['Pages'] );  local At = A['At'];  local Others = A['Others'];  local Edition = A['Edition'];  local PublicationPlace = A['PublicationPlace']  local Place = A['Place'];  local Passage = A['Passage'];  local PassageURL = A['PassageURL'];   local PublisherName = A['PublisherName'];  local UrlAccess = A['UrlAccess'];  local RegistrationRequired = A['RegistrationRequired'];  local SubscriptionRequired = A['SubscriptionRequired'];  local Via = A['Via'];  local AccessDate = A['AccessDate'];  local MesAcceso = A['MesAcceso']; -- Inexistente en la plantilla original  local AnyoAcceso = A['AñoAcceso']; -- Inexistente en la plantilla original  local ArchiveDate = A['ArchiveDate'];  local Agency = A['Agency'];  local DeadURL = A['DeadURL']  local Language = A['Language'];  local Format = A['Format'];  local Ref = A['Ref'];  local DoiBroken = A['DoiBroken'];  local ID = A['ID'];  local IgnoreISBN = A['IgnoreISBN'];  local Embargo = A['Embargo'];  local Texto1 = A['Texto1']  local ID_list = extractids( args );  local ISBNCorrecto = false;  local ISBNSugerido;   if is_set (ID_list['ISBN']) and not is_set (IgnoreISBN) then  if ModuloIdentificadores.esValidoISBN(ID_list['ISBN']) then  ISBNCorrecto= true  else  ISBNSugerido = SugerirISBN(ID_list['ISBN'])  if ISBNSugerido then  ID_list['ISBN'] = ISBNSugerido  end  end  end  local Lista_Identificadores_Formateados={} -- Lista de identificadores con enlaces y en su caso con los errores   local Quote = A['Quote'];  local TransQuote = A['TransQuote'];  local PostScript = A['PostScript'];   local LayURL = A['LayURL'];  local LaySource = A['LaySource'];  local Transcript = A['Transcript'];  local TranscriptURL = A['TranscriptURL']  local TranscriptURLorigin = A:ORIGIN('TranscriptURL');  local sepc = A['Separator'];   local LastAuthorAmp = A['LastAuthorAmp'];  local no_tracking_cats = A['NoTracking'];  --these are used by cite interview  local Callsign = A['Callsign'];  local City = A['City'];  local Cointerviewers = A['Cointerviewers']; -- deprecated  local Interviewer = A['Interviewer']; -- deprecated  local Program = A['Program'];  --Parámetros que no se utilizan en la plantilla inglesa  local SinEd = A['SinEd']  local Extra = A['Extra']  local Traductor = A['Traductor']  local Traductores = A['Traductores']  --local variables that are not cs1 parameters  local page_type; -- is this needed? Doesn't appear to be used anywhere;  local use_lowercase  local this_page = mw.title.getCurrentTitle(); --Also used for COinS and for language -- local anchor_year; -- used in the CITEREF identifier  local COinS_date; -- used in the COinS metadata  --check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories.  if not is_set(no_tracking_cats) then -- ignore if we are already not going to categorize this page  for k, v in pairs( cfg.uncategorized_namespaces ) do -- otherwise, spin through the list of namespaces we don't include in error categories  if this_page.nsText == v then -- if we find one  no_tracking_cats = "true"; -- set no_trackin_cats  break; -- and we're done  end  end  end  -- check for extra |page=, |pages= or |at= parameters.   if is_set(Page) then -- La categoría de la plantilla inglesa es intraducible. Utilizo otro error similar.   --if is_set(Pages) or is_set(At) then  -- Page = Page .. " " .. seterror('extra_pages'); -- add error message  -- Pages = ''; -- unset the others  -- At = '';  --end  if is_set(Pages) then  Page = Page .. " " .. seterror('redundant_parameters', '<code>&#124;página=</code> y <code>&#124;páginas=</code>');  Pages = ''; -- unset the others  At = '';  Passage = '';  elseif is_set(At) then  Page = Page .. " " .. seterror('redundant_parameters', '<code>&#124;página=</code> y <code>&#124;en=</code>');  Pages = ''; -- unset the others  At = '';  Passage = '';  elseif is_set(Passage) then  Page = Page .. " " .. seterror('redundant_parameters', '<code>&#124;página=</code> y <code>&#124;pasaje=</code>');  Pages = ''; -- unset the others  At = '';  Passage = '';  end  elseif is_set(Pages) then  if is_set(At) then  -- Pages = Pages .. " " .. seterror('extra_pages'); -- add error messages  Pages = Pages .. " " .. seterror('redundant_parameters', '<code>&#124;páginas=</code> y <code>&#124;en=</code>');  At = '';  Passage = '';  elseif is_set(Passage) then  Pages = Pages .. " " .. seterror('redundant_parameters', '<code>&#124;páginas=</code> y <code>&#124;pasaje=</code>');  At = '';  Passage = '';  end  elseif is_set(At) then  if is_set(Passage) then  At = At .. " " .. seterror('redundant_parameters', '<code>&#124;en=</code> y <code>&#124;pasaje=</code>');  Passage = '';  end  end  -- both |publication-place= and |place= (|location=) allowed if different  if not is_set(PublicationPlace) and is_set(Place) then  PublicationPlace = Place; -- promote |place= (|location=) to |publication-place  end   if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same  --[[ 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.ClaseCita == "encyclopaedia" ) then  if ( config.ClaseCita == "enciclopedia" ) 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  --special cases for classic book  if config.ClaseCita == 'libro' and is_set(Passage) then  if is_set(PassageURL) then  Passage = externallink( PassageURL, Passage )  end  if not is_set (sepc) then  sepc = ' ';  end  else  Passage = ''  end  --special cases for citation.  if (config.ClaseCita == "citation") then -- for citation templates  if not is_set (sepc) then -- if |separator= is not set  sepc = ','; -- set citation separator to its default (comma)  end  else -- not a citation template  if not is_set (sepc) then -- if |separator= has not been set  sepc = '.'; -- set cite xxx separator to its default (period)  end  end   if not is_set (Ref) then -- if |ref= is not set  -- if inArray(config.ClaseCita, {"citation", "libro", "publicación", "web"}) then -- for citation templates -- En la Wikipedia inglesa solo se usan citas Harvard para la clase citation  -- Quedan habilitadas las citas Harvard para cualquier clase que contenga algún autor o editor  if #a > 0 or #e > 0 then  Ref = "harv"; -- set default |ref=harv  end  end  -- check for specital case where |separator=none  if 'none' == sepc:lower() then -- if |separator=none  sepc = ''; -- then set it to a empty string  end   use_lowercase = ( sepc ~= '.' );   Others = is_set(Others) and (sepc .. " " .. Others) or "";  -- Special case for cite techreport.  if (config.ClaseCita == "techreport") then -- special case for cite techreport  if is_set(Issue) then -- cite techreport uses 'number', which other citations aliase to 'issue'  if not is_set(ID) then -- can we use ID for the "number"?  ID = Issue; -- yes, use it  Issue = ""; -- unset Issue so that "number" isn't duplicated in the rendered citation or COinS metadata  else -- can't use ID so emit error message  ID = ID .. " " .. seterror('redundant_parameters', '<code>&#124;id=</code> and <code>&#124;number=</code>');  end  end -- special case for cite interview  elseif (config.ClaseCita == "entrevista") then  if is_set(Program) then  ID = ' ' .. Program;  end  if is_set(Callsign) then  if is_set(ID) then  ID = ID .. sepc .. ' ' .. Callsign;  else  ID = ' ' .. Callsign;  end  end  if is_set(City) then  if is_set(ID) then  ID = ID .. sepc .. ' ' .. City;  else  ID = ' ' .. City;  end  end   if is_set(Interviewer) then  if is_set(TitleType) then  Others = sepc .. ' ' .. TitleType .. ' con ' .. Interviewer -- ' ' .. TitleType .. ' con ' .. Interviewer;  TitleType = '';  else  Others = sepc .. ' ' .. wrap('interview', Interviewer, use_lowercase) .. Others -- ' ' .. 'Entrevista con ' .. Interviewer;  end  if is_set(Cointerviewers) then  Others = Others .. sepc .. ' ' .. Cointerviewers;  end  else  Others = Others .. sepc .. ' (Entrevista)' --'(Interview)';  end  elseif is_set(ID) then  ID = wrap( 'id', ID)  end  --Account for the oddity that is {{cite journal}} with |pmc= set and |url= not set -- if config.ClaseCita == "journal" and not is_set(URL) and is_set(ID_list['PMC']) then  if config.ClaseCita == "publicación" 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  URLorigin = cfg.id_handlers['PMC'].parameters[1]; -- set URLorigin to parameter name for use in error message if citation is missing a |title=  end  end   if is_set(Texto1) and Texto1:match("%S+") then  -- Informar la URL con el valor del campo 1 en su caso   if config.ClaseCita == "web" and not is_set(URL) and checkurl(Texto1) then  table.insert( z.message_tail, { seterror( 'url_sugerida', {Texto1, 'url'}, true ) } )  --URL = Texto1 Utilizar URL como texto.  else  table.insert( z.message_tail, { seterror( 'text_ignored', {Texto1}, true ) } )  end  end  -- Account for the oddity that is {{cite conference}}, before generation of COinS data. --TODO: if this is only for {{cite conference}}, shouldn't we be checking? (if config.ClaseCita=='conference' then ...)   if 'conferencia' == config.ClaseCita then  if is_set(BookTitle) then  Chapter = Title; -- ChapterLink = TitleLink; -- |chapterlink= is deprecated  ChapterURL = URL;  ChapterUrlAccess = UrlAccess;  ChapterURLorigin = URLorigin;  URLorigin = '';  ChapterFormat = Format;  TransChapter = TransTitle;  Title = BookTitle;  Format = ''; -- TitleLink = '';  TransTitle = '';  URL = '';  end  elseif 'speech' ~= config.ClaseCita then  Conference = ''; -- not cite conference or cite speech so make sure this is empty string  end  -- Account for the oddity that is {{cite episode}}, before generation of COinS data. --[[ -- {{cite episode}} is not currently supported by this module  if config.ClaseCita == "episode" then  local AirDate = A['AirDate'];  local SeriesLink = A['SeriesLink'];  local Season = A['Season'];  local SeriesNumber = A['SeriesNumber'];  local Network = A['Network'];  local Station = A['Station'];  local s, n = {}, {};  local Sep = (first_set(A["SeriesSeparator"], A["Separator"]) or "") .. " ";    if is_set(Issue) then table.insert(s, cfg.messages["episode"] .. " " .. Issue); Issue = ''; end  if is_set(Season) then table.insert(s, cfg.messages["season"] .. " " .. Season); end  if is_set(SeriesNumber) then table.insert(s, cfg.messages["series"] .. " " .. SeriesNumber); end  if is_set(Network) then table.insert(n, Network); end  if is_set(Station) then table.insert(n, Station); end    Date = Date or AirDate;  Chapter = Title;  ChapterLink = TitleLink;  TransChapter = TransTitle;  Title = Series;  TitleLink = SeriesLink;  TransTitle = '';    Series = table.concat(s, Sep);  ID = table.concat(n, Sep);  end -- end of {{cite episode}} stuff]]  -- 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 .. " de " .. Date; --Month .. " " .. Date;  local Day = A['Day']  if is_set(Day) then Date = Day .. " de " .. Date end --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. This must be done before we do COinS because here is where we get the date used in the metadata.  Date validation supporting code is in Módulo:Citas/ValidaciónFechas ]]  --[[  anchor_year, COinS_date, error_message = dates({['accessdate']=AccessDate, ['airdate']=AirDate, ['archivedate']=ArchiveDate, ['date']=Date, ['doi_brokendate']=DoiBroken,  ['embargo']=Embargo, ['laydate']=LayDate, ['publicationdate']=PublicationDate, ['year']=Year});  if is_set(error_message) then  table.insert( z.message_tail, { seterror( 'bad_date', {error_message}, true ) } ); -- add this error message  end ]] -- At this point fields may be nil if they weren't specified in the template use. We can use that fact.   -- COinS metadata (see <http://ocoins.info/>) for  -- automated parsing of citation information.  local OCinSoutput = COinS{  ['Periodical'] = Periodical,  ['Chapter'] = Chapter,  ['Title'] = Title,  ['PublicationPlace'] = PublicationPlace,  ['Date'] = first_set(COinS_date, Date), -- COinS_date has correctly formatted date if Date is valid; any reason to keep Date here? Should we be including invalid dates in metadata?  ['Series'] = Series,  ['Volume'] = Volume,  ['Issue'] = Issue,  ['Pages'] = get_coins_pages (first_set(Page, Pages, At)), -- pages stripped of external links  ['Edition'] = Edition,  ['PublisherName'] = PublisherName,  ['URL'] = first_set( URL, ChapterURL ),  ['Authors'] = a,  ['ID_list'] = ID_list,  ['RawPage'] = this_page.prefixedText,  };   if is_set(Periodical) and not is_set(Chapter) and is_set(Title) then  Chapter = Title;  ChapterLink = TitleLink;  TransChapter = TransTitle;  Title = '';  TitleLink = '';  TransTitle = '';  end   -- Now perform various field substitutions.  -- We also add leading spaces and surrounding markup and punctuation to the  -- various parts of the citation, but only when they are non-nil.  if not is_set(Authors) then  local Maximum = tonumber( A['DisplayAuthors'] );   -- Preserve old-style implicit et al.  if not is_set(Maximum) and #a == 9 then  Maximum = 8;  table.insert( z.message_tail, { seterror('implict_etal_author', {}, true ) } );  elseif not is_set(Maximum) then  Maximum = #a + 1;  end   local control = {  sep = A["AuthorSeparator"] .. " ",  namesep = (first_set(A["AuthorNameSeparator"], A["NameSeparator"]) or "") .. " ",  format = A["AuthorFormat"],  maximum = Maximum,  lastauthoramp = LastAuthorAmp  };   -- If the coauthor field is also used, prevent ampersand and et al. formatting.  if is_set(Coauthors) then  control.lastauthoramp = nil;  control.maximum = #a + 1;  end   Authors = listpeople(control, a)  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   -- Utilizo temporalmente los coautores como autores.  Authors = Coauthors  Coauthors = nil  end   local EditorCount  if not is_set(Editors) then  local Maximum = tonumber( A['DisplayEditors'] );  -- Preserve old-style implicit et al.  if not is_set(Maximum) and #e == 4 then  Maximum = 3;  table.insert( z.message_tail, { seterror('implict_etal_editor', {}, true) } );  elseif not is_set(Maximum) then  Maximum = #e + 1;  end   local control = {  sep = A["EditorSeparator"] .. " ",  namesep = (first_set(A["EditorNameSeparator"], A["NameSeparator"]) or "") .. " ",  format = A['EditorFormat'],  maximum = Maximum,  lastauthoramp = LastAuthorAmp  };   Editors, EditorCount = listpeople(control, e);  else  EditorCount = 1;  end   local Cartography = "";  local Scale = "";  if config.ClaseCita == "map" then  if not is_set( Authors ) and is_set( PublisherName ) then  Authors = PublisherName;  PublisherName = "";  end  Cartography = A['Cartography'];  if is_set( Cartography ) then  Cartography = sepc .. " " .. wrap( 'cartography', Cartography, use_lowercase );  end  Scale = A['Scale'];  if is_set( Scale ) then  Scale = sepc .. " " .. Scale;  end  end   if not is_set(URL) and  not is_set(ChapterURL) and  not is_set(ArchiveURL) and  not is_set(ConferenceURL) and  not is_set(TranscriptURL) then   sinURL = true   -- Test if cite web or cite podcast |url= is missing or empty   if inArray(config.ClaseCita, {"web","podcast"}) then  table.insert( z.message_tail, { seterror( 'cite_web_url', {}, true ) } );  end   -- Test if format is given without giving a URL  if is_set(Format) then  Format = Format .. seterror( 'format_missing_url' );  end  end   -- Test if citation has no title  if not is_set(Chapter) and  not is_set(Title) and  not is_set(Periodical) and  not is_set(Conference) and  not is_set(TransTitle) and  not is_set(TransChapter) and  not is_set(Passage) then  table.insert( z.message_tail, { seterror( 'citation_missing_title', {}, true ) } );  end   Format = is_set(Format) and " " .. wrap( 'format', Format ) or ""; --is_set(Format) and " (" .. Format .. ")" or "";   local OriginalURL = URL  DeadURL = DeadURL:lower();  if is_set( ArchiveURL ) then  if ( DeadURL ~= "no" ) then  URL = ArchiveURL  URLorigin = A:ORIGIN('ArchiveURL')  end  end   -- Format chapter / article title  if is_set(Chapter) and is_set(ChapterLink) then  Chapter = "[[" .. ChapterLink .. "|" .. Chapter .. "]]";  end  if is_set(Periodical) and is_set(Title) then  Chapter = wrap( 'italic-title', Chapter );  TransChapter = wrap( 'trans-italic-title', TransChapter );  else  Chapter = kern_quotes (Chapter); -- if necessary, separate chapter title's leading and trailing quote marks from Module provided quote marks  Chapter = wrap( 'quoted-title', Chapter );  TransChapter = wrap( 'trans-quoted-title', TransChapter );  end   local TransError = ""  if is_set(TransChapter) then  if not is_set(Chapter) then  TransError = " " .. seterror( 'trans_missing_chapter' );  else  TransChapter = " " .. TransChapter;  end  end   Chapter = Chapter .. TransChapter;   if is_set(Chapter) then  if not is_set(ChapterLink) then  if is_set(ChapterURL) then  Chapter = externallink( ChapterURL, Chapter ) .. TransError;  if not is_set(URL) then  Chapter = Chapter .. Format;  Format = "";  end  elseif is_set(URL) then  Chapter = externallink( URL, Chapter ) .. TransError .. Format;  URL = "";  Format = "";  else  Chapter = Chapter .. TransError;  end  elseif is_set(ChapterURL) then  Chapter = Chapter .. " " .. externallink( ChapterURL, nil, ChapterURLorigin ) ..  TransError;  else  Chapter = Chapter .. TransError;  end  Chapter = Chapter .. sepc .. " " -- with end-space  elseif is_set(ChapterURL) then  Chapter = " " .. externallink( ChapterURL, nil, ChapterURLorigin ) .. sepc .. " ";  end   -- Format main title.  if is_set(TitleLink) and is_set(Title) then  Title = "[[" .. TitleLink .. "|" .. Title .. "]]"  end   if is_set(Traductor) and is_set(Traductores) then  Traductor = " " .. wrap( 'traductores', Traductores) .. " " .. seterror('redundant_parameters', '<code>&#124;traductor=</code> y <code>&#124;traductores=</code>')  elseif is_set(Traductor) then  Traductor = " " .. wrap( 'traductor', Traductor)  elseif is_set(Traductores) then  Traductor = " " .. wrap( 'traductores', Traductores)  end   Traductores = ''   if is_set(Periodical) then  Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from Module provided quote marks  Title = wrap( 'quoted-title', Title );  TransTitle = wrap( 'trans-quoted-title', TransTitle ); -- elseif inArray(config.ClaseCita, {"web","news","pressrelease","conference","podcast"}) and  elseif inArray(config.ClaseCita, {"web","noticia","pressrelease","conference","podcast"}) and  not is_set(Chapter) then  Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from Module provided quote marks  Title = wrap( 'quoted-title', Title );  TransTitle = wrap( 'trans-quoted-title', TransTitle );  else  Title = wrap( 'italic-title', Title );  TransTitle = wrap( 'trans-italic-title', TransTitle );  end   TransError = "";  if is_set(TransTitle) then  if not is_set(Title) then  TransError = " " .. seterror( 'trans_missing_title' );  else  TransTitle = " " .. TransTitle;  end  end   Title = Title .. Traductor .. TransTitle;   if is_set(Title) then  if not is_set(TitleLink) and is_set(URL) then  Title = externallink( URL, Title, URL_origin, UrlAccess ) .. TransError .. Format  URL = "";  TieneURL = true;  Format = "";  else  Title = Title .. TransError;  end  end   if is_set(Place) then  Place = " " .. wrap( 'written', Place, use_lowercase ) .. sepc .. " ";  end   if is_set(Conference) then  if is_set(ConferenceURL) then  Conference = externallink( ConferenceURL, Conference );  end  Conference = sepc .. " " .. Conference  elseif is_set(ConferenceURL) then  Conference = sepc .. " " .. externallink( ConferenceURL, nil, ConferenceURLorigin );  end   if not is_set(Position) then  local Minutes = A['Minutes'];  if is_set(Minutes) then  Position = " " .. Minutes .. " " .. cfg.messages['minutes'];  else  local Time = A['Time'];  if is_set(Time) then  local TimeCaption = A['TimeCaption']  if not is_set(TimeCaption) then  TimeCaption = cfg.messages['event'];  if sepc ~= '.' then  TimeCaption = TimeCaption:lower();  end  end  Position = " " .. TimeCaption .. " " .. Time;  end  end  else  Position = " " .. Position;  At = '';  end   if not is_set(Page) then  if is_set(Pages) then  if is_set(Periodical) and -- not inArray(config.ClaseCita, {"encyclopaedia","web","book","news","podcast"}) then  not inArray(config.ClaseCita, {"enciclopedia","web","libro","noticia","podcast"}) then  Pages = ": " .. Pages;  elseif tonumber(Pages) ~= nil then  Pages = sepc .." " .. PPrefix .. Pages;  else  Pages = sepc .." " .. PPPrefix .. Pages;  end  end  else  if is_set(Periodical) and -- not inArray(config.ClaseCita, {"encyclopaedia","web","book","news","podcast"}) then  not inArray(config.ClaseCita, {"enciclopedia","web","libro","noticia","podcast"}) then  Page = ": " .. Page;  else  Page = sepc .." " .. PPrefix .. Page;  end  end   At = is_set(At) and (sepc .. " " .. At) or "";  Passage = is_set(Passage) and (sepc .. " " .. Passage) or "";  Position = is_set(Position) and (sepc .. " " .. Position) or "";  if config.ClaseCita == 'map' then  local Section = A['Section'];  local Inset = A['Inset'];  if first_set( Pages, Page, At ) ~= nil or sepc ~= '.' then  if is_set( Section ) then  Section = ", " .. wrap( 'section', Section, true );  end  if is_set( Inset ) then  Inset = ", " .. wrap( 'inset', Inset, true );  end  else  if is_set( Section ) then  Section = sepc .. " " .. wrap( 'section', Section, use_lowercase );  if is_set( Inset ) then  Inset = ", " .. wrap( 'inset', Inset, true );  end  elseif is_set( Inset ) then  Inset = sepc .. " " .. wrap( 'inset', Inset, use_lowercase );  end  end  At = At .. Section .. Inset;  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  -- Poner en minúsculas el primer caracter del idioma si está en mayúsculas  Language = Language:gsub("^%u", string.lower)   if Language == 'español' or Language == 'castellano' or Language == 'es' or Language:match('^es%-.*') then  Language=""; -- No mostrar el idioma español  else  local name = mw.language.fetchLanguageName( Language:lower(), "es" ); -- experiment: this seems to return correct ISO 639-1 language names   if is_set (name) then  Language=" " .. wrap( 'language', name );  else  Language=" " .. wrap( 'language', Language ); -- no match, use parameter's value  end  end   else  Language=""; -- Asegurarnos de que el idioma no es nulo.  end  -- handle type parameter for those CS1 citations that have default values  -- if inArray(config.ClaseCita, {"AV media notes", "DVD notes", "podcast", "pressrelease", "techreport", "thesis"}) then  if inArray(config.ClaseCita, {"notas audiovisual", "notas de DVD", "podcast", "pressrelease", "techreport", "tesis"}) then  TitleType = set_titletype (config.ClaseCita, TitleType);  if is_set(Degree) and "Tesis" == TitleType then -- special case for cite thesis  TitleType = "Tesis de " .. Degree;  end  end   if is_set(TitleType) then -- if type parameter is specified  TitleType = " (" .. TitleType .. ")"; -- display it in parentheses  end   TitleNote = is_set(TitleNote) and (sepc .. " " .. TitleNote) or "";   if is_set(Edition) then  if is_set(SinEd) then -- No existe el parámetro en el módulo de la wikipedia inglesa.  Edition = " " .. wrap( 'sin edición', Edition ) -- No existe el parámetro en el módulo de la wikipedia inglesa.  else  Edition = " " .. wrap( 'edition', Edition )  end  else  Edition = ""  end  Issue = is_set(Issue) and (" (" .. Issue .. ")") or "";  Series = is_set(Series) and (sepc .. " " .. Series) or "";  OrigYear = is_set(OrigYear) and (" [" .. OrigYear .. "]") or "";  Agency = is_set(Agency) and (sepc .. " " .. Agency) or "";   if is_set(Volume) then  if Volume:match ('^%d+$') or Volume:match ('^[MDCLXVI]+$') -- negrita solamente si el capítulo está reflejado como cifra decimal o números romanos  then Volume = " <b>" .. dashtohyphen(Volume) .. "</b>";  else Volume = sepc .." " .. Volume;  end  end  --[[ This code commented out while discussion continues until after week of 2014-03-23 live module update;  if is_set(Volume) then  if ( mw.ustring.len(Volume) > 4 )  then Volume = sepc .. " " .. Volume;  else  Volume = " <b>" .. hyphentodash(Volume) .. "</b>";  if is_set(Series) then Volume = sepc .. Volume;  end  end  end ]]  ------------------------------------ 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  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  Via = " " .. wrap( 'via', Via );  end   if UrlAccess == 'registration' then  RegistrationRequired = true  end  if is_set(SubscriptionRequired) then  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  -- if is_set(AccessDate) then  if is_set(AccessDate) or is_set(AnyoAcceso) then  -- Test if accessdate is given without giving a URL  if sinURL then  table.insert( z.message_tail, { seterror( 'accessdate_missing_url', {}, true ) } );  AccessDate = '';  else  if is_set(AccessDate) then  if is_set(MesAcceso) and is_set(AnyoAcceso) then  AccessDate = AccessDate .. seterror('redundant_parameters', '<code>&#124;fechaacceso=</code>, <code>&#124;añoacceso=</code> y <code>&#124;mesacceso=</code>')  elseif is_set(MesAcceso) then  AccessDate = AccessDate .. seterror('redundant_parameters', '<code>&#124;fechaacceso=</code> y <code>&#124;mesacceso=</code>')  elseif is_set(AnyoAcceso) then  if string.find(AccessDate, '%sde%s') then  AccessDate = AccessDate .. ' de ' .. AnyoAcceso  else  AccessDate = AccessDate .. seterror('redundant_parameters', '<code>&#124;fechaacceso=</code> y <code>&#124;Añoacceso=</code>');  end  end  elseif is_set(MesAcceso) then  AccessDate = MesAcceso .. ' de ' .. AnyoAcceso  else  AccessDate = AnyoAcceso  end  local retrv_text = " " .. cfg.messages['retrieved']  if (sepc ~= ".") then retrv_text = retrv_text:lower() end  AccessDate = '<span class="reference-accessdate">' .. sepc  .. substitute( retrv_text, {format_date(AccessDate)} ) .. '</span>'  end  elseif is_set(MesAcceso) then  end   if is_set(ID) then ID = sepc .." ".. ID; end  if "tesis" == config.ClaseCita and is_set(Docket) then  ID = sepc .." Docket ".. Docket .. ID;  end   Lista_Identificadores_Formateados = buildidlist( ID_list, {DoiBroken = DoiBroken, IgnoreISBN = IgnoreISBN, Embargo=Embargo, ISBNCorrecto = ISBNCorrecto, ISBNSugerido = ISBNSugerido} );   if is_set(URL) then  URL = " " .. externallink( URL, nil, URLorigin, UrlAccess );  end  -- Set postscript default.  if not is_set (PostScript) then -- if |postscript= has not been set (Postscript is nil which is the default for {{citation}}) and  if (config.ClaseCita ~= "citation") then -- this template is not a citation template  PostScript = '.'; -- must be a cite xxx template so set postscript to default (period)  end  else  if PostScript:lower() == 'none' then -- if |postscript=none then  PostScript = ''; -- no postscript  end  end   if is_set(Quote) or is_set(TransQuote) then  -- Eliminar comillas de Quote  if (Quote:sub(1,1) == '"' and Quote:sub(-1,-1) == '"') or  (Quote:sub(1,1) == '«' and Quote:sub(-1,-1) == '»') then  Quote = Quote:sub(2,-2);  end   -- No añadir el punto final a la cita si el campo Quote ya incluye un punto  if Quote:sub(-1,-1) == '.' or Quote:sub(-1,-1) == '?' or  Quote:sub(-1,-1) == '!' then  PostScript = ""  end   -- Eliminar comillas de TransQuote  if (TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"') or  (Quote:sub(1,1) == '«' and Quote:sub(-1,-1) == '»') then  TransQuote = TransQuote:sub(2, -2);  end   -- No añadir el punto final a la cita si el campo TransQuote ya incluye un punto  if TransQuote:sub(-1,-1) == '.' or TransQuote:sub(-1,-1) == '?' or  TransQuote:sub(-1,-1) == '!' then  PostScript = ""  end  Quote = Quote .. " " .. wrap( 'trans-quoted-title', TransQuote );  TransQuote = wrap( 'trans-quoted-title', TransQuote );  Quote = sepc .." " .. wrap( 'quoted-text', Quote );  end   local Archived  if is_set(ArchiveURL) then  if not is_set(ArchiveDate) then  ArchiveDate = seterror('archive_missing_date');  else  ArchiveDate = format_date(ArchiveDate)  end  if "no" == DeadURL then  local arch_text = cfg.messages['archived'];  if sepc ~= "." then arch_text = arch_text:lower() end  Archived = sepc .. " " .. substitute( cfg.messages['archived-not-dead'],  { externallink( ArchiveURL, arch_text ), ArchiveDate } );  if not is_set(OriginalURL) then  Archived = Archived .. " " .. seterror('archive_missing_url');  end  elseif is_set(OriginalURL) then  local arch_text = cfg.messages['archived-dead'];  if sepc ~= "." then arch_text = arch_text:lower() end  Archived = sepc .. " " .. substitute( arch_text,  { externallink( OriginalURL, cfg.messages['original'] ), ArchiveDate } );  else  local arch_text = cfg.messages['archived-missing'];  if sepc ~= "." then arch_text = arch_text:lower() end  Archived = sepc .. " " .. substitute( arch_text,  { seterror('archive_missing_url'), ArchiveDate } );  end  else  Archived = ""  end   local Lay  if is_set(LayURL) then  if is_set(LayDate) then LayDate = " (" .. format_date(LayDate) .. ")" end  if is_set(LaySource) then  LaySource = " &ndash; ''" .. safeforitalics(LaySource) .. "''";  else  LaySource = "";  end  if sepc == '.' then  Lay = sepc .. " " .. externallink( LayURL, cfg.messages['lay summary'] ) .. LaySource .. LayDate  else  Lay = sepc .. " " .. externallink( LayURL, cfg.messages['lay summary']:lower() ) .. LaySource .. LayDate  end  else  Lay = "";  end   if is_set(Transcript) then  if is_set(TranscriptURL) then Transcript = externallink( TranscriptURL, Transcript ); end  elseif is_set(TranscriptURL) then  Transcript = externallink( TranscriptURL, nil, TranscriptURLorigin );  end   local Publisher;  if is_set(Periodical) and -- not inArray(config.ClaseCita, {"encyclopaedia","web","pressrelease","podcast"}) then  not inArray(config.ClaseCita, {"enciclopedia","web","pressrelease","podcast"}) then  if is_set(PublisherName) then  if is_set(PublicationPlace) then  Publisher = PublicationPlace .. ": " .. PublisherName;  else  Publisher = PublisherName;  end  elseif is_set(PublicationPlace) then  Publisher= PublicationPlace;  else  Publisher = "";  end  if is_set(PublicationDate) then  if is_set(Publisher) then  Publisher = Publisher .. ", " .. wrap( 'published', PublicationDate );  else  Publisher = PublicationDate;  end  end  if is_set(Publisher) then  Publisher = " (" .. Publisher .. ")";  end  else  if is_set(PublicationDate) then  PublicationDate = " (" .. wrap( 'published', format_date(PublicationDate) ) .. ")";  end  if is_set(PublisherName) then  if is_set(PublicationPlace) then  Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate;  else  Publisher = sepc .. " " .. PublisherName .. PublicationDate;  end  elseif is_set(PublicationPlace) then  Publisher= sepc .. " " .. PublicationPlace .. PublicationDate;  else  Publisher = PublicationDate;  end  end   -- Several of the above rely upon detecting this as nil, so do it last.  if is_set(Periodical) then  if is_set(Title) or is_set(TitleNote) then  Periodical = sepc .. " " .. wrap( 'italic-title', Periodical )  else  Periodical = wrap( 'italic-title', Periodical )  end  end  --[[ Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided). ]]  if "speech" == config.ClaseCita then -- cite speech only  TitleNote = " (Speech)"; -- annotate the citation  if is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter   if is_set (Conference) then -- and if |event= is set  Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering  end  end  end   -- Piece all bits together at last. Here, all should be non-nil.  -- We build things this way because it is more efficient in LUA  -- not to keep reassigning to the same string variable over and over.   local tcommon -- if inArray(config.ClaseCita, {"journal","citation"}) and is_set(Periodical) then  if inArray(config.ClaseCita, {"publicación","citation"}) and is_set(Periodical) then  if is_set(Others) then Others = Others .. sepc .. " " end  tcommon = safejoin( {Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Scale, Series,  Language, Cartography, Edition, Publisher, Agency, Volume, Issue}, sepc );  else  tcommon = safejoin( {Title, TitleNote, Conference, Periodical, Format, TitleType, Scale, Series, Language,  Volume, Issue, Others, Cartography, Edition, Publisher, Agency}, sepc );  end   if #Lista_Identificadores_Formateados > 0 then  Lista_Identificadores_Formateados = safejoin( { sepc .. " ", table.concat( Lista_Identificadores_Formateados, sepc .. " " ), ID }, sepc );  else  Lista_Identificadores_Formateados = ID;  end   local idcommon = safejoin( { Lista_Identificadores_Formateados, URL, Archived, AccessDate, Via, SubscriptionRequired, Lay, Quote }, sepc );  local text;  local pgtext = Position .. Page .. Pages .. At .. Passage;   if is_set(Authors) then  if is_set(Coauthors) then  Authors = Authors .. A['AuthorSeparator'] .. " " .. Coauthors  end  if is_set(Date) then  Date = " ("..format_date(Date)..")" .. OrigYear .. sepc .. " "  elseif string.sub(Authors,-1,-1) == sepc then  Authors = Authors .. " "  else  Authors = Authors .. sepc .. " "  end  if is_set(Editors) then  local in_text = " ";  local post_text = "";  if is_set(Chapter) then  in_text = in_text .. cfg.messages['in'] .. " "  end  if EditorCount <= 1 then  post_text = ", " .. cfg.messages['editor'];  else  post_text = ", " .. cfg.messages['editors'];  end  if (sepc ~= '.') then in_text = in_text:lower() end  Editors = in_text .. Editors .. post_text;  if (string.sub(Editors,-1,-1) == sepc)  then Editors = Editors .. " "  else Editors = Editors .. sepc .. " "  end  end  text = safejoin( {Authors, Date, Chapter, Place, Editors, tcommon }, sepc );  text = safejoin( {text, pgtext, idcommon}, sepc );  elseif is_set(Editors) then  if is_set(Date) then  if EditorCount <= 1 then  Editors = Editors .. ", " .. cfg.messages['editor'];  else  Editors = Editors .. ", " .. cfg.messages['editors'];  end  Date = " (" .. format_date(Date) ..")" .. OrigYear .. sepc .. " "  else  if EditorCount <= 1 then  Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " "  else  Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " "  end  end  text = safejoin( {Editors, Date, Chapter, Place, tcommon}, sepc );  text = safejoin( {text, pgtext, idcommon}, sepc );  else  if is_set(Date) then  if ( string.sub(tcommon,-1,-1) ~= sepc )  then Date = sepc .." " .. format_date(Date) .. OrigYear  else Date = " " .. format_date(Date) .. OrigYear  end  end -- if config.ClaseCita=="journal" and is_set(Periodical) then  if config.ClaseCita=="publicación" and is_set(Periodical) then  text = safejoin( {Chapter, Place, tcommon}, sepc );  text = safejoin( {text, pgtext, Date, idcommon}, sepc );  else  text = safejoin( {Chapter, Place, tcommon, Date}, sepc );  text = safejoin( {text, pgtext, idcommon}, sepc );  end  end   if is_set(PostScript) and PostScript ~= sepc then  text = safejoin( {text, sepc}, sepc ); --Deals with italics, spaces, etc.  text = text:sub(1,-sepc:len()-1); -- text = text:sub(1,-2); --Remove final separator (assumes that sepc is only one character)  end   text = safejoin( {text, PostScript}, sepc );   -- Now enclose the whole thing in a <span/> element  local options = {};   if is_set(config.ClaseCita) and config.ClaseCita ~= "citation" then  options.class = "citation " .. config.ClaseCita;  else  options.class = "citation";  end   if is_set(Ref) and Ref:lower() ~= "none" then  local id = Ref  if ( "harv" == Ref ) then  local names = {} --table of last names & year  if #a > 0 then  for i,v in ipairs(a) do  names[i] = v.last  if i == 4 then break end  end  elseif #e > 0 then  for i,v in ipairs(e) do  names[i] = v.last  if i == 4 then break end  end  end -- names[ #names + 1 ] = first_set(Year, anchor_year); -- Year first for legacy citations -- names[ #names + 1 ] = first_set(Year, ''); -- Year first for legacy citations  names[ #names + 1 ] = first_set(wYear, wfecha, ''); -- Year first for legacy citations  id = anchorid(names)  end  options.id = id;  end   if string.len(text:gsub("<span[^>/]*>.-</span>", ""):gsub("%b<>","")) <= 2 then  z.error_categories = {};  text = seterror('empty_citation');  z.message_tail = {};  end   if is_set(options.id) then  text = '<span id="' .. mw.uri.anchorEncode(options.id) ..'" class="' .. mw.text.nowiki(options.class) .. '">' .. text .. "</span>";  else  text = '<span class=

módulo, citas, documentación, módulo, editar, historial, purgar, módulo, citas, código, discusión, tests, comprobar, tests, subpáginas, enlaces, continuación, muestra, documentación, transcluida, desde, subpágina, salta, caja, código, este, módulo, permite, ge. Documentacion del modulo ver editar historial purgar Modulo Citas codigo doc discusion tests comprobar tests subpaginas enlaces A continuacion se muestra la documentacion transcluida desde la subpagina doc salta a la caja de codigo Uso Este modulo permite generar citas de libros noticias notas de albumes y DVD etc Modulos auxiliaresModulo Citas Configuracion Modulo Citas Whitelist Modulo Citas ValidacionFechas no llamado de momento Modulo Citas SugerenciasFuncionesEsta documentacion esta transcluida desde Modulo Citas doc Por favor anade las categorias en la subpagina de documentacion y los interwikis en Wikidata Subpaginas de este modulo local z error categories error ids message tail Include translation message hooks ID and error handling configuration settings local cfg mw loadData Mdodulo Citas Configuracion pruebas Contains a list of all recognized parameters local whitelist mw loadData Modulo Citas Whitelist pruebas local dates require Modulo Citas ValidacionFechas pruebas dates location of date validation code Modulo para formatear las fechas local DateModule require Modulo Date Date Whether variable is set or not function is set var return not var nil or var end First set variable or nil if none function first set local list for var in pairs list do if is set var then return var end end end Whether needle is in haystack function inArray needle haystack if needle nil then return false end for n v in ipairs haystack do if v needle then return n end end return false end Formatea una fecha para que se devuelva de la siguiente forma 1 de enero de 2020 Formats a date so it is returned as follows 1 de enero de 2020 function format date date string function dateFormatter text return DateModule text text d de B de Y end local stat res pcall dateFormatter date string if stat then return res else return date string end 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 name table insert z message tail seterror deprecated params error message true add error message table insert z message tail seterror deprecated params name true add error message end Populates numbered arguments in a message string using an argument table function substitute msg args return args and tostring mw message newRawMessage msg args or msg return args and mw message newRawMessage msg args plain or msg end Apply kerning to open the space between the quote mark provided by the Module and a leading or trailing quote mark contained in a title or chapter parameter s value This function will positive kern either single or double quotes Unkerned title with leading and trailing single quote marks Kerned title with leading and trailing single quote marks in real life the kerning isn t as wide as this example function kern quotes str local left lt span style padding left 0 2em gt 1 lt span gt spacing to use when title contains leading single or double quote mark local right lt span style padding right 0 2em gt 1 lt span gt spacing to use when title contains trailing single or double quote mark if str match then str string gsub str left 1 replace captured leading single or double quote with left side lt span gt end if str match then str string gsub str right 1 replace captured trailing single or double quote with right side lt span gt end return str end Wraps a string using a message list configuration taking one argument function wrap key str lower if not is set str then return elseif inArray key italic title trans italic title then str safeforitalics str end if lower true then return substitute cfg messages key lower str else return substitute cfg messages key str end end Argument wrapper This function provides support for argument mapping defined in the configuration file so that multiple names can be transparently aliased to single internal variable function argument wrapper args local origin return setmetatable ORIGIN function self k local dummy self k force the variable to be loaded return origin k end index function tbl k if origin k nil then return nil end local args list v args cfg aliases k if type list table then v origin k selectone args list redundant parameters if origin k nil then origin k Empty string not nil end elseif list nil then v origin k args list list else maybe let through instead of raising an error v origin k args k k error cfg messages unknown argument map end Empty strings not nil if v nil then v cfg defaults k or origin k end tbl rawset tbl k v return v end end Looks for a parameter s name in the whitelist Parameters in the whitelist can have three values true active supported parameters false deprecated supported parameters nil unsupported parameters function validate name local name tostring name local state whitelist basic arguments name Normal arguments if true state then return true end valid actively supported parameter if false state then deprecated parameter name 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 then return true end valid actively supported parameter if false state then deprecated parameter name parameter is deprecated but still supported return true end return false Not supported because not found or name is set to nil end Formats a comment for error trapping function errorcomment content hidden return wrap hidden and hidden error or visible error content end Sets an error condition and returns the appropriate error message The actual placement of the error message in the output is the responsibility of the calling function function seterror error id arguments raw prefix suffix local error state cfg error conditions error id prefix prefix or suffix suffix or if error state nil then error cfg messages undefined error elseif is set error state category then table insert z error categories error state category end local message substitute error state message arguments message message cfg messages help page link error state anchor cfg messages help page label z error ids error id true if inArray error id bare url missing title trans missing title and z error ids citation missing title then return false end message table concat prefix message suffix if raw true then return message error state hidden end return errorcomment message error state hidden end Formats a wiki style external link function externallinkid options local url string options id if options encode true or options encode nil then url string mw uri encode url string end return wrap id internallink options link options label options separator or amp nbsp mw ustring format s s s s options prefix url string options suffix or mw text nowiki options id end Formats a wiki style internal link function internallinkid options return wrap id internallink options link options label options separator or amp nbsp mw ustring format s s s s options prefix options id options suffix or mw text nowiki options id end Format an internal link if link is really set function internallink link label if link and link then return mw ustring format s s link label else return label end end Format an external link with error checking function externallink URL label source local error str if not is set label then label URL if is set source then error str seterror bare url missing title wrap parameter source false else error cfg messages bare url no origin end end if not checkurl URL then error str seterror bad url false error str elseif mw title getCurrentTitle inNamespaces 0 100 104 and not mw title getCurrentTitle text match Wikipedia and URL match a wikipedia org then error str seterror bad url autorreferencia false error str end return table concat URL safeforurl label error str end lt N O R M A L I Z E L C C N gt lccn normalization http www loc gov marc lccn namespace html normalization 1 Remove all blanks 2 If there is a forward slash in the string remove it and remove all characters to the right of the forward slash 3 If there is a hyphen in the string a Remove it b Inspect the substring following to the right of the removed hyphen Then and assuming that steps 1 and 2 have been carried out 1 All these characters should be digits and there should be six or less not done in this function 2 If the length of the substring is less than 6 left fill the substring with zeroes until the length is six Returns a normalized lccn for lccn to validate There is no error checking step 3 b 1 performed in this function local function normalize lccn lccn lccn lccn gsub s 1 strip whitespace if nil string find lccn then lccn lccn match 2 remove forward slash and all character to the right of it end local prefix local suffix prefix suffix lccn match 3 a remove hyphen by splitting the string into prefix and suffix if nil suffix then if there was a hyphen suffix string rep 0 6 string len suffix suffix 3 b 2 left fill the suffix with 0s if suffix length less than 6 lccn prefix suffix reassemble the lccn end return lccn end Format LCCN link and do simple error checking LCCN is a character string 8 12 characters long The length of the LCCN dictates the character type of the first 1 3 characters the rightmost eight are always digits http info uri info registry OAIHandler verb GetRecord amp metadataPrefix reg amp identifier info lccn length 8 then all digits length 9 then lccn 1 is alpha length 10 then lccn 1 and lccn 2 are both alpha or both digits length 11 then lccn 1 is alpha lccn 2 and lccn 3 are both alpha or both digits length 12 then lccn 1 and lccn 2 are both alpha function lccn id local handler cfg id handlers LCCN local err cat presume that LCCN is valid id normalize lccn id local len id len get the length of the lccn if 8 len then if id match d then if LCCN has anything but digits nil if only digits err cat seterror bad lccn set an error message end elseif 9 len then LCCN should be adddddddd if nil id match a d d d d d d d d then does it match our pattern err cat seterror bad lccn set an error message end elseif 10 len then LCCN should be aadddddddd or dddddddddd if id match d then if LCCN has anything but digits nil if only digits if nil id match a a d d d d d d d d then see if it matches our pattern err cat seterror bad lccn no match set an error message end end elseif 11 len then LCCN should be aaadddddddd or adddddddddd if not id match a a a d d d d d d d d or id match a d d d d d d d d d d then see if it matches one of our patterns err cat seterror bad lccn no match set an error message end elseif 12 len then LCCN should be aadddddddddd if not id match a a d d d d d d d d d d then see if it matches our pattern err cat seterror bad lccn no match set an error message end else err cat seterror bad lccn wrong length set an error message end return externallinkid link handler link label handler label prefix handler prefix id id separator handler separator encode handler encode err cat end Format PMID and do simple error checking PMIDs are sequential numbers beginning at 1 and counting up This code checks the PMID to see that it contains only digits and is less than test limit the value in local variable test limit will need to be updated periodically as more PMIDs are issued function pmid id local test limit 36000000 update this value as PMIDs approach local handler cfg id handlers PMID local err cat presume that PMID is valid if id match d then if PMID has anything but digits err cat seterror bad pmid set an error message else PMID is only digits local id num tonumber id convert id to a number for range testing if 1 gt id num or test limit lt id num then if PMID is outside test limit boundaries err cat seterror bad pmid set an error message end end return externallinkid link handler link label handler label prefix handler prefix id id separator handler separator encode handler encode err cat end Determines if a PMC identifier s online version is embargoed Compares the date in embargo against today s date If embargo date is in the future returns true otherwse returns false because the embargo has expired or embargo not set in this cite function is embargoed embargo 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 gt tonumber todays date then is embargo date is in the future return true still embargoed end end return false embargo expired or embargo not set end Format a PMC do simple error checking and check 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 PMCs are sequential numbers beginning at 1 and counting up This code checks the PMC to see that it contains only digits and is less than test limit the value in local variable test limit will need to be updated periodically as more PMCs are issued function pmc id embargo local test limit 10000000 update this value as PMCs approach local handler cfg id handlers PMC local err cat presume that PMC is valid local text if id match d then if PMC has anything but digits err cat seterror bad pmc set an error message else PMC is only digits local id num tonumber id convert id to a number for range testing if 1 gt id num or test limit lt id num then if PMC is outside test limit boundaries err cat seterror bad pmc set an error message end end if is embargoed embargo then text handler link handler label handler separator id err cat 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 err cat end return text end Formats a DOI and checks for DOI errors DOI names contain two parts prefix and suffix separated by a forward slash Prefix directory indicator 10 followed by a registrant code Suffix character string of any length chosen by the registrant This function checks a DOI name for prefix suffix If the doi name contains spaces or endashes or if it ends with a period or a comma this function will emit a bad doi error message DOI names are case insensitive and can incorporate any printable Unicode characters so the test for spaces endash and terminal punctuation may not be technically correct but it appears that in practice these characters are rarely if ever used in doi names function doi id inactive local cat local handler cfg id handlers DOI local text if is set inactive then 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 Wikipedia Paginas con DOI inactivos desde inactive year else table insert z error categories Wikipedia Paginas con DOI inactivos 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 inactive end if nil id match 10 s s then doi must begin with 10 must contain a fwd slash must not contain spaces or endashes and must not end with period or comma cat seterror bad doi end return text inactive cat end Formats an OpenLibrary link and checks for associated errors function openlibrary id local code id sub 1 1 local handler cfg id handlers OL if code A then return externallinkid link handler link label handler label prefix http openlibrary org authors OL id id separator handler separator encode handler encode elseif code M then return externallinkid link handler link label handler label prefix http openlibrary org books OL id id separator handler separator encode handler encode elseif code W then return externallinkid link handler link label handler label prefix http openlibrary org works OL id id separator handler separator encode handler encode else return externallinkid link handler link label handler label prefix http openlibrary org OL id id separator handler separator encode handler encode seterror bad ol 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 ModuloIdentificadores require Modulo Identificadores 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 text local valid issn true id id gsub s strip spaces hyphens and ndashes from the issn 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 valid issn ModuloIdentificadores esValidoISXN id 8 validate issn end if true valid issn then id string sub id 1 4 string sub id 5 if valid display correctly formatted version 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 This function sets default title types equivalent to the citation including type lt default value gt 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 AV media notes cite class or DVD notes cite class then if this citation is cite AV media notes or cite DVD notes if notas audiovisual cite class or notas de DVD cite class then if this citation is cite AV media notes or cite DVD notes return Media notes display AV media notes DVD media notes annotation Falta traducir elseif podcast cite class then if this citation is cite podcast return Podcast display podcast annotation elseif pressrelease cite class then if this citation is cite press release return Press release display press release annotation elseif techreport cite class then if this citation is cite techreport return Technical report display techreport annotation elseif tesis cite class then if this citation is cite thesis degree option handled after this function returns return Tesis display simple thesis annotation without degree modification end end Determines whether a URL string is valid At present the only check is whether the string appears to be prefixed with a URI scheme It is not determined whether the URI scheme is valid or whether the URL is otherwise well formed function checkurl url str Protocol relative or URL scheme return url str sub 1 2 or url str match nil end Removes irrelevant text and dashes from ISBN number Similar to that used for Special BookSources function cleanisbn isbn str return isbn str gsub 0 9X end Extract page numbers from external wikilinks in any of the page pages or at parameters for use in COinS function get coins pages pages if not is set pages then return pages end if no page numbers then we re done while true do pattern pages match w s w d pattern is the opening bracket the url and following space s url if nil pattern then break end no more urls pages pages gsub pattern remove as many instances of pattern as possible end pages pages gsub remove the brackets pages pages gsub replace endashes with hyphens pages pages gsub amp w and replace html entities amp ndash etc with hyphens do we need to replace numerical entities like amp 32 and the like return pages end Gets the display text for a wikilink like A B or B gives B function removewikilink str return str gsub function l return l gsub 1 gsub s s 1 end end Escape sequences for content that will be used for URL descriptions function safeforurl str if str match nil then table insert z message tail seterror wikilink in url true end return str gsub n amp 91 amp 93 n end Convierte un guion largo signo de negativo en un guion corto function dashtohyphen str if not is set str or str match lt gt nil then return str end return str gsub end Protects a string that will be wrapped in wiki italic markup function safeforitalics str Note We can not use lt i gt for italics as the expected behavior for italics specified by in the title is that they will be inverted i e unitalicized in the resulting references In addition lt i gt and tend to interact poorly under Mediawiki s HTML tidy if not is set str then return str else if str sub 1 1 then str lt span gt lt span gt str end if str sub 1 1 then str str lt span gt lt span gt end Remove newlines as they break italics return str gsub n end end Joins a sequence of strings together while checking for duplicate separation characters function safejoin tbl duplicate char Note we use string functions here rather than ustring functions This has considerably faster performance and should work correctly as long as the duplicate char is strict ASCII The strings in tbl may be ASCII or UTF8 local str local comp local end chr local trim for value in ipairs tbl do if value nil then value end if str then str value elseif value then if value sub 1 1 lt then Special case of values enclosed in spans and other markup comp value gsub b lt gt else comp value end if comp sub 1 1 duplicate char then trim false end chr str sub 1 1 str str lt HERE enchr end chr if end chr duplicate char then str str sub 1 2 elseif end chr then if str sub 3 1 duplicate char then str str sub 1 4 elseif str sub 5 1 duplicate char then trim true elseif str sub 4 1 duplicate char then trim true end elseif end chr then if str sub 3 1 duplicate char then trim true elseif str sub 2 1 duplicate char then trim true end elseif end chr then if str sub 2 1 duplicate char then str str sub 1 3 end end if trim then if value comp then local dup2 duplicate char if dup2 match A then dup2 dup2 end value value gsub b lt gt dup2 1 1 else value value sub 2 1 end end end str str value end end return str end Attempts to convert names to initials function reducetoinitials first local initials for word in string gmatch first S do table insert initials string sub word 1 1 Vancouver format does not include full stops end return table concat initials Vancouver format does not include spaces end Formats a list of people e g authors editors function listpeople control people local sep control sep local namesep control namesep local format control format local maximum control maximum local lastauthoramp control lastauthoramp local text local etal false if sep sub 1 1 then sep sep end if maximum nil and maximum lt 1 then return 0 end for i person in ipairs people do if is set person last then local mask person mask local one local sep one sep if maximum nil and i gt maximum then etal true break elseif mask nil then local n tonumber mask if n nil then one string rep amp mdash n else one mask sep one end else one person last local first person first if is set first then if vanc format then first reducetoinitials first end one one namesep first end if is set person link then one person link one end if is set person link and nil person link find then one one seterror bad authorlink end check for url in author link end table insert text one table insert text sep one end end local count text 2 if count gt 0 then if count gt 1 and is set lastauthoramp and not etal then text text 2 amp end text text nil end local result table concat text construct list if etal then local etal text cfg messages et al result result etal text end if necessary wrap result in lt span gt tag to format in Small Caps if scap format then result lt span class smallcaps style font variant small caps gt result lt span gt end return result count end Generates a CITEREF anchor ID function anchorid options return CITAREF table concat options return CITEREF table concat options end Gets name list from the input arguments function extractnames args list name local names local i 1 local last while true do last selectone args cfg aliases list name Last redundant parameters i if not is set last then just in case someone passed in an empty parameter break end names i last last first selectone args cfg aliases list name First redundant parameters i link selectone args cfg aliases list name Link redundant parameters i mask selectone args cfg aliases list name Mask redundant parameters i i i 1 end return names end Populates ID table from arguments using configuration settings function extractids args local id list for k v in pairs cfg id handlers do v selectone args v parameters redundant parameters if is set v then id list k v end end return id list end Takes a table of IDs and turns it into a table of formatted ID outputs function buildidlist id list options local new list handler function fallback k return index function t i return cfg id handlers k i end end for k v in pairs id list do fallback to read only cfg handler setmetatable id v fallback k if handler mode external then table insert new list handler label externallinkid handler elseif handler mode internal then table insert new list handler label internallinkid handler elseif handler mode manual then error cfg messages unknown ID mode elseif k DOI then table insert new list handler label doi v options DoiBroken elseif k LCCN then table insert new list handler label lccn v elseif k OL then table insert new list handler label openlibrary v elseif k PMC then table insert new list handler label pmc v options Embargo elseif k PMID then table insert new list handler label pmid v elseif k ISSN then table insert new list handler label issn v upper elseif k ISBN then local ISBN internallinkid handler if not checkisbn v and not is set options IgnoreISBN then ISBN ISBN seterror bad isbn false end local ISBN if options ISBNCorrecto or options ISBNSugerido or is set options IgnoreISBN then ISBN internallinkid handler else ISBN incorrecto ISBN internallinkid handler seterror bad isbn false end table insert new list handler label ISBN else error cfg messages unknown manual ID end end function comp a b used in following table sort return a 1 lt b 1 end table sort new list comp for k v in ipairs new list do new list k v 2 end return new list end function CorregirISBN ISBNIncorrecto local ModuloIdentificadores require Modulo Identificadores local ISBNCorregido Convertir mayusculas ISBNCorregido ISBNIncorrecto upper Corregir guiones ISBNCorregido ISBNCorregido gsub Eliminar ISBN del principio ISBNCorregido ISBNCorregido match ISBN or ISBNCorregido Eliminar separadores como y del final ISBNCorregido ISBNCorregido gsub if ModuloIdentificadores esValidoISBN ISBNCorregido then return ISBNCorregido end Ver si se trata de un ISBN de 13 local ISBNCorregidoSin978 ISBNCorregidoSin978 ISBNCorregido match 978 s if ISBNCorregidoSin978 and ModuloIdentificadores esValidoISBN ISBNCorregidoSin978 then 978 ISBN10 return ISBNCorregidoSin978 end ISBN de 13 al que se ha quitado 978 if ModuloIdentificadores esValidoISBN 978 ISBNCorregido then if ISBNCorregido match then return 978 ISBNCorregido elseif ISBNCorregido match then return 978 ISBNCorregido else return 978 ISBNCorregido end end 13 ISBN o 13 ISBN local ISBNCorregidoSi13 ISBNCorregidoSin13 ISBNCorregido match 13 s if ISBNCorregidoSin13 and ModuloIdentificadores esValidoISBN ISBNCorregidoSin13 then return ISBNCorregidoSin13 end end function CorregirISBNs ISBNIncorrecto1 ISBNIncorrecto2 Tomar aquel de los dos ISBNs correctos si uno de ellos es un ISBN10 y el otro el correspondiente ISBN13 local ISBN1Corregido CorregirISBN ISBNIncorrecto1 local ISBN2Corregido CorregirISBN ISBNIncorrecto2 if ISBN1Corregido and ISBN2Corregido then Ambos son correctos if ISBN1Corregido ISBN2Corregido then Ambos son iguales tras corregirse return ISBN1Corregido end Ver si uno de ellos es un ISBN10 y el otro un ISBN13 local ISBNSinDigitoControl ISBNSinDigitoControl ISBN1Corregido match if ISBNSinDigitoControl and ISBN2Corregido match 978 s ISBNSinDigitoControl then return ISBN2Corregido end ISBNSinDigitoControl ISBN2Corregido match if ISBNSinDigitoControl and ISBN1Corregido match 978 s ISBNSinDigitoControl then return ISBN1Corregido end elseif ISBN1Corregido then return ISBN1Corregido elseif ISBN2Corregido then return ISBN1Corregido end end function SugerirISBN ISBNIncorrecto local ISBNSugerido Ejemplos 0 88254 165 x gt 0 88254 165 X 0 7153 5734 4 gt 0 7153 5734 4 0 313 31807 7 gt 0 313 31807 7 ISBN 13 9788495379092 978 0 7432 9302 0 y 0 7432 9302 0 9788430948949 8430948945 8496702057 9788496702059 0198152213 978019815221 13 978 0 511 41399 5 13 9788432238406 ISBN con caracteres incorrectos ISBNSugerido CorregirISBN ISBNIncorrecto if ISBNSugerido then return ISBNSugerido end ISBN10 ISBN13 o ISBN13 ISBN10 local ISBN1 ISBN2 ISBN1 ISBN2 ISBNIncorrecto match s if is set ISBN1 and is set ISBN2 then ISBNSugerido CorregirISBNs ISBN1 ISBN2 if ISBNSugerido then return ISBNSugerido end end ISBN10 y ISBN13 o ISBN13 y ISBN10 ISBN1 ISBN2 ISBNIncorrecto match s y s if is set ISBN1 and is set ISBN2 then ISBNSugerido CorregirISBNs ISBN1 ISBN2 if ISBNSugerido then return ISBNSugerido end end ISBN10 ISBN13 o ISBN13 ISBN10 ISBN1 ISBN2 ISBNIncorrecto match s if is set ISBN1 and is set ISBN2 then ISBNSugerido CorregirISBNs ISBN1 ISBN2 if ISBNSugerido then return ISBNSugerido end end end Chooses one matching parameter from a list of parameters to consider Generates an error if more than one match is present function selectone args possible error condition index local value nil local selected local error list if index nil then index tostring index end Handle special case of replaced by empty string if index 1 then for v in ipairs possible do v v gsub if is set args v then if value nil and selected v then table insert error list v else value args v selected v end end end end for v in ipairs possible do if index nil then v v gsub index end if is set args v then if value nil and selected v then table insert error list v else value args v selected v end end end if error list gt 0 then local error str for k in ipairs error list do if error str then error str error str cfg messages parameter separator end error str error str wrap parameter k end if error list gt 1 then error str error str cfg messages parameter final separator else error str error str cfg messages parameter pair separator end error str error str wrap parameter selected table insert z message tail seterror error condition error str true end return value selected end COinS metadata see lt http ocoins info gt allows automated tools to parse the citation information function COinS data if table type data or nil next data then return end local ctx ver Z39 88 2004 treat table strictly as an array with only set values local OCinSoutput setmetatable newindex function self key value if is set value then rawset self self 1 table concat key mw uri encode removewikilink value end end if is set data Chapter then OCinSoutput rft val fmt info ofi fmt kev mtx book OCinSoutput rft genre bookitem OCinSoutput rft btitle data Chapter OCinSoutput rft atitle data Title elseif is set data Periodical then OCinSoutput rft val fmt info ofi fmt kev mtx journal OCinSoutput rft genre article OCinSoutput rft jtitle data Periodical OCinSoutput rft atitle data Title else OCinSoutput rft val fmt info ofi fmt kev mtx book OCinSoutput rft genre book OCinSoutput rft btitle data Title end OCinSoutput rft place data PublicationPlace OCinSoutput rft date data Date OCinSoutput rft series data Series OCinSoutput rft volume data Volume OCinSoutput rft issue data Issue OCinSoutput rft pages data Pages OCinSoutput rft edition data Edition OCinSoutput rft pub data PublisherName for k v in pairs data ID list do local id value cfg id handlers k COinS if k ISBN then value cleanisbn v else value v end if string sub id or 1 4 info then OCinSoutput rft id table concat id v else OCinSoutput id value end end local last first for k v in ipairs data Authors do last first v last v first if k 1 then if is set last then OCinSoutput rft aulast last end if is set first then OCinSoutput rft aufirst first end end if is set last and is set first then OCinSoutput rft au table concat last first elseif is set last then OCinSoutput rft au last end end OCinSoutput rft id data URL OCinSoutput rfr id table concat info sid mw site server match data RawPage OCinSoutput setmetatable OCinSoutput nil sort with version string always first and combine table sort OCinSoutput table insert OCinSoutput 1 ctx ver ctx ver such as Z39 88 2004 return table concat OCinSoutput amp end This is the main function doing the majority of the citation formatting function citation0 config args local ModuloIdentificadores require Modulo Identificadores Load Input Parameters The argment wrapper facillitates the mapping of multiple aliases to single internal variable local A argument wrapper args local i local PPrefix A PPrefix local PPPrefix A PPPrefix if is set A NoPP then PPPrefix PPrefix end Pick out the relevant fields from the arguments Different citation templates define different field names for the same underlying things local Authors A Authors local a extractnames args AuthorList local Coauthors A Coauthors local Editors A Editors local e extractnames args EditorList local Year A Year local wYear Year local PublicationDate A PublicationDate local OrigYear A OrigYear local Date A Date local wfecha Date local LayDate A LayDate Get title data local Title A Title local BookTitle A BookTitle local Conference A Conference local TransTitle A TransTitle local TitleNote A TitleNote local TitleLink A TitleLink local Chapter A Chapter local ChapterLink A ChapterLink local TransChapter A TransChapter local TitleType A TitleType local Degree A Degree local Docket A Docket local ArchiveURL A ArchiveURL local URL A URL local URLorigin A ORIGIN URL local ChapterURL A ChapterURL local ChapterURLorigin A ORIGIN ChapterURL local ConferenceURL A ConferenceURL local ConferenceURLorigin A ORIGIN ConferenceURL local SinURL false local Periodical A Periodical local Series A Series local Volume A Volume local Issue A Issue local Position local Page A Page local Pages dashtohyphen A Pages local At A At local Others A Others local Edition A Edition local PublicationPlace A PublicationPlace local Place A Place local Passage A Passage local PassageURL A PassageURL local PublisherName A PublisherName local UrlAccess A UrlAccess local RegistrationRequired A RegistrationRequired local SubscriptionRequired A SubscriptionRequired local Via A Via local AccessDate A AccessDate local MesAcceso A MesAcceso Inexistente en la plantilla original local AnyoAcceso A AnoAcceso Inexistente en la plantilla original local ArchiveDate A ArchiveDate local Agency A Agency local DeadURL A DeadURL local Language A Language local Format A Format local Ref A Ref local DoiBroken A DoiBroken local ID A ID local IgnoreISBN A IgnoreISBN local Embargo A Embargo local Texto1 A Texto1 local ID list extractids args local ISBNCorrecto false local ISBNSugerido if is set ID list ISBN and not is set IgnoreISBN then if ModuloIdentificadores esValidoISBN ID list ISBN then ISBNCorrecto true else ISBNSugerido SugerirISBN ID list ISBN if ISBNSugerido then ID list ISBN ISBNSugerido end end end local Lista Identificadores Formateados Lista de identificadores con enlaces y en su caso con los errores local Quote A Quote local TransQuote A TransQuote local PostScript A PostScript local LayURL A LayURL local LaySource A LaySource local Transcript A Transcript local TranscriptURL A TranscriptURL local TranscriptURLorigin A ORIGIN TranscriptURL local sepc A Separator local LastAuthorAmp A LastAuthorAmp local no tracking cats A NoTracking these are used by cite interview local Callsign A Callsign local City A City local Cointerviewers A Cointerviewers deprecated local Interviewer A Interviewer deprecated local Program A Program Parametros que no se utilizan en la plantilla inglesa local SinEd A SinEd local Extra A Extra local Traductor A Traductor local Traductores A Traductores local variables that are not cs1 parameters local page type is this needed Doesn t appear to be used anywhere local use lowercase local this page mw title getCurrentTitle Also used for COinS and for language local anchor year used in the CITEREF identifier local COinS date used in the COinS metadata check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories if not is set no tracking cats then ignore if we are already not going to categorize this page for k v in pairs cfg uncategorized namespaces do otherwise spin through the list of namespaces we don t include in error categories if this page nsText v then if we find one no tracking cats true set no trackin cats break and we re done end end end check for extra page pages or at parameters if is set Page then La categoria de la plantilla inglesa es intraducible Utilizo otro error similar if is set Pages or is set At then Page Page seterror extra pages add error message Pages unset the others At end if is set Pages then Page Page seterror redundant parameters lt code gt amp 124 pagina lt code gt y lt code gt amp 124 paginas lt code gt Pages unset the others At Passage elseif is set At then Page Page seterror redundant parameters lt code gt amp 124 pagina lt code gt y lt code gt amp 124 en lt code gt Pages unset the others At Passage elseif is set Passage then Page Page seterror redundant parameters lt code gt amp 124 pagina lt code gt y lt code gt amp 124 pasaje lt code gt Pages unset the others At Passage end elseif is set Pages then if is set At then Pages Pages seterror extra pages add error messages Pages Pages seterror redundant parameters lt code gt amp 124 paginas lt code gt y lt code gt amp 124 en lt code gt At Passage elseif is set Passage then Pages Pages seterror redundant parameters lt code gt amp 124 paginas lt code gt y lt code gt amp 124 pasaje lt code gt At Passage end elseif is set At then if is set Passage then At At seterror redundant parameters lt code gt amp 124 en lt code gt y lt code gt amp 124 pasaje lt code gt Passage end end both publication place and place location allowed if different if not is set PublicationPlace and is set Place then PublicationPlace Place promote place location to publication place end if PublicationPlace Place then Place end don t need both if they are the same 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 ClaseCita encyclopaedia then if config ClaseCita enciclopedia 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 special cases for classic book if config ClaseCita libro and is set Passage then if is set PassageURL then Passage externallink PassageURL Passage end if not is set sepc then sepc end else Passage end special cases for citation if config ClaseCita citation then for citation templates if not is set sepc then if separator is not set sepc set citation separator to its default comma end else not a citation template if not is set sepc then if separator has not been set sepc set cite xxx separator to its default period end end if not is set Ref then if ref is not set if inArray config ClaseCita citation libro publicacion web then for citation templates En la Wikipedia inglesa solo se usan citas Harvard para la clase citation Quedan habilitadas las citas Harvard para cualquier clase que contenga algun autor o editor if a gt 0 or e gt 0 then Ref harv set default ref harv end end check for specital case where separator none if none sepc lower then if separator none sepc then set it to a empty string end use lowercase sepc Others is set Others and sepc Others or Special case for cite techreport if config ClaseCita techreport then special case for cite techreport if is set Issue then cite techreport uses number which other citations aliase to issue if not is set ID then can we use ID for the number ID Issue yes use it Issue unset Issue so that number isn t duplicated in the rendered citation or COinS metadata else can t use ID so emit error message ID ID seterror redundant parameters lt code gt amp 124 id lt code gt and lt code gt amp 124 number lt code gt end end special case for cite interview elseif config ClaseCita entrevista then if is set Program then ID Program end if is set Callsign then if is set ID then ID ID sepc Callsign else ID Callsign end end if is set City then if is set ID then ID ID sepc City else ID City end end if is set Interviewer then if is set TitleType then Others sepc TitleType con Interviewer TitleType con Interviewer TitleType else Others sepc wrap interview Interviewer use lowercase Others Entrevista con Interviewer end if is set Cointerviewers then Others Others sepc Cointerviewers end else Others Others sepc Entrevista Interview end elseif is set ID then ID wrap id ID end Account for the oddity that is cite journal with pmc set and url not set if config ClaseCita journal and not is set URL and is set ID list PMC then if config ClaseCita publicacion 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 URLorigin cfg id handlers PMC parameters 1 set URLorigin to parameter name for use in error message if citation is missing a title end end if is set Texto1 and Texto1 match S then Informar la URL con el valor del campo 1 en su caso if config ClaseCita web and not is set URL and checkurl Texto1 then table insert z message tail seterror url sugerida Texto1 url true URL Texto1 Utilizar URL como texto else table insert z message tail seterror text ignored Texto1 true end end Account for the oddity that is cite conference before generation of COinS data TODO if this is only for cite conference shouldn t we be checking if config ClaseCita conference then if conferencia config ClaseCita then if is set BookTitle then Chapter Title ChapterLink TitleLink chapterlink is deprecated ChapterURL URL ChapterUrlAccess UrlAccess ChapterURLorigin URLorigin URLorigin ChapterFormat Format TransChapter TransTitle Title BookTitle Format TitleLink TransTitle URL end elseif speech config ClaseCita then Conference not cite conference or cite speech so make sure this is empty string end Account for the oddity that is cite episode before generation of COinS data cite episode is not currently supported by this module if config ClaseCita episode then local AirDate A AirDate local SeriesLink A SeriesLink local Season A Season local SeriesNumber A SeriesNumber local Network A Network local Station A Station local s n local Sep first set A SeriesSeparator A Separator or if is set Issue then table insert s cfg messages episode Issue Issue end if is set Season then table insert s cfg messages season Season end if is set SeriesNumber then table insert s cfg messages series SeriesNumber end if is set Network then table insert n Network end if is set Station then table insert n Station end Date Date or AirDate Chapter Title ChapterLink TitleLink TransChapter TransTitle Title Series TitleLink SeriesLink TransTitle Series table concat s Sep ID table concat n Sep end end of cite episode stuff 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 de Date Month Date local Day A Day if is set Day then Date Day de Date end 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 This must be done before we do COinS because here is where we get the date used in the metadata Date validation supporting code is in Modulo Citas ValidacionFechas anchor year COinS date error message dates accessdate AccessDate airdate AirDate archivedate ArchiveDate date Date doi brokendate DoiBroken embargo Embargo laydate LayDate publicationdate PublicationDate year Year if is set error message then table insert z message tail seterror bad date error message true add this error message end At this point fields may be nil if they weren t specified in the template use We can use that fact COinS metadata see lt http ocoins info gt for automated parsing of citation information local OCinSoutput COinS Periodical Periodical Chapter Chapter Title Title PublicationPlace PublicationPlace Date first set COinS date Date COinS date has correctly formatted date if Date is valid any reason to keep Date here Should we be including invalid dates in metadata Series Series Volume Volume Issue Issue Pages get coins pages first set Page Pages At pages stripped of external links Edition Edition PublisherName PublisherName URL first set URL ChapterURL Authors a ID list ID list RawPage this page prefixedText if is set Periodical and not is set Chapter and is set Title then Chapter Title ChapterLink TitleLink TransChapter TransTitle Title TitleLink TransTitle end Now perform various field substitutions We also add leading spaces and surrounding markup and punctuation to the various parts of the citation but only when they are non nil if not is set Authors then local Maximum tonumber A DisplayAuthors Preserve old style implicit et al if not is set Maximum and a 9 then Maximum 8 table insert z message tail seterror implict etal author true elseif not is set Maximum then Maximum a 1 end local control sep A AuthorSeparator namesep first set A AuthorNameSeparator A NameSeparator or format A AuthorFormat maximum Maximum lastauthoramp LastAuthorAmp If the coauthor field is also used prevent ampersand and et al formatting if is set Coauthors then control lastauthoramp nil control maximum a 1 end Authors listpeople control a 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 Utilizo temporalmente los coautores como autores Authors Coauthors Coauthors nil end local EditorCount if not is set Editors then local Maximum tonumber A DisplayEditors Preserve old style implicit et al if not is set Maximum and e 4 then Maximum 3 table insert z message tail seterror implict etal editor true elseif not is set Maximum then Maximum e 1 end local control sep A EditorSeparator namesep first set A EditorNameSeparator A NameSeparator or format A EditorFormat maximum Maximum lastauthoramp LastAuthorAmp Editors EditorCount listpeople control e else EditorCount 1 end local Cartography local Scale if config ClaseCita map then if not is set Authors and is set PublisherName then Authors PublisherName PublisherName end Cartography A Cartography if is set Cartography then Cartography sepc wrap cartography Cartography use lowercase end Scale A Scale if is set Scale then Scale sepc Scale end end if not is set URL and not is set ChapterURL and not is set ArchiveURL and not is set ConferenceURL and not is set TranscriptURL then sinURL true Test if cite web or cite podcast url is missing or empty if inArray config ClaseCita web podcast then table insert z message tail seterror cite web url true end Test if format is given without giving a URL if is set Format then Format Format seterror format missing url end end Test if citation has no title if not is set Chapter and not is set Title and not is set Periodical and not is set Conference and not is set TransTitle and not is set TransChapter and not is set Passage then table insert z message tail seterror citation missing title true end Format is set Format and wrap format Format or is set Format and Format or local OriginalURL URL DeadURL DeadURL lower if is set ArchiveURL then if DeadURL no then URL ArchiveURL URLorigin A ORIGIN ArchiveURL end end Format chapter article title if is set Chapter and is set ChapterLink then Chapter ChapterLink Chapter end if is set Periodical and is set Title then Chapter wrap italic title Chapter TransChapter wrap trans italic title TransChapter else Chapter kern quotes Chapter if necessary separate chapter title s leading and trailing quote marks from Module provided quote marks Chapter wrap quoted title Chapter TransChapter wrap trans quoted title TransChapter end local TransError if is set TransChapter then if not is set Chapter then TransError seterror trans missing chapter else TransChapter TransChapter end end Chapter Chapter TransChapter if is set Chapter then if not is set ChapterLink then if is set ChapterURL then Chapter externallink ChapterURL Chapter TransError if not is set URL then Chapter Chapter Format Format end elseif is set URL then Chapter externallink URL Chapter TransError Format URL Format else Chapter Chapter TransError end elseif is set ChapterURL then Chapter Chapter externallink ChapterURL nil ChapterURLorigin TransError else Chapter Chapter TransError end Chapter Chapter sepc with end space elseif is set ChapterURL then Chapter externallink ChapterURL nil ChapterURLorigin sepc end Format main title if is set TitleLink and is set Title then Title TitleLink Title end if is set Traductor and is set Traductores then Traductor wrap traductores Traductores seterror redundant parameters lt code gt amp 124 traductor lt code gt y lt code gt amp 124 traductores lt code gt elseif is set Traductor then Traductor wrap traductor Traductor elseif is set Traductores then Traductor wrap traductores Traductores end Traductores if is set Periodical then Title kern quotes Title if necessary separate title s leading and trailing quote marks from Module provided quote marks Title wrap quoted title Title TransTitle wrap trans quoted title TransTitle elseif inArray config ClaseCita web news pressrelease conference podcast and elseif inArray config ClaseCita web noticia pressrelease conference podcast and not is set Chapter then Title kern quotes Title if necessary separate title s leading and trailing quote marks from Module provided quote marks Title wrap quoted title Title TransTitle wrap trans quoted title TransTitle else Title wrap italic title Title TransTitle wrap trans italic title TransTitle end TransError if is set TransTitle then if not is set Title then TransError seterror trans missing title else TransTitle TransTitle end end Title Title Traductor TransTitle if is set Title then if not is set TitleLink and is set URL then Title externallink URL Title URL origin UrlAccess TransError Format URL TieneURL true Format else Title Title TransError end end if is set Place then Place wrap written Place use lowercase sepc end if is set Conference then if is set ConferenceURL then Conference externallink ConferenceURL Conference end Conference sepc Conference elseif is set ConferenceURL then Conference sepc externallink ConferenceURL nil ConferenceURLorigin end if not is set Position then local Minutes A Minutes if is set Minutes then Position Minutes cfg messages minutes else local Time A Time if is set Time then local TimeCaption A TimeCaption if not is set TimeCaption then TimeCaption cfg messages event if sepc then TimeCaption TimeCaption lower end end Position TimeCaption Time end end else Position Position At end if not is set Page then if is set Pages then if is set Periodical and not inArray config ClaseCita encyclopaedia web book news podcast then not inArray config ClaseCita enciclopedia web libro noticia podcast then Pages Pages elseif tonumber Pages nil then Pages sepc PPrefix Pages else Pages sepc PPPrefix Pages end end else if is set Periodical and not inArray config ClaseCita encyclopaedia web book news podcast then not inArray config ClaseCita enciclopedia web libro noticia podcast then Page Page else Page sepc PPrefix Page end end At is set At and sepc At or Passage is set Passage and sepc Passage or Position is set Position and sepc Position or if config ClaseCita map then local Section A Section local Inset A Inset if first set Pages Page At nil or sepc then if is set Section then Section wrap section Section true end if is set Inset then Inset wrap inset Inset true end else if is set Section then Section sepc wrap section Section use lowercase if is set Inset then Inset wrap inset Inset true end elseif is set Inset then Inset sepc wrap inset Inset use lowercase end end At At Section Inset 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 Poner en minusculas el primer caracter del idioma si esta en mayusculas Language Language gsub u string lower if Language espanol or Language castellano or Language es or Language match es then Language No mostrar el idioma espanol else local name mw language fetchLanguageName Language lower es experiment this seems to return correct ISO 639 1 language names if is set name then Language wrap language name else Language wrap language Language no match use parameter s value end end else Language Asegurarnos de que el idioma no es nulo end handle type parameter for those CS1 citations that have default values if inArray config ClaseCita AV media notes DVD notes podcast pressrelease techreport thesis then if inArray config ClaseCita notas audiovisual notas de DVD podcast pressrelease techreport tesis then TitleType set titletype config ClaseCita TitleType if is set Degree and Tesis TitleType then special case for cite thesis TitleType Tesis de Degree end end if is set TitleType then if type parameter is specified TitleType TitleType display it in parentheses end TitleNote is set TitleNote and sepc TitleNote or if is set Edition then if is set SinEd then No existe el parametro en el modulo de la wikipedia inglesa Edition wrap sin edicion Edition No existe el parametro en el modulo de la wikipedia inglesa else Edition wrap edition Edition end else Edition end Issue is set Issue and Issue or Series is set Series and sepc Series or OrigYear is set OrigYear and OrigYear or Agency is set Agency and sepc Agency or if is set Volume then if Volume match d or Volume match MDCLXVI negrita solamente si el capitulo esta reflejado como cifra decimal o numeros romanos then Volume lt b gt dashtohyphen Volume lt b gt else Volume sepc Volume end end This code commented out while discussion continues until after week of 2014 03 23 live module update if is set Volume then if mw ustring len Volume gt 4 then Volume sepc Volume else Volume lt b gt hyphentodash Volume lt b gt if is set Series then Volume sepc Volume end end end 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 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 Via wrap via Via end if UrlAccess registration then RegistrationRequired true end if is set SubscriptionRequired then 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 if is set AccessDate then if is set AccessDate or is set AnyoAcceso then Test if accessdate is given without giving a URL if sinURL then table insert z message tail seterror accessdate missing url true AccessDate else if is set AccessDate then if is set MesAcceso and is set AnyoAcceso then AccessDate AccessDate seterror redundant parameters lt code gt amp 124 fechaacceso lt code gt lt code gt amp 124 anoacceso lt code gt y lt code gt amp 124 mesacceso lt code gt elseif is set MesAcceso then AccessDate AccessDate seterror redundant parameters lt code gt amp 124 fechaacceso lt code gt y lt code gt amp 124 mesacceso lt code gt elseif is set AnyoAcceso then if string find AccessDate sde s then AccessDate AccessDate de AnyoAcceso else AccessDate AccessDate seterror redundant parameters lt code gt amp 124 fechaacceso lt code gt y lt code gt amp 124 Anoacceso lt code gt end end elseif is set MesAcceso then AccessDate MesAcceso de AnyoAcceso else AccessDate AnyoAcceso end local retrv text cfg messages retrieved if sepc then retrv text retrv text lower end AccessDate lt span class reference accessdate gt sepc substitute retrv text format date AccessDate lt span gt end elseif is set MesAcceso then end if is set ID then ID sepc ID end if tesis config ClaseCita and is set Docket then ID sepc Docket Docket ID end Lista Identificadores Formateados buildidlist ID list DoiBroken DoiBroken IgnoreISBN IgnoreISBN Embargo Embargo ISBNCorrecto ISBNCorrecto ISBNSugerido ISBNSugerido if is set URL then URL externallink URL nil URLorigin UrlAccess end Set postscript default if not is set PostScript then if postscript has not been set Postscript is nil which is the default for citation and if config ClaseCita citation then this template is not a citation template PostScript must be a cite xxx template so set postscript to default period end else if PostScript lower none then if postscript none then PostScript no postscript end end if is set Quote or is set TransQuote then Eliminar comillas de Quote if Quote sub 1 1 and Quote sub 1 1 or Quote sub 1 1 and Quote sub 1 1 then Quote Quote sub 2 2 end No anadir el punto final a la cita si el campo Quote ya incluye un punto if Quote sub 1 1 or Quote sub 1 1 or Quote sub 1 1 then PostScript end Eliminar comillas de TransQuote if TransQuote sub 1 1 and TransQuote sub 1 1 or Quote sub 1 1 and Quote sub 1 1 then TransQuote TransQuote sub 2 2 end No anadir el punto final a la cita si el campo TransQuote ya incluye un punto if TransQuote sub 1 1 or TransQuote sub 1 1 or TransQuote sub 1 1 then PostScript end Quote Quote wrap trans quoted title TransQuote TransQuote wrap trans quoted title TransQuote Quote sepc wrap quoted text Quote end local Archived if is set ArchiveURL then if not is set ArchiveDate then ArchiveDate seterror archive missing date else ArchiveDate format date ArchiveDate end if no DeadURL then local arch text cfg messages archived if sepc then arch text arch text lower end Archived sepc substitute cfg messages archived not dead externallink ArchiveURL arch text ArchiveDate if not is set OriginalURL then Archived Archived seterror archive missing url end elseif is set OriginalURL then local arch text cfg messages archived dead if sepc then arch text arch text lower end Archived sepc substitute arch text externallink OriginalURL cfg messages original ArchiveDate else local arch text cfg messages archived missing if sepc then arch text arch text lower end Archived sepc substitute arch text seterror archive missing url ArchiveDate end else Archived end local Lay if is set LayURL then if is set LayDate then LayDate format date LayDate end if is set LaySource then LaySource amp ndash safeforitalics LaySource else LaySource end if sepc then Lay sepc externallink LayURL cfg messages lay summary LaySource LayDate else Lay sepc externallink LayURL cfg messages lay summary lower LaySource LayDate end else Lay end if is set Transcript then if is set TranscriptURL then Transcript externallink TranscriptURL Transcript end elseif is set TranscriptURL then Transcript externallink TranscriptURL nil TranscriptURLorigin end local Publisher if is set Periodical and not inArray config ClaseCita encyclopaedia web pressrelease podcast then not inArray config ClaseCita enciclopedia web pressrelease podcast then if is set PublisherName then if is set PublicationPlace then Publisher PublicationPlace PublisherName else Publisher PublisherName end elseif is set PublicationPlace then Publisher PublicationPlace else Publisher end if is set PublicationDate then if is set Publisher then Publisher Publisher wrap published PublicationDate else Publisher PublicationDate end end if is set Publisher then Publisher Publisher end else if is set PublicationDate then PublicationDate wrap published format date PublicationDate end if is set PublisherName then if is set PublicationPlace then Publisher sepc PublicationPlace PublisherName PublicationDate else Publisher sepc PublisherName PublicationDate end elseif is set PublicationPlace then Publisher sepc PublicationPlace PublicationDate else Publisher PublicationDate end end Several of the above rely upon detecting this as nil so do it last if is set Periodical then if is set Title or is set TitleNote then Periodical sepc wrap italic title Periodical else Periodical wrap italic title Periodical end end Handle the oddity that is cite speech This code overrides whatever may be the value assigned to TitleNote through department and forces it to be Speech so that the annotation directly follows the title parameter value in the citation rather than the event parameter value if provided if speech config ClaseCita then cite speech only TitleNote Speech annotate the citation if is set Periodical then if Periodical perhaps because of an included website or journal parameter if is set Conference then and if event is set Conference Conference sepc then add appropriate punctuation to the end of the Conference variable before rendering end end end Piece all bits together at last Here all should be non nil We build things this way because it is more efficient in LUA not to keep reassigning to the same string variable over and over local tcommon if inArray config ClaseCita journal citation and is set Periodical then if inArray config ClaseCita publicacion citation and is set Periodical then if is set Others then Others Others sepc end tcommon safejoin Others Title TitleNote Conference Periodical Format TitleType Scale Series Language Cartography Edition Publisher Agency Volume Issue sepc else tcommon safejoin Title TitleNote Conference Periodical Format TitleType Scale Series Language Volume Issue Others Cartography Edition Publisher Agency sepc end if Lista Identificadores Formateados gt 0 then Lista Identificadores Formateados safejoin sepc table concat Lista Identificadores Formateados sepc ID sepc else Lista Identificadores Formateados ID end local idcommon safejoin Lista Identificadores Formateados URL Archived AccessDate Via SubscriptionRequired Lay Quote sepc local text local pgtext Position Page Pages At Passage if is set Authors then if is set Coauthors then Authors Authors A AuthorSeparator Coauthors end if is set Date then Date format date Date OrigYear sepc elseif string sub Authors 1 1 sepc then Authors Authors else Authors Authors sepc end if is set Editors then local in text local post text if is set Chapter then in text in text cfg messages in end if EditorCount lt 1 then post text cfg messages editor else post text cfg messages editors end if sepc then in text in text lower end Editors in text Editors post text if string sub Editors 1 1 sepc then Editors Editors else Editors Editors sepc end end text safejoin Authors Date Chapter Place Editors tcommon sepc text safejoin text pgtext idcommon sepc elseif is set Editors then if is set Date then if EditorCount lt 1 then Editors Editors cfg messages editor else Editors Editors cfg messages editors end Date format date Date OrigYear sepc else if EditorCount lt 1 then Editors Editors cfg messages editor sepc else Editors Editors cfg messages editors sepc end end text safejoin Editors Date Chapter Place tcommon sepc text safejoin text pgtext idcommon sepc else if is set Date then if string sub tcommon 1 1 sepc then Date sepc format date Date OrigYear else Date format date Date OrigYear end end if config ClaseCita journal and is set Periodical then if config ClaseCita publicacion and is set Periodical then text safejoin Chapter Place tcommon sepc text safejoin text pgtext Date idcommon sepc else text safejoin Chapter Place tcommon Date sepc text safejoin text pgtext idcommon sepc end end if is set PostScript and PostScript sepc then text safejoin text sepc sepc Deals with italics spaces etc text text sub 1 sepc len 1 text text sub 1 2 Remove final separator assumes that sepc is only one character end text safejoin text PostScript sepc Now enclose the whole thing in a lt span gt element local options if is set config ClaseCita and config ClaseCita citation then options class citation config ClaseCita else options class citation end if is set Ref and Ref lower none then local id Ref if harv Ref then local names table of last names amp year if a gt 0 then for i v in ipairs a do names i v last if i 4 then break end end elseif e gt 0 then for i v in ipairs e do names i v last if i 4 then break end end end names names 1 first set Year anchor year Year first for legacy citations names names 1 first set Year Year first for legacy citations names names 1 first set wYear wfecha Year first for legacy citations id anchorid names end options id id end if string len text gsub lt span gt gt lt span gt gsub b lt gt lt 2 then z error categories text seterror empty citation z message tail end if is set options id then text lt span id mw uri anchorEncode options id class mw text nowiki options class gt text lt span gt else text lt span class, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos