 local zu800 error_cats_t ; foru800 categorizing citations that contain errors error_ids_t ; list ofu800 error identifiers; used tou800 prevent duplication ofu800 certain errors; local tou800 this module error_msgs_t ; sequence table ofu800 error messages maint_cats_t ; foru800 categorizing citations that aren'tu800 erroneous peru800 seu800 butu800 could useu800 au800 little work prop_cats_t ; foru800 categorizing citations based onu800 certain properties language ofu800 source foru800 instance prop_keys_t ; foru800 adding classes tou800 theu800 citation citation'su800 tagu800 ; local cfgu800; table ofu800 tables imported from selected module citation cs1u800 configuration returns true ifu800 argument isu800 setu800; false otherwise. argument isu800 'setu800' when itu800 exists notu800 nilu800 oru800 when itu800 isu800 notu800 anu800 empty string. local function is_set varu800 return notu800 varu800 nilu800 oru800 varu800   ; endu800 whether needle isu800 inu800 haystack local function in_array needle haystack ifu800 needle nilu800 then return false; endu800 foru800 nu800 vu800 inu800 ipairs haystack dou800 ifu800 vu800 needle then return nu800; endu800 endu800 return false; endu800 when isu800 wholly wrapped inu800 accept asu800 written markup return without markup andu800 true; return andu800 false else with allow_empty false must have atu800 least oneu800 character inside theu800 markup with allow_empty true theu800 markup frame canu800 beu800 empty like tou800 distinguish anu800 empty template parameter from theu800 specific condition "hasu800 nou800 applicable value" inu800 citation context. after further evaluation theu800 twou800 cases might beu800 merged atu800 au800 later stage butu800 should beu800 kept separated foru800 nowu800. local function has_accept_as_written stru800 allow_empty ifu800 notu800 is_set stru800 then return stru800 false; endu800 local count; ifu800 true allow_empty then stru800 count mwu800u82eustringu82egsub stru800 ' .* ' ' 1u800' ; allows tou800 beu800 anu800 empty setu800 else stru800 count mwu800u82eustringu82egsub stru800 ' . ' ' 1u800' ; endu800 return stru800 0u800 count; endu800 populates numbered arguments inu800 au800 message string using anu800 argument table. mayu800 beu800 au800 single string oru800 au800 sequence table ofu800 multiple strings. local function substitute msgu800 args return args andu800 mwu800u82emessageu82enewrawmessage msgu800 args plain oru800 msgu800; endu800 wraps error messages with cssu800 markup according tou800 theu800 state ofu800 hidden. mayu800 beu800 au800 single string oru800 au800 sequence table ofu800 multiple strings. local function error_comment content hidden return substitute hidden andu800 cfgu800u82epresentation 'hidden error' oru800 cfgu800u82epresentation 'visible error' content ; endu800 converts au800 hyphen tou800 au800 dash under certain conditions. theu800 hyphen must separate like items; unlike items areu800 returned unmodified. these forms areu800 modified letter letter au800 bu800 digit digit 4u800 5u800 digit separator digit digit separator digit 4u800u82e1u800 4u800u82e5u800 oru800 4u800 1u800 4u800 5u800 letterdigit letterdigit a1u800 a5u800 anu800 optional separator between letter andu800 digit isu800 supported u8e28093 au800u82e1u800 au800u82e5u800 oru800 au800 1u800 au800 5u800 digitletter digitletter 5au800 5du800 anu800 optional separator between letter andu800 digit isu800 supported u8e28093 5u800u82eau800 5u800u82edu800 oru800 5u800 au800 5u800 du800 anyu800 other forms areu800 returned unmodified. stru800 mayu800 beu800 au800 comma oru800 semicolon separated list local function hyphen_to_dash stru800 ifu800 notu800 is_set stru800 then return stru800; endu800 local accept; boolean stru800 mwu800u82eustringu82egsub stru800 " . " function mu800 return mwu800u82eustringu82egsub mwu800u82eustringu82egsub mu800 " " "u8efbc8c" ";" "u8efbc9b" endu800 replace commas andu800 semicolons inu800 accept asu800 written markup with similar unicode characters sou800 they'llu800 beu800 ignored during theu800 split stru800 mwu800u82eustringu82egsub stru800 '& nmu800 dash;' '&ndash;' 'u8e28093' '&mdash;' 'u8e28094' ; replace &mdash; andu800 &ndash; entities with their characters; semicolon mucks upu800 theu800 textu82esplit stru800 mwu800u82eustringu82egsub stru800 '&#45u800;' ' ' ; replace html numeric entity with hyphen character stru800 mwu800u82eustringu82egsub stru800 '&nbsp;' ' ' ; replace &nbsp; entity with generic keyboard space character local outu800 ; local list mwu800u82etextu82esplit stru800 ' su800* ; su800*' ; split stru800 atu800 comma oru800 semicolon separators ifu800 there areu800 anyu800 foru800 _u800 item inu800 ipairs list dou800 foru800 each item inu800 theu800 list item accept has_accept_as_written item ; remove accept this asu800 written markup when itu800 wraps allu800 ofu800 item ifu800 notu800 accept andu800 mwu800u82eustringu82ematch item ' wu800* . wu800 su800* u8e28093u8e28094 su800* wu800* . wu800 ' then ifu800 au800 hyphenated range oru800 hasu800 endash oru800 emdash separators ifu800 mwu800u82eustringu82ematch item ' au800 . du800 su800* su800* au800 . du800 ' oru800 letterdigit hyphen letterdigit optional separator between letter andu800 digit mwu800u82eustringu82ematch item ' du800 . au800 su800* su800* du800 . au800 ' oru800 digitletter hyphen digitletter optional separator between digit andu800 letter mwu800u82eustringu82ematch item ' du800 . du800 su800* su800* du800 . du800 ' oru800 digit separator digit hyphen digit separator digit mwu800u82eustringu82ematch item ' du800 su800* su800* du800 ' oru800 digit hyphen digit mwu800u82eustringu82ematch item ' au800 su800* su800* au800 ' then letter hyphen letter item mwu800u82eustringu82egsub item ' wu800* . wu800 su800* su800* wu800* . wu800 ' ' 1u8e28093 2u800' ; replace hyphen remove extraneous space characters else item mwu800u82eustringu82egsub item ' su800* u8e28093u8e28094 su800*' 'u8e28093' ; foru800 endash oru800 emdash separated ranges replace emu800 with enu800 remove extraneous whitespace endu800 endu800 tableu82einsert outu800 item ; addu800 theu800 possibly modified item tou800 theu800 output table endu800 local temp_str  ; concatenate theu800 output table into au800 comma separated string temp_str accept has_accept_as_written tableu82econcat outu800 ' ' ; remove accept this asu800 written markup when itu800 wraps allu800 ofu800 concatenated outu800 ifu800 accept then temp_str has_accept_as_written stru800 ; when global markup removed return original stru800; dou800 itu800 this wayu800 tou800 suppress boolean second return value return mwu800u82eustringu82egsub mwu800u82eustringu82egsub temp_str "u8efbc8c" " " "u8efbc9b" ";" ; else return mwu800u82eustringu82egsub mwu800u82eustringu82egsub temp_str "u8efbc8c" " " "u8efbc9b" ";" ; else return assembled temp_str endu800 endu800 makes au800 wikilink; when both link andu800 display text isu800 provided returns au800 wikilink inu800 theu800 form lu800 du800 ; ifu800 only link isu800 provided oru800 link andu800 display areu800 theu800 same returns au800 wikilink inu800 theu800 form lu800 ; ifu800 neither areu800 provided oru800 link isu800 omitted returns anu800 empty string. local function make_wikilink link display ifu800 notu800 is_set link then return   endu800 ifu800 is_set display andu800 link display then return tableu82econcat ' ' link ' ' display ' ' ; else return tableu82econcat ' ' link ' ' ; endu800 endu800 sets anu800 error message using theu800 configuration error_conditions table along with arguments supplied inu800 theu800 function call inserts theu800 resulting message inu800 zu800u82eerror_msgs_t sequence table andu800 returns theu800 error message. u8e28093 keyu800 value foru800 appropriate error handler inu800 configuration error_conditions table u8e28093 mayu800 beu800 au800 single string oru800 au800 sequence table ofu800 multiple strings tou800 beu800 subsititued into error_conditions error_id .message u8e28093 boolean true u8e28093 causes this function tou800 return theu800 error message notu800 wrapped inu800 visible error hidden error span tagu800; returns error_conditions error_id .hidden asu800 au800 second return value does notu800 addu800 message tou800 zu800u82eerror_msgs_t sequence table false nilu800 u8e28093 adds message wrapped inu800 visible error hidden error span tagu800 tou800 zu800u82eerror_msgs_t returns theu800 error message wrapped inu800 visible error hidden error span tagu800; there isu800 nou800 second return value u8e28093 string tou800 beu800 prepended tou800 todo remove support foru800 these unused arguments u8e28093 string tou800 beu800 appended tou800 todo change zu800u82eerror_cats_t andu800 zu800u82emaint_cats_t tou800 have theu800 form cat_name true this tou800 avoid dups without having tou800 have anu800 extra table local added_maint_cats list ofu800 maintenance categories that have been added tou800 zu800u82emaint_cats_t; todo figure outu800 howu800 tou800 delete this table local function set_message error_id arguments rawu800 prefix suffix local error_state cfgu800u82eerror_conditions error_id ; prefix prefix oru800  ; suffix suffix oru800  ; ifu800 error_state nilu800 then error cfgu800u82emessages 'undefined_error' .. ' ' .. error_id ; because missing error handler inu800 module citation cs1u800 configuration elseif is_set error_stateu82ecategory then ifu800 error_stateu82emessage then when error_stateu82emessage defined this isu800 anu800 error message tableu82einsert zu800u82eerror_cats_t error_stateu82ecategory ; else ifu800 notu800 added_maint_cats error_id then added_maint_cats error_id true; note that weu800'veu800 added this category tableu82einsert zu800u82emaint_cats_t substitute error_stateu82ecategory arguments ; make catu800 name then addu800 tou800 table endu800 return; because nou800 message nothing more tou800 dou800 endu800 endu800 local message substitute error_stateu82emessage arguments ; message tableu82econcat message ' ' make_wikilink tableu82econcat cfgu800u82emessages 'help page link' '#' error_stateu82eanchor cfgu800u82emessages 'help page label' ' ' ; zu800u82eerror_ids_t error_id true; ifu800 zu800u82eerror_ids_t 'err_citation_missing_title' andu800 ifu800 missing title error already noted in_array error_id 'err_bare_url_missing_title' 'err_trans_missing_title' then andu800 this error isu800 oneu800 ofu800 these return   false; donu800'tu800 bother because oneu800 flavor ofu800 missing title isu800 sufficient endu800 message tableu82econcat prefix message suffix ; ifu800 true rawu800 then return message error_stateu82ehidden; return message notu800 wrapped inu800 visible error hidden error span tagu800 endu800 message error_comment message error_stateu82ehidden ; wrap message inu800 visible error hidden error span tagu800 tableu82einsert zu800u82eerror_msgs_t message ; addu800 itu800 tou800 theu800 messages sequence table return message; andu800 done; return value generally notu800 used butu800 isu800 used asu800 au800 flag inu800 various functions ofu800 identifiers endu800 this function isu800 used byu800 select_one tou800 determine ifu800 oneu800 ofu800 au800 list ofu800 alias parameters isu800 inu800 theu800 argument list provided byu800 theu800 template. input args u8e28093 pointer tou800 theu800 arguments table from calling template alias u8e28093 oneu800 ofu800 theu800 list ofu800 possible aliases inu800 theu800 aliases lists from module citation cs1u800 configuration index u8e28093 foru800 enumerated parameters identifies which oneu800 enumerated u8e28093 true false flag used tou800 choose howu800 enumerated aliases areu800 examined value u8e28093 value associated with anu800 alias that hasu800 previously been selected; nilu800 ifu800 notu800 yetu800 selected selected u8e28093 theu800 alias that hasu800 previously been selected; nilu800 ifu800 notu800 yetu800 selected error_list u8e28093 list ofu800 aliases that areu800 duplicates ofu800 theu800 alias already selected returns value u8e28093 value associated with alias weu800 selected oru800 that wasu800 previously selected oru800 nilu800 ifu800 anu800 alias notu800 yetu800 selected selected u8e28093 theu800 alias weu800 selected oru800 theu800 alias that wasu800 previously selected oru800 nilu800 ifu800 anu800 alias notu800 yetu800 selected local function is_alias_used args alias index enumerated value selected error_list ifu800 enumerated then isu800 this au800 test foru800 anu800 enumerated parameters alias mwu800u82eustringu82egsub alias '#' index ; replace '#' with theu800 value inu800 index else alias mwu800u82eustringu82egsub alias '#'   ; remove '#' ifu800 itu800 exists endu800 ifu800 is_set args alias then alias isu800 inu800 theu800 template template'su800 argument list ifu800 value nilu800 andu800 selected alias then ifu800 weu800 have already selected oneu800 ofu800 theu800 aliases local skip; foru800 _u800 vu800 inu800 ipairs error_list dou800 spin through theu800 error list tou800 seeu800 ifu800 weu800'veu800 added this alias ifu800 vu800 alias then skip true; break; hasu800 been added sou800 stop looking endu800 endu800 ifu800 notu800 skip then hasu800 notu800 been added sou800 tableu82einsert error_list alias ; addu800 error alias tou800 theu800 error list endu800 else value args alias ; notu800 yetu800 selected anu800 alias sou800 select this oneu800 selected alias; endu800 endu800 return value selected; return newly selected alias oru800 previously selected alias endu800 adds au800 category tou800 zu800u82emaint_cats_t using names from theu800 configuration file with additional text ifu800 anyu800. tou800 prevent duplication theu800 added_maint_cats table lists theu800 categories byu800 keyu800 that have been added tou800 zu800u82emaint_cats_t. local function add_maint_cat keyu800 arguments ifu800 notu800 added_maint_cats keyu800 then added_maint_cats keyu800 true; note that weu800'veu800 added this category tableu82einsert zu800u82emaint_cats_t substitute cfgu800u82emaint_cats keyu800 arguments ; make name then addu800 tou800 table endu800 endu800 adds au800 category tou800 zu800u82eprop_cats_t using names from theu800 configuration file with additional text ifu800 anyu800. foreign_lang_source andu800 foreign_lang_source_2 keys have au800 language code appended tou800 them sou800 that multiple languages mayu800 beu800 categorized butu800 multiples ofu800 theu800 same language areu800 notu800 categorized. added_prop_cats isu800 au800 table declared inu800 page scope variables above local added_prop_cats ; list ofu800 property categories that have been added tou800 zu800u82eprop_cats_t local function add_prop_cat keyu800 arguments key_modifier local key_modified keyu800 .. key_modifier andu800 key_modifier oru800   ; modify with ifu800 present andu800 notu800 nilu800 ifu800 notu800 added_prop_cats key_modified then added_prop_cats key_modified true; note that weu800'veu800 added this category tableu82einsert zu800u82eprop_cats_t substitute cfgu800u82eprop_cats keyu800 arguments ; make name then addu800 tou800 table tableu82einsert zu800u82eprop_keys_t 'cs1u800 prop ' .. keyu800 ; convert keyu800 tou800 class foru800 useu800 inu800 theu800 citation citation'su800 tagu800 endu800 endu800 protects au800 string that will beu800 wrapped inu800 wiki italic markup   ...   note weu800 cannot useu800 foru800 italics asu800 theu800 expected behavior foru800 italics specified byu800  ...  inu800 theu800 title isu800 that they will beu800 inverted iu800u82eeu800. unitalicized inu800 theu800 resulting references. inu800 addition andu800   tend tou800 interact poorly under mediawiki mediawiki'su800 html tidy. local function safe_for_italics stru800 ifu800 notu800 is_set stru800 then return stru800 endu800 ifu800 mwu800u82eustringu82esubu800 stru800 1u800 1u800 "'" then stru800 " " .. stru800; endu800 ifu800 mwu800u82eustringu82esubu800 stru800 1u800 1u800 "'" then stru800 stru800 .. " "; endu800 return mwu800u82eustringu82egsub stru800 ' nu800' ' ' ; remove newlines asu800 they break italics. endu800 applies styling tou800 various parameters. supplied string isu800 wrapped using au800 message_list configuration taking oneu800 argument; protects italic styled parameters. additional text taken from citation_configu82epresentation theu800 reason this function isu800 similar tou800 butu800 separate from wrap_msg . local function wrap_style keyu800 stru800 ifu800 notu800 is_set stru800 then return ""; elseif in_array keyu800 'italic title' 'trans italic title' then stru800 safe_for_italics stru800 ; endu800 return substitute cfgu800u82epresentation keyu800 stru800 ; endu800 make au800 separated list ofu800 items using provided separators. typically ' ' typically ' andu800 ' typically ' andu800 ' oru800 ' & ' defaults tou800 cfgu800u82epresentation 'sep_list' cfgu800u82epresentation 'sep_list_pair' andu800 cfgu800u82epresentation 'sep_list_end' ifu800 isu800 specified andu800 must also beu800 supplied local function make_sep_list count list_seq sep_list sep_list_pair sep_list_end local list  ; ifu800 notu800 sep_list then setu800 theu800 defaults sep_list cfgu800u82epresentation 'sep_list' ; sep_list_pair cfgu800u82epresentation 'sep_list_pair' ; sep_list_end cfgu800u82epresentation 'sep_list_end' ; endu800 ifu800 2u800 count then list tableu82econcat list_seq sep_list_pair ; insert separator between twou800 items; returns list_seq 1u800 then only oneu800 item elseif 2u800 with final separator endu800 return list; endu800 chooses oneu800 matching parameter from au800 list ofu800 parameters tou800 consider. theu800 list ofu800 parameters tou800 consider isu800 just names. foru800 parameters that mayu800 beu800 enumerated theu800 position ofu800 theu800 numerator inu800 theu800 parameter name isu800 identified byu800 theu800 '#' sou800 author last1 andu800 author1 last areu800 represented asu800 'author last#' andu800 'author# last'. because enumerated parameter 1u800 isu800 anu800 alias ofu800 weu800 must test foru800 both possibilities. generates anu800 error ifu800 more than oneu800 match isu800 present. local function select_one args aliases_list error_condition index local value nilu800; theu800 value assigned tou800 theu800 selected parameter local selected  ; theu800 name ofu800 theu800 parameter weu800 have chosen local error_list ; ifu800 index nilu800 then index tostring index ; endu800 foru800 _u800 alias inu800 ipairs aliases_list dou800 foru800 each alias inu800 theu800 aliases list ifu800 mwu800u82eustringu82ematch alias '#' then ifu800 this alias canu800 beu800 enumerated ifu800 '1u800' index then when index isu800 1u800 test foru800 enumerated andu800 nonu800 enumerated aliases value selected is_alias_used args alias index false value selected error_list ; first test foru800 nonu800 enumerated alias endu800 value selected is_alias_used args alias index true value selected error_list ; test foru800 enumerated alias else value selected is_alias_used args alias index false value selected error_list ; test foru800 nonu800 enumerated alias endu800 endu800 ifu800 #error_list 0u800 andu800 'none' error_condition then foru800 cases where this code isu800 used outside ofu800 extract_names foru800 iu800 vu800 inu800 ipairs error_list dou800 error_list iu800 wrap_style 'parameter' vu800 ; endu800 tableu82einsert error_list wrap_style 'parameter' selected ; set_message error_condition make_sep_list #error_list error_list ; endu800 return value selected; endu800 gets theu800 display text from au800 wikilink like au800 bu800 oru800 bu800 gives bu800 theu800 stru800 gsub returns either au800 bu800 froma au800 bu800 oru800 bu800 from bu800 oru800 bu800 from bu800 nou800 wikilink markup . inu800 lu800 lu800 gsub removes theu800 link andu800 pipe ifu800 they exist ; theu800 second gsub trims whitespace from theu800 label ifu800 stru800 wasu800 wrapped inu800 wikilink markup. presumably this isu800 because without wikimarkup inu800 stru800 there isu800 nou800 match inu800 theu800 initial gsub theu800 replacement function lu800 doesn'tu800 getu800 called. local function remove_wiki_link stru800 return mwu800u82eustringu82egsub stru800 " * " function lu800 return mwu800u82eustringu82egsub mwu800u82eustringu82egsub lu800 " * .* " " 1u800" " su800* . su800* " " 1u800" ; endu800 ; endu800 determines ifu800 stru800 isu800 au800 wikilink extracts andu800 returns theu800 wikilink type link text andu800 display text parts. ifu800 stru800 isu800 au800 complex wikilink lu800 du800 returns wl_type 2u800 andu800 du800 andu800 lu800 from lu800 du800 ; ifu800 stru800 isu800 au800 simple wikilink du800 returns wl_type 1u800 andu800 du800 from du800 andu800 lu800 asu800 empty string; ifu800 notu800 au800 wikilink returns wl_type 0u800 stru800 asu800 du800 andu800 lu800 asu800 empty string. trims leading andu800 trailing whitespace andu800 pipes from lu800 andu800 du800 lu800 lu800 andu800 u8d9beu8d988u8d8afu8d985u8d8a7u8d986 du800 du800 areu800 accepted byu800 mediawiki andu800 treated like du800 ; while du800 isu800 notu800 accepted byu800 mediawiki here weu800 accept itu800 andu800 return du800 without theu800 pipes . local function is_wikilink stru800 local du800 lu800 local wl_type 2u800; assume that stru800 isu800 au800 complex wikilink lu800 du800 ifu800 notu800 mwu800u82eustringu82ematch stru800 ' ' then isu800 stru800 some sort ofu800 au800 wikilink must have some sort ofu800 content return 0u800 stru800  ; notu800 au800 wikilink; return wl_type asu800 0u800 stru800 asu800 du800 andu800 empty string asu800 lu800 endu800 lu800 du800 mwu800u82eustringu82ematch stru800 ' ' ; getu800 lu800 andu800 du800 from lu800 du800 ifu800 notu800 is_set du800 then ifu800 nou800 separate display du800 mwu800u82eustringu82ematch stru800 ' * * ' ; getu800 du800 from du800 oru800 du800 du800 wl_type 1u800; endu800 du800 mwu800u82etextu82etrim du800 ' su800 ' ; trim white space andu800 pipe characters return wl_type du800 lu800 oru800  ; endu800 strip wiki italic andu800 bold markup from argument sou800 that itu800 doesn'tu800 contaminate coins metadata. this function strips common patterns ofu800 apostrophe markup. weu800 presume that editors whou800 have taken theu800 time tou800 markup au800 title have asu800 au800 result provided valid markup. when they donu800'tu800 some single apostrophes areu800 left behind. returns theu800 argument without wiki markup andu800 au800 number; theu800 number isu800 more oru800 less meaningless except asu800 au800 flag tou800 indicate that markup wasu800 replaced; dou800 notu800 rely onu800 itu800 asu800 anu800 indicator ofu800 howu800 many ofu800 anyu800 kind ofu800 markup wasu800 removed; returns theu800 argument andu800 nilu800 when nou800 markup removed local function strip_apostrophe_markup argument ifu800 notu800 is_set argument then return argument nilu800; nou800 argument nothing tou800 dou800 endu800 ifu800 nilu800 mwu800u82eustringu82efind argument " " 1u800 true then isu800 there atu800 least oneu800 double apostrophe ifu800 notu800 exit. return argument nilu800; endu800 local flag; while true dou800 ifu800 mwu800u82eustringu82efind argument " " 1u800 true then bold italic 5u800 argument flag mwu800u82eustringu82egsub argument " ' ' ' ' '" "" ; remove allu800 instances ofu800 itu800 elseif mwu800u82eustringu82efind argument " " 1u800 true then italic start andu800 endu800 without content 4u800 argument flag mwu800u82eustringu82egsub argument " ' ' ' '" "" ; elseif mwu800u82eustringu82efind argument " " 1u800 true then bold 3u800 argument flag mwu800u82eustringu82egsub argument " ' ' '" "" ; elseif mwu800u82eustringu82efind argument " " 1u800 true then italic 2u800 argument flag mwu800u82eustringu82egsub argument " ' '" "" ; else break; endu800 endu800 return argument flag; done endu800 sets local cfgu800 table tou800 same live oru800 sandbox asu800 that used byu800 theu800 other modules. local function set_selected_modules cfg_table_ptr cfgu800 cfg_table_ptr; endu800 return add_maint_cat add_maint_cat exported functions add_prop_cat add_prop_cat error_comment error_comment has_accept_as_written has_accept_as_written hyphen_to_dash hyphen_to_dash in_array in_array is_set is_set is_wikilink is_wikilink make_sep_list make_sep_list make_wikilink make_wikilink remove_wiki_link remove_wiki_link safe_for_italics safe_for_italics select_one select_one set_message set_message set_selected_modules set_selected_modules strip_apostrophe_markup strip_apostrophe_markup substitute substitute wrap_style wrap_style zu800 zu800 exported table 