Changeset 506635
- Timestamp:
- 02/17/2012 04:24:56 PM (14 years ago)
- Location:
- kcite/trunk
- Files:
-
- 4 edited
-
kcite-citeproc/citeproc.js (modified) (194 diffs)
-
kcite-citeproc/kcite.js (modified) (5 diffs)
-
kcite.php (modified) (32 diffs)
-
readme.txt (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kcite/trunk/kcite-citeproc/citeproc.js
r473946 r506635 32 32 * The Initial Developer of the Original Code is Frank G. Bennett, 33 33 * Jr. All portions of the code written by Frank G. Bennett, Jr. are 34 * Copyright (c) 2009 and 2010Frank G. Bennett, Jr. All Rights Reserved.34 * Copyright (c) 2009, 2010 and 2011 Frank G. Bennett, Jr. All Rights Reserved. 35 35 * 36 36 * Alternatively, the contents of this file may be used under the … … 58 58 } 59 59 var CSL = { 60 STATUTE_SUBDIV_GROUPED_REGEX: /((?:^| )(?:pt\.|ch\.|subch\.|sec\.|art\.|para\.))/g, 61 STATUTE_SUBDIV_PLAIN_REGEX: /(?:(?:^| )(?:pt\.|ch\.|subch\.|sec\.|art\.|para\.))/, 62 STATUTE_SUBDIV_STRINGS: { 63 "pt.": "part", 64 "ch.": "chapter", 65 "subch.": "subchapter", 66 "sec.": "section", 67 "art.": "article", 68 "para.": "paragraph" 69 }, 70 NestedBraces: [ 71 ["(", "["], 72 [")", "]"] 73 ], 74 checkNestedBraceOpen: new RegExp(".*\\("), 75 checkNestedBraceClose: new RegExp(".*\\)"), 76 LangPrefsMap: { 77 "title":"titles", 78 "title-short":"titles", 79 "container-title":"titles", 80 "collection-title":"titles", 81 "publisher":"publishers", 82 "authority":"publishers", 83 "publisher-place": "places", 84 "event-place": "places" 85 }, 86 AbbreviationSegments: function () { 87 this["container-title"] = {}; 88 this["collection-title"] = {}; 89 this["institution-entire"] = {}; 90 this["institution-part"] = {}; 91 this["nickname"] = {}; 92 this["number"] = {}; 93 this["title"] = {}; 94 this["place"] = {}; 95 this["hereinafter"] = {}; 96 this["classic"] = {}; 97 this["container-phrase"] = {}; 98 this["title-phrase"] = {}; 99 }, 60 100 GENDERS: ["masculine", "feminine"], 61 101 ERROR_NO_RENDERED_FORM: 1, … … 87 127 POSITION_TEST_VARS: ["position", "first-reference-note-number", "near-note"], 88 128 AREAS: ["citation", "citation_sort", "bibliography", "bibliography_sort"], 89 MULTI_FIELDS: [" publisher", "publisher-place", "event-place", "title","container-title", "collection-title", "institution", "authority","edition","genre","title-short"],129 MULTI_FIELDS: ["event", "publisher", "publisher-place", "event-place", "title", "container-title", "collection-title", "authority","edition","genre","title-short","subjurisdiction","medium"], 90 130 CITE_FIELDS: ["first-reference-note-number", "locator", "locator-revision"], 91 131 MINIMAL_NAME_FIELDS: ["literal", "family"], 92 132 SWAPPING_PUNCTUATION: [".", "!", "?", ":",","], 93 133 TERMINAL_PUNCTUATION: [":", ".", ";", "!", "?", " "], 94 SPLICE_PUNCTUATION: [".", "!", "?", ":", ";", ","],95 134 NONE: 0, 96 135 NUMERIC: 1, … … 133 172 PARALLEL_MATCH_VARS: ["container-title"], 134 173 PARALLEL_TYPES: ["legal_case", "legislation", "bill"], 135 PARALLEL_COLLAPSING_MID_VARSET: ["volume", " container-title", "section"],174 PARALLEL_COLLAPSING_MID_VARSET: ["volume", "issue", "container-title", "section", "collection-number"], 136 175 LOOSE: 0, 137 176 STRICT: 1, … … 395 434 "\u06E6": "\u064A" 396 435 }, 436 LOCATOR_LABELS_REGEXP: new RegExp("^((ch|col|fig|no|l|n|op|p|para|pt|sec|sv|vrs|vol)\\.)\\s+(.*)"), 437 LOCATOR_LABELS_MAP: { 438 "ch": "chapter", 439 "col": "column", 440 "fig": "figure", 441 "no": "issue", 442 "l": "line", 443 "n": "note", 444 "op": "opus", 445 "p": "page", 446 "para": "para", 447 "pt": "part", 448 "sec": "section", 449 "sv": "sub-verbo", 450 "vrs": "verse", 451 "vol": "volume" 452 }, 397 453 SUPERSCRIPTS_REGEXP: new RegExp("[\u00AA\u00B2\u00B3\u00B9\u00BA\u02B0\u02B1\u02B2\u02B3\u02B4\u02B5\u02B6\u02B7\u02B8\u02E0\u02E1\u02E2\u02E3\u02E4\u1D2C\u1D2D\u1D2E\u1D30\u1D31\u1D32\u1D33\u1D34\u1D35\u1D36\u1D37\u1D38\u1D39\u1D3A\u1D3C\u1D3D\u1D3E\u1D3F\u1D40\u1D41\u1D42\u1D43\u1D44\u1D45\u1D46\u1D47\u1D48\u1D49\u1D4A\u1D4B\u1D4C\u1D4D\u1D4F\u1D50\u1D51\u1D52\u1D53\u1D54\u1D55\u1D56\u1D57\u1D58\u1D59\u1D5A\u1D5B\u1D5C\u1D5D\u1D5E\u1D5F\u1D60\u1D61\u2070\u2071\u2074\u2075\u2076\u2077\u2078\u2079\u207A\u207B\u207C\u207D\u207E\u207F\u2120\u2122\u3192\u3193\u3194\u3195\u3196\u3197\u3198\u3199\u319A\u319B\u319C\u319D\u319E\u319F\u02C0\u02C1\u06E5\u06E6]", "g"), 398 454 locale: {}, … … 536 592 CSL.Output.Queue.prototype.startTag = function (name, token) { 537 593 var tokenstore = {}; 538 if (this.state.tmp["doing-macro-with-date"] && this.state.tmp. area.slice(-5) === "_sort") {594 if (this.state.tmp["doing-macro-with-date"] && this.state.tmp.extension) { 539 595 token = this.empty; 540 596 name = "empty"; … … 560 616 blob = new CSL.Blob(undefined, this.formats.value()[token], token); 561 617 } 618 if (this.nestedBraces) { 619 blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); 620 blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); 621 blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); 622 blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); 623 } 562 624 curr = this.current.value(); 563 625 curr.push(blob); … … 570 632 this.current.pop(); 571 633 }; 572 CSL.Output.Queue.prototype.append = function (str, tokname, notSerious ) {634 CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePredecessor, noStripPeriods) { 573 635 var token, blob, curr; 574 636 var useblob = true; … … 613 675 this.last_char_rendered = str.slice(-1); 614 676 str = str.replace(/\s+'/g, " \'").replace(/^'/g, " \'"); 615 this.state.tmp.term_predecessor = true; 677 if (!ignorePredecessor) { 678 this.state.tmp.term_predecessor = true; 679 } 616 680 } 617 681 blob = new CSL.Blob(str, token); 682 if (this.nestedBraces) { 683 blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); 684 blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); 685 blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); 686 blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); 687 } 618 688 curr = this.current.value(); 619 689 if ("undefined" === typeof curr && this.current.mystack.length === 0) { … … 622 692 } 623 693 if ("string" === typeof blob.blobs) { 624 if (this.state.tmp.strip_periods ) {694 if (this.state.tmp.strip_periods && !noStripPeriods) { 625 695 blob.blobs = blob.blobs.replace(/\./g, ""); 626 696 } 627 this.state.tmp.term_predecessor = true; 697 if (!ignorePredecessor) { 698 this.state.tmp.term_predecessor = true; 699 } 628 700 } 629 701 if (!notSerious) { … … 646 718 CSL.Output.Queue.prototype.string = function (state, myblobs, blob) { 647 719 var i, ilen, j, jlen, b; 648 var txt_esc = CSL.getSafeEscape(this.state .opt.mode, this.state.tmp.area);720 var txt_esc = CSL.getSafeEscape(this.state); 649 721 var blobs = myblobs.slice(); 650 722 var ret = []; … … 685 757 } 686 758 if (b && b.length) { 687 b = txt_esc(blobjr.strings.prefix ) + b + txt_esc(blobjr.strings.suffix);759 b = txt_esc(blobjr.strings.prefix, state.tmp.nestedBraces) + b + txt_esc(blobjr.strings.suffix, state.tmp.nestedBraces); 688 760 ret.push(b); 689 761 if (state.tmp.count_offset_characters) { … … 706 778 span_split = (parseInt(i, 10) + 1); 707 779 if (i < ret.length - 1 && "object" === typeof ret[i + 1]) { 708 if ( !ret[i + 1].UGLY_DELIMITER_SUPPRESS_HACK) {780 if (blob_delimiter && !ret[i + 1].UGLY_DELIMITER_SUPPRESS_HACK) { 709 781 ret[i] += txt_esc(blob_delimiter); 710 782 } else { … … 735 807 if (b && b.length) { 736 808 use_prefix = blob.strings.prefix; 737 b = txt_esc(use_prefix ) + b + txt_esc(use_suffix);809 b = txt_esc(use_prefix, state.tmp.nestedBraces) + b + txt_esc(use_suffix, state.tmp.nestedBraces); 738 810 if (state.tmp.count_offset_characters) { 739 811 state.tmp.offset_characters += (use_prefix.length + use_suffix.length); … … 788 860 CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, has_more) { 789 861 var state, ret, ret_last_char, use_delim, i, blob, pos, len, ppos, llen, pppos, lllen, res, str, params, txt_esc; 790 txt_esc = CSL.getSafeEscape(this.state .opt.mode, this.state.tmp.area);862 txt_esc = CSL.getSafeEscape(this.state); 791 863 if (!delim) { 792 864 delim = ""; … … 1047 1119 TERMS.indexOf(doblob.strings.suffix.slice(-1)) > -1)) { 1048 1120 blob.strings.suffix = blob.strings.suffix.slice(1); 1049 }1050 }1051 }1052 if ("string" === typeof doblob.blobs && doblob.blobs) {1053 for (var ppos = doblob.decorations.length - 1; ppos > -1; ppos += -1) {1054 var params = doblob.decorations[ppos];1055 if (params[0] === "@strip-periods" && params[1] === "true") {1056 doblob.blobs = state.fun.decorate[params[0]][params[1]](state, doblob.blobs);1057 doblob.decorations = doblob.decorations.slice(0, ppos).concat(doblob.decorations.slice(ppos + 1));1058 1121 } 1059 1122 } … … 1281 1344 if (hasDate) { 1282 1345 func = function (state, Item) { 1283 if (state.tmp. area.slice(-5) === "_sort") {1346 if (state.tmp.extension) { 1284 1347 state.tmp["doing-macro-with-date"] = true; 1285 1348 } … … 1295 1358 CSL.buildStyle.call(this, navi); 1296 1359 end_of_macro = new CSL.Token("group", CSL.END); 1360 if (macro_key_token.decorations) { 1361 end_of_macro.decorations = macro_key_token.decorations.slice(); 1362 } 1297 1363 if (hasDate) { 1298 1364 func = function (state, Item) { 1299 if (state.tmp. area.slice(-5) === "_sort") {1365 if (state.tmp.extension) { 1300 1366 state.tmp["doing-macro-with-date"] = false; 1301 1367 } … … 1718 1784 CSL.Engine = function (sys, style, lang, forceLang) { 1719 1785 var attrs, langspec, localexml, locale; 1720 this.processor_version = "1.0.2 23";1786 this.processor_version = "1.0.278"; 1721 1787 this.csl_version = "1.0"; 1722 1788 this.sys = sys; … … 1724 1790 if ("string" !== typeof style) { 1725 1791 style = ""; 1792 } 1793 if (CSL.getAbbreviation) { 1794 this.sys.getAbbreviation = CSL.getAbbreviation; 1726 1795 } 1727 1796 this.parallel = new CSL.Parallel(this); … … 2019 2088 return ret; 2020 2089 }; 2090 CSL.ITERATION = 0; 2021 2091 CSL.Engine.prototype.retrieveItem = function (id) { 2022 2092 var Item, m, pos, len, mm; 2093 CSL.ITERATION += 1; 2023 2094 if (this.registry.generate.genIDs["" + id]) { 2024 2095 Item = this.registry.generate.items["" + id]; … … 2031 2102 } 2032 2103 if (this.opt.development_extensions.field_hack && Item.note) { 2033 m = CSL.NOTE_FIELDS_REGEXP.exec(Item.note);2104 m = Item.note.match(CSL.NOTE_FIELDS_REGEXP); 2034 2105 if (m) { 2106 var names = {}; 2035 2107 for (pos = 0, len = m.length; pos < len; pos += 1) { 2036 mm = CSL.NOTE_FIELD_REGEXP.exec(m[pos]); 2037 if (!Item[mm[1]]) { 2038 if (CSL.DATE_VARIABLES.indexOf(mm[1]) > -1) { 2039 Item[mm[1]] = {raw:mm[2]}; 2040 } else { 2041 Item[mm[1]] = mm[2].replace(/^\s+/, "").replace(/\s+$/, ""); 2042 } 2043 } 2044 } 2108 mm = m[pos].match(CSL.NOTE_FIELD_REGEXP); 2109 if (!Item[mm[1]] && CSL.DATE_VARIABLES.indexOf(mm[1]) > -1) { 2110 Item[mm[1]] = {raw:mm[2]}; 2111 } else if (!Item[mm[1]] && CSL.NAME_VARIABLES.indexOf(mm[1]) > -1) { 2112 if (!Item[mm[1]]) { 2113 Item[mm[1]] = [] 2114 } 2115 var lst = mm[2].split(/\s*\|\|\s*/) 2116 if (lst.length === 1) { 2117 Item[mm[1]].push({family:lst[0],isInstitution:true}); 2118 } else if (lst.length === 2) { 2119 Item[mm[1]].push({family:lst[0],given:lst[1]}); 2120 } 2121 } else if (!Item[mm[1]] || mm[1] === "type") { 2122 Item[mm[1]] = mm[2].replace(/^\s+/, "").replace(/\s+$/, ""); 2123 } 2124 Item.note.replace(CSL.NOTE_FIELD_REGEXP, "") 2125 } 2126 } 2127 } 2128 if (this.opt.development_extensions.jurisdiction_subfield && Item.jurisdiction) { 2129 var subjurisdictions = Item.jurisdiction.split(";"); 2130 if (subjurisdictions.length > 1) { 2131 Item.subjurisdiction = subjurisdictions.slice(0,2).join(";"); 2045 2132 } 2046 2133 } … … 2068 2155 }; 2069 2156 CSL.Engine.prototype.fixOpt = function (token, name, localname) { 2070 if ( "citation" === token.name || "bibliography" === token.name) {2071 if (! this[token.name].opt[name] && "undefined" !== t his.opt[name]) {2157 if (["citation", "bibliography"].indexOf(token.name) > -1) { 2158 if (! this[token.name].opt[name] && "undefined" !== typeof this.opt[name]) { 2072 2159 this[token.name].opt[name] = this.opt[name]; 2073 2160 } 2074 2161 } 2075 2162 if ("name" === token.name || "names" === token.name) { 2076 if ("undefined" === typeof token.strings[localname] && "undefined" !== typeof this[this.build. area].opt[name]) {2077 token.strings[localname] = this[this.build. area].opt[name];2163 if ("undefined" === typeof token.strings[localname] && "undefined" !== typeof this[this.build.root].opt[name]) { 2164 token.strings[localname] = this[this.build.root].opt[name]; 2078 2165 } 2079 2166 } … … 2193 2280 CSL.Engine.prototype.setLangTagsForCslTransliteration = function (tags) { 2194 2281 var i, ilen; 2195 this.opt['locale- pri'] = [];2282 this.opt['locale-translit'] = []; 2196 2283 for (i = 0, ilen = tags.length; i < ilen; i += 1) { 2197 this.opt['locale- pri'].push(tags[i]);2284 this.opt['locale-translit'].push(tags[i]); 2198 2285 } 2199 2286 }; 2200 2287 CSL.Engine.prototype.setLangTagsForCslTranslation = function (tags) { 2201 2288 var i, ilen; 2202 this.opt['locale- sec'] = [];2289 this.opt['locale-translat'] = []; 2203 2290 for (i = 0, ilen = tags.length; i < ilen; i += 1) { 2204 this.opt['locale-sec'].push(tags[i]); 2205 } 2206 }; 2207 CSL.Engine.prototype.setOriginalCreatorNameFormsOption = function (arg) { 2208 if (arg) { 2209 this.opt["locale-show-original-names"] = true; 2210 } else { 2211 this.opt["locale-show-original-names"] = false; 2212 } 2213 }; 2214 CSL.Engine.prototype.setOriginalCreatorNameFormatOption = function (arg) { 2215 if (arg) { 2216 this.opt["locale-use-original-name-format"] = true; 2217 } else { 2218 this.opt["locale-use-original-name-format"] = false; 2219 } 2220 }; 2221 CSL.Engine.prototype.setSuppressTitleTransliterationOption = function (arg) { 2222 if (arg) { 2223 this.opt["locale-suppress-title-transliteration"] = true; 2224 } else { 2225 this.opt["locale-suppress-title-transliteration"] = false; 2226 } 2291 this.opt['locale-translat'].push(tags[i]); 2292 } 2293 }; 2294 CSL.Engine.prototype.setLangPrefsForCites = function (params) { 2295 var opt = this.opt['cite-lang-prefs']; 2296 for (var segment in params) { 2297 var supplements = []; 2298 while (params[segment].length > 1) { 2299 supplements.push(params[segment].pop()); 2300 } 2301 var sortval = {orig:1,translit:2,translat:3}; 2302 if (supplements.length === 2 && sortval[supplements[0]] < sortval[supplements[1]]) { 2303 supplements.reverse(); 2304 } 2305 while (supplements.length) { 2306 params[segment].push(supplements.pop()); 2307 } 2308 var lst = opt[segment]; 2309 while (lst.length) { 2310 lst.pop(); 2311 } 2312 for (var i = 0, ilen = params[segment].length; i < ilen; i += 1) { 2313 lst.push(params[segment][i]); 2314 } 2315 } 2227 2316 }; 2228 2317 CSL.Engine.prototype.setAutoVietnameseNamesOption = function (arg) { … … 2233 2322 } 2234 2323 }; 2324 CSL.Engine.prototype.setAbbreviations = function (arg) { 2325 if (this.sys.setAbbreviations) { 2326 this.sys.setAbbreviations(arg); 2327 } 2328 } 2235 2329 CSL.Engine.Opt = function () { 2236 2330 this.has_disambiguate = false; … … 2238 2332 this.dates = {}; 2239 2333 this["locale-sort"] = []; 2240 this["locale- pri"] = [];2241 this["locale- sec"] = [];2334 this["locale-translit"] = []; 2335 this["locale-translat"] = []; 2242 2336 this["default-locale"] = []; 2243 this["locale-use-original-name-format"] = false;2244 2337 this["noun-genders"] = {}; 2245 2338 this.update_mode = CSL.NONE; … … 2260 2353 this.development_extensions.locator_date_and_revision = true; 2261 2354 this.development_extensions.locator_parsing_for_plurals = true; 2355 this.development_extensions.locator_label_parse = true; 2262 2356 this.development_extensions.raw_date_parsing = true; 2263 2357 this.development_extensions.clean_up_csl_flaws = true; 2358 this.development_extensions.flip_parentheses_to_braces = true; 2359 this.development_extensions.parse_section_variable = true; 2360 this.development_extensions.jurisdiction_subfield = true; 2264 2361 this.gender = {}; 2362 this['cite-lang-prefs'] = { 2363 persons:['orig'], 2364 institutions:['orig'], 2365 titles:['orig','translat'], 2366 publishers:['orig'], 2367 places:['orig'] 2368 } 2265 2369 }; 2266 2370 CSL.Engine.Tmp = function () { … … 2272 2376 this.namepart_type = false; 2273 2377 this.area = "citation"; 2378 this.root = "citation"; 2379 this.extension = ""; 2274 2380 this.can_substitute = new CSL.Stack(0, CSL.LITERAL); 2275 2381 this.element_rendered_ok = false; 2276 2382 this.element_trace = new CSL.Stack("style"); 2277 2383 this.nameset_counter = 0; 2278 this. term_sibling= new CSL.Stack([false, false, false], CSL.LITERAL);2384 this.group_context = new CSL.Stack([false, false, false], CSL.LITERAL); 2279 2385 this.term_predecessor = false; 2280 2386 this.jump = new CSL.Stack(0, CSL.LITERAL); … … 2324 2430 this.lang = false; 2325 2431 this.area = "citation"; 2432 this.root = "citation"; 2433 this.extension = ""; 2326 2434 this.substitute_level = new CSL.Stack(0, CSL.LITERAL); 2435 this.names_level = 0; 2327 2436 this.render_nesting_level = 0; 2328 2437 this.render_seen = false; … … 2514 2623 break; 2515 2624 } 2516 var name = this.transform.name(this, names[j], this.opt["locale-pri"]); 2625 var res = this.nameOutput.getName(names[j], "locale-translit", true); 2626 var name = res.name; 2517 2627 if (name && name.family) { 2518 2628 myname = name.family; … … 2753 2863 this.parallel.StartCitation(sortedItems); 2754 2864 this.output.queue[0].strings.delimiter = ", "; 2865 this.tmp.term_predecessor = false; 2755 2866 entry_item_ids.push("" + CSL.getCite.call(this, item)); 2756 2867 skips[item.id] = true; … … 2765 2876 this.parallel.PruneOutputQueue(); 2766 2877 } else if (!this.registry.registry[item.id].siblings) { 2878 this.tmp.term_predecessor = false; 2767 2879 entry_item_ids.push("" + CSL.getCite.call(this, item)); 2768 2880 } … … 2879 2991 } 2880 2992 } 2993 if (this.opt.development_extensions.locator_label_parse) { 2994 if (item.locator && (!item.label || item.label === 'page')) { 2995 var m = CSL.LOCATOR_LABELS_REGEXP.exec(item.locator); 2996 if (m) { 2997 item.label = CSL.LOCATOR_LABELS_MAP[m[2]]; 2998 item.locator = m[3]; 2999 } 3000 } 3001 } 2881 3002 Item = this.retrieveItem("" + item.id); 2882 3003 var newitem = [Item, item]; … … 2961 3082 var citations; 2962 3083 if (this.opt.update_mode === CSL.POSITION) { 3084 var citationsInNote = {}; 2963 3085 for (i = 0; i < 2; i += 1) { 2964 3086 citations = [textCitations, noteCitations][i]; … … 2969 3091 if (!onecitation.properties.noteIndex) { 2970 3092 onecitation.properties.noteIndex = 0; 3093 } 3094 if (!citationsInNote[onecitation.properties.noteIndex]) { 3095 citationsInNote[onecitation.properties.noteIndex] = 1; 3096 } else { 3097 citationsInNote[onecitation.properties.noteIndex] += 1; 2971 3098 } 2972 3099 for (k = 0, klen = citations[j].sortedItems.length; k < klen; k += 1) { … … 3000 3127 var useme = false; 3001 3128 if ((citations[(j - 1)].sortedItems[0][1].id == item[1].id && citations[j - 1].properties.noteIndex >= (citations[j].properties.noteIndex - 1)) || citations[(j - 1)].sortedItems[0][1].id == this.registry.registry[item[1].id].parallel) { 3002 useme = true; 3129 if (citationsInNote[citations[j - 1].properties.noteIndex] === 1 || citations[j - 1].properties.noteIndex === 0) { 3130 useme = true; 3131 } 3003 3132 } 3004 3133 for (n = 0, nlen = items.slice(1).length; n < nlen; n += 1) { … … 3201 3330 CSL.getAmbiguousCite = function (Item, disambig) { 3202 3331 var use_parallels, ret; 3332 var oldTermSiblingLayer = this.tmp.group_context.value().slice(); 3203 3333 if (disambig) { 3204 3334 this.tmp.disambig_request = disambig; … … 3220 3350 this.tmp.suppress_decorations = false; 3221 3351 this.parallel.use_parallels = use_parallels; 3352 this.tmp.group_context.replace(oldTermSiblingLayer, "literal"); 3222 3353 return ret; 3223 3354 }; … … 3225 3356 if (last_collapsed && ! this.tmp.have_collapsed && "string" === typeof this.citation.opt["after-collapse-delimiter"]) { 3226 3357 this.tmp.splice_delimiter = this.citation.opt["after-collapse-delimiter"]; 3227 } else if (this.tmp.have_collapsed && this.opt.xclass === "in-text" ) {3358 } else if (this.tmp.have_collapsed && this.opt.xclass === "in-text" && this.opt.update_mode !== CSL.NUMERIC) { 3228 3359 this.tmp.splice_delimiter = ", "; 3229 3360 } else if (this.tmp.cite_locales[pos - 1]) { … … 3241 3372 var result, objects, myparams, len, pos, item, last_collapsed, params, empties, composite, compie, myblobs, Item, llen, ppos, obj, preceding_item, txt_esc, error_object; 3242 3373 this.tmp.last_primary_names_string = false; 3243 txt_esc = CSL.Output.Formats[this.opt.mode].text_escape; 3374 this.tmp.nestedBraces = false; 3375 txt_esc = CSL.getSafeEscape(this); 3244 3376 this.tmp.area = "citation"; 3245 3377 result = ""; … … 3253 3385 this.registry.citationreg.citationById[citationID].properties.backref_index = false; 3254 3386 this.registry.citationreg.citationById[citationID].properties.backref_citation = false; 3387 } 3388 if (this.opt.xclass === "note") { 3389 var parasets = []; 3390 var lastTitle = false; 3391 var lastPosition = false; 3392 var lastID = false; 3393 for (var i=0, ilen = inputList.length; i < ilen; i += 1) { 3394 var type = inputList[i][0].type; 3395 var title = inputList[i][0].title; 3396 var position = inputList[i][1].position; 3397 var id = inputList[i][0].id; 3398 if (title && type === "legal_case" && id !== lastID && position) { 3399 if (title !== lastTitle || parasets.length === 0) { 3400 var lst = []; 3401 parasets.push(lst); 3402 } 3403 lst.push(inputList[i][1]); 3404 } 3405 lastTitle = title; 3406 lastPosition = position; 3407 lastID = id; 3408 } 3409 for (var i=0, ilen=parasets.length; i < ilen; i += 1) { 3410 var lst = parasets[i]; 3411 if (lst.length < 2) { 3412 continue; 3413 } 3414 var locatorInLastPosition = lst.slice(-1)[0].locator; 3415 if (locatorInLastPosition) { 3416 for (var j=0, jlen=lst.length - 1; j < jlen; j += 1) { 3417 if (lst[j].locator) { 3418 locatorInLastPosition = false; 3419 } 3420 } 3421 } 3422 if (locatorInLastPosition) { 3423 lst[0].locator = locatorInLastPosition; 3424 delete lst.slice(-1)[0].locator; 3425 lst[0].label = lst.slice(-1)[0].label; 3426 if (lst.slice(-1)[0].label) { 3427 delete lst.slice(-1)[0].label; 3428 } 3429 } 3430 } 3255 3431 } 3256 3432 myparams = []; … … 3300 3476 myparams.push(params); 3301 3477 } 3478 this.tmp.has_purged_parallel = false; 3302 3479 this.parallel.PruneOutputQueue(this); 3303 3480 empties = 0; … … 3356 3533 } 3357 3534 if ("object" === typeof composite && composite.length === 0 && !item["suppress-author"]) { 3358 composite.push("[CSL STYLE ERROR: reference with no printed form.]"); 3535 if (this.tmp.has_purged_parallel) { 3536 composite.push(""); 3537 } else { 3538 composite.push("[CSL STYLE ERROR: reference with no printed form.]"); 3539 } 3359 3540 } 3360 3541 if (objects.length && "string" === typeof composite[0]) { … … 3363 3544 if (tmpstr && tmpstr.slice(0, 1) === ",") { 3364 3545 objects.push(tmpstr); 3365 } else { 3546 } else if ("string" == typeof objects.slice(-1)[0] && objects.slice(-1)[0].slice(-1) === ",") { 3547 objects.push(" " + tmpstr) 3548 } else if (tmpstr) { 3366 3549 objects.push(txt_esc(this.tmp.splice_delimiter) + tmpstr); 3367 3550 } … … 3398 3581 use_layout_suffix = use_layout_suffix.slice(1); 3399 3582 } 3583 this.output.nestedBraces = false; 3400 3584 result = txt_esc(this.citation.opt.layout_prefix) + result + txt_esc(use_layout_suffix); 3401 3585 if (!this.tmp.suppress_decorations) { … … 3473 3657 this.tmp.shadow_numbers = {}; 3474 3658 this.tmp.first_name_string = false; 3659 if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.prefix) { 3660 var openBrace = CSL.checkNestedBraceOpen.exec(item.prefix); 3661 var closeBrace = CSL.checkNestedBraceClose.exec(item.prefix); 3662 if (openBrace) { 3663 if (!closeBrace) { 3664 this.output.nestedBraces = CSL.NestedBraces; 3665 } else if (closeBrace[0].length < openBrace[0].length) { 3666 this.output.nestedBraces = CSL.NestedBraces; 3667 } else { 3668 this.output.nestedBraces = false; 3669 } 3670 } else if (closeBrace) { 3671 this.output.nestedBraces = false; 3672 } 3673 } 3475 3674 }; 3476 3675 CSL.citeEnd = function (Item, item) { … … 3486 3685 this.tmp.disambig_request = false; 3487 3686 this.tmp.cite_locales.push(this.tmp.last_cite_locale); 3687 if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.suffix) { 3688 var openBrace = CSL.checkNestedBraceOpen.exec(item.suffix); 3689 var closeBrace = CSL.checkNestedBraceClose.exec(item.suffix); 3690 if (closeBrace) { 3691 if (!openBrace) { 3692 this.output.nestedBraces = false; 3693 } else if (openBrace[0].length < closeBrace[0].length) { 3694 this.output.nestedBraces = false; 3695 } else { 3696 this.output.nestedBraces = CSL.NestedBraces; 3697 } 3698 } else if (openBrace) { 3699 this.output.nestedBraces = CSL.NestedBraces; 3700 } 3701 } 3488 3702 }; 3489 3703 CSL.Node = {}; … … 3491 3705 build: function (state, target) { 3492 3706 if (this.tokentype === CSL.START) { 3707 state.build.area = "bibliography"; 3708 state.build.root = "bibliography"; 3493 3709 state.fixOpt(this, "names-delimiter", "delimiter"); 3494 3710 state.fixOpt(this, "name-delimiter", "delimiter"); … … 3507 3723 state.fixOpt(this, "et-al-subsequent-min", "et-al-subsequent-min"); 3508 3724 state.fixOpt(this, "et-al-subsequent-use-first", "et-al-subsequent-use-first"); 3509 state.build.area_return = state.build.area;3510 state.build.area = "bibliography";3511 }3512 if (this.tokentype === CSL.END) {3513 state.build.area = state.build.area_return;3514 3725 } 3515 3726 target.push(this); … … 3548 3759 ret.base = CSL.LANG_BASES[langlst[0]]; 3549 3760 if ("undefined" === typeof ret.base) { 3550 CSL.debug("Warning: unknown locale "+langstr+", setting to en-US");3551 return {base:"en-US", best: "en-US", bare:"en"};3761 CSL.debug("Warning: unknown locale "+langstr+", setting fallback to en-US"); 3762 return {base:"en-US", best:langstr, bare:"en"}; 3552 3763 } 3553 3764 if (langlst.length === 1 || langlst[1] === "x") { … … 3590 3801 this.locale[lang_out].terms = {}; 3591 3802 this.locale[lang_out].opts = {}; 3803 this.locale[lang_out].opts["skip-words"] = CSL.SKIP_WORDS; 3592 3804 this.locale[lang_out].dates = {}; 3593 3805 } … … 3669 3881 for (attrname in attributes) { 3670 3882 if (attributes.hasOwnProperty(attrname)) { 3671 if (attributes[attrname] === "true") { 3672 this.locale[lang_out].opts[attrname.slice(1)] = true; 3673 } else { 3674 this.locale[lang_out].opts[attrname.slice(1)] = false; 3883 if (attrname === "@punctuation-in-quote") { 3884 if (attributes[attrname] === "true") { 3885 this.locale[lang_out].opts[attrname.slice(1)] = true; 3886 } else { 3887 this.locale[lang_out].opts[attrname.slice(1)] = false; 3888 } 3889 } else if (attrname === "@skip-words") { 3890 var skip_words = attributes[attrname].split(/\s+/); 3891 this.locale[lang_out].opts[attrname.slice(1)] = skip_words; 3675 3892 } 3676 3893 } … … 3705 3922 state.fixOpt(this, "et-al-subsequent-min", "et-al-subsequent-min"); 3706 3923 state.fixOpt(this, "et-al-subsequent-use-first", "et-al-subsequent-use-first"); 3707 state.build.area_return = state.build.area;3708 3924 state.build.area = "citation"; 3709 3925 } … … 3720 3936 } 3721 3937 state.citation.srt = new CSL.Registry.Comparifier(state, "citation_sort"); 3722 state.build.area = state.build.area_return;3723 3938 } 3724 3939 } … … 3730 3945 state.build.date_parts = []; 3731 3946 state.build.date_variables = this.variables; 3732 if (!state.build. sort_flag) {3947 if (!state.build.extension) { 3733 3948 CSL.Util.substituteStart.call(this, state, target); 3734 3949 } 3735 if (state.build. area.slice(-5) === "_sort") {3950 if (state.build.extension) { 3736 3951 func = CSL.dateMacroAsSortKey; 3737 3952 } else { … … 3774 3989 } 3775 3990 dp = dpx.slice(); 3776 if ( state.tmp.area.slice(-5) !== "_sort"&& ("" + Item.volume) === "" + state.tmp.date_object.year && this.dateparts.length === 1 && this.dateparts[0] === "year") {3991 if (!state.tmp.extension && ("" + Item.volume) === "" + state.tmp.date_object.year && this.dateparts.length === 1 && this.dateparts[0] === "year") { 3777 3992 for (key in state.tmp.date_object) { 3778 3993 if (state.tmp.date_object.hasOwnProperty(key)) { … … 3806 4021 this.execs.push(func); 3807 4022 } 3808 if (!state.build. sort_flag&& (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON)) {4023 if (!state.build.extension && (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON)) { 3809 4024 func = function (state, Item) { 3810 4025 state.output.endTag(); … … 3815 4030 target.push(this); 3816 4031 if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) { 3817 if (!state.build. sort_flag) {4032 if (!state.build.extension) { 3818 4033 CSL.Util.substituteEnd.call(this, state, target); 3819 4034 } … … 3993 4208 value = "" + state.tmp.date_object.season; 3994 4209 if (value && value.match(/^[1-4]$/)) { 3995 state.tmp. term_sibling.replace([false, false, true]);4210 state.tmp.group_context.replace([false, false, true]); 3996 4211 state.output.append(state.getTerm(("season-0" + value)), this); 3997 4212 } else if (value) { … … 4005 4220 state.tmp.has_done_year_suffix = true; 4006 4221 num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10); 4007 number = new CSL.NumericBlob(num, this );4222 number = new CSL.NumericBlob(num, this, Item.id); 4008 4223 this.successor_prefix = state[state.build.area].opt.layout_delimiter; 4009 4224 this.splice_prefix = state[state.build.area].opt.layout_delimiter; … … 4099 4314 CSL.Node.group = { 4100 4315 build: function (state, target) { 4101 var func, execs , outer_area;4316 var func, execs; 4102 4317 if (this.tokentype === CSL.START) { 4103 4318 CSL.Util.substituteStart.call(this, state, target); … … 4106 4321 } 4107 4322 func = function (state, Item) { 4108 state.tmp.term_sibling.push([false, false, false], CSL.LITERAL);4109 };4110 this.execs.push(func);4111 func = function (state, Item) {4112 4323 state.output.startTag("group", this); 4324 if (state.tmp.group_context.mystack.length) { 4325 state.output.current.value().parent = state.tmp.group_context.value()[4]; 4326 } 4327 state.tmp.group_context.push([false, false, false, false, state.output.current.value()], CSL.LITERAL); 4328 if (this.strings.oops) { 4329 state.tmp.group_context.value()[3] = this.strings.oops; 4330 } 4113 4331 }; 4114 4332 execs = []; … … 4117 4335 if (this.strings["has-publisher-and-publisher-place"]) { 4118 4336 state.build["publisher-special"] = true; 4119 outer_area = state.build.area.replace(/_sort$/, ""); 4120 if ("string" === typeof state[outer_area].opt["name-delimiter"]) { 4121 func = function (state, Item) { 4122 if (Item.publisher && Item["publisher-place"]) { 4123 var publisher_lst = Item.publisher.split(/;\s*/); 4124 var publisher_place_lst = Item["publisher-place"].split(/;\s*/); 4125 if (publisher_lst.length > 1 4126 && publisher_lst.length === publisher_place_lst.length) { 4127 state.publisherOutput = new CSL.PublisherOutput(state); 4128 state.publisherOutput["publisher-list"] = publisher_lst; 4129 state.publisherOutput["publisher-place-list"] = publisher_place_lst; 4130 state.publisherOutput.group_tok = this; 4131 } 4337 func = function (state, Item) { 4338 if (this.strings["subgroup-delimiter"] 4339 && Item.publisher && Item["publisher-place"]) { 4340 var publisher_lst = Item.publisher.split(/;\s*/); 4341 var publisher_place_lst = Item["publisher-place"].split(/;\s*/); 4342 if (publisher_lst.length > 1 4343 && publisher_lst.length === publisher_place_lst.length) { 4344 state.publisherOutput = new CSL.PublisherOutput(state, this); 4345 state.publisherOutput["publisher-list"] = publisher_lst; 4346 state.publisherOutput["publisher-place-list"] = publisher_place_lst; 4132 4347 } 4133 } ;4134 this.execs.push(func);4135 }4348 } 4349 }; 4350 this.execs.push(func); 4136 4351 } 4137 4352 } else { 4138 4353 if (state.build["publisher-special"]) { 4139 4354 state.build["publisher-special"] = false; 4140 outer_area = state.build.area.replace(/_sort$/, ""); 4141 if ("string" === typeof state[outer_area].opt["name-delimiter"]) { 4355 if ("string" === typeof state[state.build.root].opt["name-delimiter"]) { 4142 4356 func = function (state, Item) { 4143 4357 if (state.publisherOutput) { 4144 state.publisherOutput.name_delimiter = state[outer_area].opt["name-delimiter"];4145 state.publisherOutput.delimiter_precedes_last = state[outer_area].opt["delimiter-precedes-last"];4146 state.publisherOutput.and = state[outer_area].opt.and;4147 4358 state.publisherOutput.render(); 4148 4359 state.publisherOutput = false; … … 4153 4364 } 4154 4365 func = function (state, Item) { 4155 var flag = state.tmp. term_sibling.value();4366 var flag = state.tmp.group_context.pop(); 4156 4367 state.output.endTag(); 4157 if (!flag[2] && (flag[1] || (!flag[1] && !flag[0]))) { 4368 var upperflag = state.tmp.group_context.value(); 4369 if (flag[1]) { 4370 state.tmp.group_context.value()[1] = true; 4371 } 4372 if (flag[2] || (flag[0] && !flag[1])) { 4373 state.tmp.group_context.value()[2] = true; 4374 } else { 4158 4375 if (state.output.current.value().blobs) { 4159 4376 state.output.current.value().blobs.pop(); 4160 4377 } 4161 } 4162 state.tmp.term_sibling.pop(); 4163 if ((flag[2] || (!flag[1] && flag[0])) && state.tmp.term_sibling.mystack.length > 1) { 4164 state.tmp.term_sibling.replace([false, false, true]); 4378 if (state.tmp.group_context.value()[3]) { 4379 state.output.current.mystack[state.output.current.mystack.length - 2].strings.delimiter = state.tmp.group_context.value()[3]; 4380 } 4165 4381 } 4166 4382 }; … … 4229 4445 build: function (state, target) { 4230 4446 if ([CSL.SINGLETON, CSL.START].indexOf(this.tokentype) > -1) { 4231 if ("string" === typeof state.build.name_delimiter ) {4447 if ("string" === typeof state.build.name_delimiter && !this.strings.delimiter) { 4232 4448 this.strings.delimiter = state.build.name_delimiter; 4233 4449 } 4234 var func = function (state, Item) { 4235 var myand, and_default_prefix, and_suffix; 4236 if ("text" === this.strings.and) { 4237 myand = state.getTerm("and", "long", 0); 4238 } else if ("symbol" === this.strings.and) { 4239 myand = "&"; 4240 } 4241 if (state.nameOutput.name.and_term) { 4242 myand = state.getTerm("and", "long", 0); 4243 } 4244 if (CSL.STARTSWITH_ROMANESQUE_REGEXP.test(myand)) { 4245 and_default_prefix = " "; 4246 and_suffix = " "; 4247 } else { 4248 and_default_prefix = ""; 4249 and_suffix = ""; 4250 } 4450 var myand, and_default_prefix, and_suffix; 4451 if ("text" === this.strings.and) { 4452 this.and_term = state.getTerm("and", "long", 0); 4453 } else if ("symbol" === this.strings.and) { 4454 this.and_term = "&"; 4455 } 4456 if ("undefined" === typeof this.and_term && state.build.and_term) { 4457 this.and_term = state.getTerm("and", "long", 0); 4458 } 4459 if (CSL.STARTSWITH_ROMANESQUE_REGEXP.test(this.and_term)) { 4460 this.and_prefix_single = " "; 4461 this.and_prefix_multiple = ", "; 4462 if ("string" === typeof this.strings.delimiter) { 4463 this.and_prefix_multiple = this.strings.delimiter; 4464 } 4465 this.and_suffix = " "; 4466 } else { 4467 this.and_prefix_single = ""; 4468 this.and_prefix_multiple = ""; 4469 this.and_suffix = ""; 4470 } 4471 if (this.strings["delimiter-precedes-last"] === "always") { 4472 this.and_prefix_single = this.strings.delimiter; 4473 } else if (this.strings["delimiter-precedes-last"] === "never") { 4474 if (this.and_prefix_multiple) { 4475 this.and_prefix_multiple = " "; 4476 } 4477 } 4478 func = function (state, Item) { 4251 4479 this.and = {}; 4252 this.and.single = new CSL.Blob(myand); 4253 this.and.single.strings.suffix = and_suffix; 4254 this.and.multiple = new CSL.Blob(myand); 4255 this.and.multiple.strings.suffix = and_suffix; 4256 if (this.strings["delimiter-precedes-last"] === "always") { 4257 this.and.single.strings.prefix = this.strings.delimiter; 4258 this.and.multiple.strings.prefix = this.strings.delimiter; 4259 } else if (this.strings["delimiter-precedes-last"] === "contextual") { 4260 this.and.single.strings.prefix = and_default_prefix; 4261 this.and.multiple.strings.prefix = this.strings.delimiter; 4262 } else { 4263 this.and.single.strings.prefix = and_default_prefix; 4264 this.and.multiple.strings.prefix = and_default_prefix; 4480 if ("undefined" !== typeof this.and_term) { 4481 state.output.append(this.and_term, "empty", true); 4482 this.and.single = state.output.pop(); 4483 this.and.single.strings.prefix = this.and_prefix_single; 4484 this.and.single.strings.suffix = this.and_suffix; 4485 state.output.append(this.and_term, "empty", true); 4486 this.and.multiple = state.output.pop(); 4487 this.and.multiple.strings.prefix = this.and_prefix_multiple; 4488 this.and.multiple.strings.suffix = this.and_suffix; 4489 } else if ("undefined" !== this.strings.delimiter) { 4490 this.and.single = new CSL.Blob(this.strings.delimiter); 4491 this.and.single.strings.prefix = ""; 4492 this.and.single.strings.suffix = ""; 4493 this.and.multiple = new CSL.Blob(this.strings.delimiter); 4494 this.and.multiple.strings.prefix = ""; 4495 this.and.multiple.strings.suffix = ""; 4265 4496 } 4266 4497 state.nameOutput.institution = this; … … 4394 4625 } else if ("title" === variable) { 4395 4626 state.transform.init("empty", "title"); 4396 state.transform.setTransformLocale("locale-sort");4397 4627 state.transform.setTransformFallback(true); 4398 4628 func = state.transform.getOutputFunction(this.variables); … … 4491 4721 if (item && item.prefix) { 4492 4722 sp = ""; 4493 if (item.prefix.match(CSL.ENDSWITH_ROMANESQUE_REGEXP)) { 4723 var prefix = item.prefix.replace(/<[^>]+>/g, "").replace(/\s+$/, "").replace(/^\s+/, ""); 4724 if (prefix.match(CSL.ENDSWITH_ROMANESQUE_REGEXP)) { 4494 4725 sp = " "; 4495 4726 } 4496 state.output.append((item.prefix + sp), this); 4727 var ignorePredecessor = false; 4728 if (CSL.TERMINAL_PUNCTUATION.slice(0,-1).indexOf(prefix.slice(-1)) > -1 4729 && prefix[0] != prefix[0].toLowerCase()) { 4730 state.tmp.term_predecessor = false; 4731 ignorePredecessor = true; 4732 } 4733 prefix = (item.prefix + sp).replace(/\s+/g, " ") 4734 state.output.append(prefix, this, false, ignorePredecessor); 4497 4735 } 4498 4736 }; … … 4617 4855 this.names = names; 4618 4856 this.variables = names.variables; 4619 if (this.nameset_base === 0 && !this._first_creator_variable) {4620 this._first_creator_variable = this.variables[0];4621 }4622 4857 this.state.tmp.value = []; 4623 4858 for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) { … … 4630 4865 this.name = undefined; 4631 4866 this.institutionpart = {}; 4867 this.state.tmp.group_context.value()[1] = true; 4868 if (!this.state.tmp.value.length) { 4869 return; 4870 } 4871 this.state.tmp.group_context.value()[2] = false; 4632 4872 }; 4633 4873 CSL.NameOutput.prototype.reinit = function (names) { 4634 if ( !this._hasValues()) {4874 if (this.state.tmp.can_substitute.value()) { 4635 4875 this.nameset_offset = 0; 4636 4876 this.variables = names.variables; 4637 } 4638 }; 4639 CSL.NameOutput.prototype._hasValues = function () { 4640 for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) { 4641 var v = this.variables[i]; 4642 if (this.Item[v]) { 4643 return true; 4644 } 4645 } 4646 return false; 4877 var oldval = this.state.tmp.value.slice(); 4878 this.state.tmp.value = []; 4879 for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) { 4880 if (this.Item[this.variables[i]] && this.Item[this.variables[i]].length) { 4881 this.state.tmp.value = this.state.tmp.value.concat(this.Item[this.variables[i]]); 4882 } 4883 } 4884 if (this.state.tmp.value.length) { 4885 this.state.tmp.can_substitute.replace(false, CSL.LITERAL); 4886 } 4887 this.state.tmp.value = oldval; 4888 } 4647 4889 }; 4648 4890 CSL.NameOutput.prototype.outputNames = function () { 4649 4891 var i, ilen; 4650 4892 var variables = this.variables; 4893 if (this.institution.and) { 4894 if (!this.institution.and.single.blobs && !this.institution.and.single.blobs.length) { 4895 this.institution.and.single.blobs = this.name.and.single.blobs; 4896 } 4897 if (!this.institution.and.single.blobs && !this.institution.and.multiple.blobs.length) { 4898 this.institution.and.multiple.blobs = this.name.and.multiple.blobs; 4899 } 4900 } 4651 4901 this.variable_offset = {}; 4652 4902 if (this.family) { … … 4675 4925 this.constrainNames(); 4676 4926 if (this.name.strings.form === "count") { 4677 if (this.state.tmp. area.slice(-5) === "_sort"|| this.names_count != 0) {4927 if (this.state.tmp.extension || this.names_count != 0) { 4678 4928 this.state.output.append(this.names_count, "empty"); 4679 } else { 4680 this.state.tmp.term_sibling.value()[1] = true; 4681 this.state.tmp.term_sibling.value()[2] = false; 4929 this.state.tmp.group_context.value()[2] = true; 4682 4930 } 4683 4931 return; … … 4722 4970 this.state.output.append(blob, this.names); 4723 4971 this.state.tmp.name_node.top = this.state.output.current.value(); 4724 this.state.tmp.name_node.string = this.state.output.string(this.state, this.state.tmp.name_node.top.blobs, false); 4972 var oldSuppressDecorations = this.state.tmp.suppress_decorations; 4973 this.state.tmp.suppress_decorations = true; 4974 var lastBlob = this.state.tmp.name_node.top.blobs.pop(); 4975 var name_node_string = this.state.output.string(this.state, lastBlob.blobs, false); 4976 this.state.tmp.name_node.top.blobs.push(lastBlob); 4977 if (name_node_string) { 4978 this.state.tmp.name_node.string = name_node_string; 4979 } 4980 this.state.tmp.suppress_decorations = oldSuppressDecorations; 4725 4981 if (this.state.tmp.name_node.string && !this.state.tmp.first_name_string) { 4726 4982 this.state.tmp.first_name_string = this.state.tmp.name_node.string; 4727 4983 } 4728 if (" undefined" === typeofthis.Item.type) {4984 if ("classic" === this.Item.type) { 4729 4985 var author_title = []; 4730 if (this.state.tmp. name_node.string) {4731 author_title.push(this.state.tmp. name_node.string);4986 if (this.state.tmp.first_name_string) { 4987 author_title.push(this.state.tmp.first_name_string); 4732 4988 } 4733 4989 if (this.Item.title) { … … 4735 4991 } 4736 4992 author_title = author_title.join(", "); 4737 if (author_title ) {4738 this.state.transform.loadAbbreviation(" classic", author_title);4739 if (this.state.transform.abbrevs .classic[author_title]) {4993 if (author_title && this.state.sys.getAbbreviation) { 4994 this.state.transform.loadAbbreviation("default", "classic", author_title); 4995 if (this.state.transform.abbrevs["default"].classic[author_title]) { 4740 4996 this.state.tmp.done_vars.push("title"); 4741 this.state.output.append(this.state.transform.abbrevs .classic[author_title], "empty", true);4997 this.state.output.append(this.state.transform.abbrevs["default"].classic[author_title], "empty", true); 4742 4998 blob = this.state.output.pop(); 4743 this.state.tmp.name_node.top.blobs = [blob]; 4744 } 4745 } 4746 } 4747 if (this.Item.type === "personal_communication") { 4999 this.state.tmp.name_node.top.blobs.pop(); 5000 this.state.tmp.name_node.top.blobs.push(blob); 5001 } 5002 } 5003 } 5004 if (this.Item.type === "personal_communication" || this.Item.type === "interview") { 4748 5005 var author = ""; 4749 if (this.state.tmp.name_node.string) { 4750 author = this.state.tmp.name_node.string; 4751 } 4752 if (author) { 4753 this.state.transform.loadAbbreviation("nickname", author); 4754 } 4755 if (this.state.transform.abbrevs.nickname[author]) { 4756 this.state.output.append(this.state.transform.abbrevs.nickname[author], "empty", true) 4757 blob = this.state.output.pop(); 4758 this.state.tmp.name_node.top.blobs = [blob]; 5006 author = this.state.tmp.name_node.string; 5007 if (author && this.state.sys.getAbbreviation && !(this.item && this.item["suppress-author"])) { 5008 this.state.transform.loadAbbreviation("default", "nickname", author); 5009 var myLocalName = this.state.transform.abbrevs["default"].nickname[author]; 5010 if (myLocalName) { 5011 if (myLocalName === "{suppress}") { 5012 this.state.tmp.name_node.top.blobs.pop(); 5013 this.state.tmp.group_context.value()[2] = false; 5014 } else { 5015 this.state.output.append(myLocalName, "empty", true) 5016 blob = this.state.output.pop(); 5017 this.state.tmp.name_node.top.blobs = [blob]; 5018 } 5019 } 4759 5020 } 4760 5021 } … … 4816 5077 CSL.NameOutput.prototype._collapseAuthor = function () { 4817 5078 var myqueue, mystr, oldchars; 5079 if (this.nameset_base === 0 && this.Item[this.variables[0]] && !this._first_creator_variable) { 5080 this._first_creator_variable = this.variables[0]; 5081 } 4818 5082 if ((this.item && this.item["suppress-author"] && this._first_creator_variable == this.variables[0]) 4819 5083 || (this.state[this.state.tmp.area].opt.collapse … … 4885 5149 } 4886 5150 if (this.etal_min === 1 && this.etal_use_first === 1 4887 && !(this.state.tmp.area === "bibliography_sort" 4888 || this.state.tmp.area === "citation_sort" 5151 && !(this.state.tmp.extension 4889 5152 || this.state.tmp.just_looking)) { 4890 5153 chopvar = v; … … 4940 5203 } 4941 5204 } 4942 for (v in this.freeters) {4943 this._transformNameset(this.freeters[v]);4944 }4945 for (v in this.persons) {4946 for (i = 0, ilen = this.persons[v].length; i < ilen; i += 1) {4947 this._transformNameset(this.persons[v][i]);4948 }4949 this._transformNameset(this.institutions[v]);4950 for (i = 0, ilen = this.institutions[v].length; i < ilen; i += 1) {4951 this.state.transform.loadAbbreviation("institution", this.institutions[v][i].literal);4952 }4953 }4954 5205 for (i = 0, ilen = this.variables.length; i < ilen; i += 1) { 4955 5206 if (this.institutions[v].length) { … … 4959 5210 if (this.persons[v][i].length) { 4960 5211 this.nameset_offset += 1; 4961 }4962 this.institutions[v][i] = this._splitInstitution(this.institutions[v][i], v, i);4963 }4964 }4965 for (v in this.institutions) {4966 for (i = 0, ilen = this.institutions[v].length; i < ilen; i += 1) {4967 var long_form = this.institutions[v][i]["long"];4968 if (this.state.transform.abbrevs.institution[long_form.join(", ")]) {4969 var short_form = this.state.transform.abbrevs.institution[long_form.join(", ")].split(", ");4970 if (short_form.length === long_form.length) {4971 this.institutions[v][i]["short"] = short_form;4972 }4973 5212 } 4974 5213 } … … 5083 5322 } 5084 5323 }; 5085 CSL.NameOutput.prototype._splitInstitution = function (value, v, i) {5086 var ret = {};5087 ret["long"] = this._trimInstitution(value.literal.split(/\s*\|\s*/), v, i);5088 var str = value.literal;5089 if (str) {5090 if (str.slice(0,1) === '"' && str.slice(-1) === '"') {5091 ret["short"] = [str.slice(1,-1)];5092 } else {5093 ret["short"] = this._trimInstitution(str.split(/\s*\|\s*/), v, i);5094 }5095 } else {5096 ret["short"] = false;5097 }5098 return ret;5099 };5100 CSL.NameOutput.prototype._trimInstitution = function (subunits, v, i) {5101 var s;5102 var use_first = this.institution.strings["use-first"];5103 if (!use_first) {5104 if (this.persons[v][i].length === 0) {5105 use_first = this.institution.strings["substitute-use-first"];5106 }5107 }5108 if (!use_first) {5109 use_first = 0;5110 }5111 var append_last = this.institution.strings["use-last"];5112 if (!append_last) {5113 append_last = 0;5114 }5115 if (use_first || append_last) {5116 s = subunits.slice();5117 subunits = subunits.slice(0, use_first);5118 s = s.slice(use_first);5119 if (append_last) {5120 if (append_last > s.length) {5121 append_last = s.length;5122 }5123 if (append_last) {5124 subunits = subunits.concat(s.slice((s.length - append_last)));5125 }5126 }5127 }5128 return subunits;5129 };5130 5324 CSL.NameOutput.prototype.joinPersons = function (blobs, pos) { 5131 5325 var ret; … … 5134 5328 } else if (this.etal_spec[pos] === 2) { 5135 5329 ret = this._joinEllipsis(blobs, "name"); 5330 } else if (!this.state.tmp.sort_key_flag) { 5331 ret = this._joinAnd(blobs, "name"); 5136 5332 } else { 5137 ret = this._join And(blobs, "name");5333 ret = this._join(blobs, " "); 5138 5334 } 5139 5335 return ret; … … 5486 5682 for (var j = 0, jlen = this.institutions[v].length; j < jlen; j += 1) { 5487 5683 var institution, institution_short, institution_long, short_style, long_style; 5684 var name = this.institutions[v][j]; 5685 var j, ret, optLangTag, jlen, key, localesets; 5686 if (this.state.tmp.extension) { 5687 localesets = ["sort"]; 5688 } else if (name.isInstitution) { 5689 localesets = this.state.opt['cite-lang-prefs'].institutions; 5690 } else { 5691 localesets = this.state.opt['cite-lang-prefs'].persons; 5692 } 5693 slot = {primary:false,secondary:false,tertiary:false}; 5694 if (localesets) { 5695 var slotnames = ["primary", "secondary", "tertiary"]; 5696 for (var k = 0, klen = slotnames.length; k < klen; k += 1) { 5697 if (localesets.length - 1 < j) { 5698 break; 5699 } 5700 if (localesets[k]) { 5701 slot[slotnames[k]] = 'locale-' + localesets[k]; 5702 } 5703 } 5704 } else { 5705 slot.primary = 'locale-translat'; 5706 } 5707 if (this.state.tmp.area !== "bibliography" 5708 && !(this.state.tmp.area === "citation" 5709 && this.state.opt.xclass === "note" 5710 && this.item && !this.item.position)) { 5711 slot.secondary = false; 5712 slot.tertiary = false; 5713 } 5714 var res; 5715 res = this.getName(name, slot.primary, true); 5716 var primary = res.name; 5717 var usedOrig = res.usedOrig; 5718 if (primary) { 5719 primary = this.fixupInstitution(primary, v, j); 5720 } 5721 secondary = false; 5722 if (slot.secondary) { 5723 res = this.getName(name, slot.secondary, false, usedOrig); 5724 secondary = res.name; 5725 usedOrig = res.usedOrig; 5726 if (secondary) { 5727 secondary = this.fixupInstitution(secondary, v, j); 5728 } 5729 } 5730 tertiary = false; 5731 if (slot.tertiary) { 5732 res = this.getName(name, slot.tertiary, false, usedOrig); 5733 tertiary = res.name; 5734 if (tertiary) { 5735 tertiary = this.fixupInstitution(tertiary, v, j); 5736 } 5737 } 5488 5738 switch (this.institution.strings["institution-parts"]) { 5489 5739 case "short": 5490 if ( this.institutions[v][j]["short"].length) {5740 if (primary["short"].length) { 5491 5741 short_style = this._getShortStyle(); 5492 institution = [this._renderOneInstitutionPart( this.institutions[v][j]["short"], short_style)];5742 institution = [this._renderOneInstitutionPart(primary["short"], short_style)]; 5493 5743 } else { 5494 long_style = this._getLongStyle( v, j);5495 institution = [this._renderOneInstitutionPart( this.institutions[v][j]["long"], long_style)];5744 long_style = this._getLongStyle(primary, v, j); 5745 institution = [this._renderOneInstitutionPart(primary["long"], long_style)]; 5496 5746 } 5497 5747 break; 5498 5748 case "short-long": 5499 long_style = this._getLongStyle( v, j);5749 long_style = this._getLongStyle(primary, v, j); 5500 5750 short_style = this._getShortStyle(); 5501 institution_short = this._renderOneInstitutionPart( this.institutions[v][j]["short"], short_style);5502 institution_long = this._ renderOneInstitutionPart(this.institutions[v][j]["long"], long_style);5751 institution_short = this._renderOneInstitutionPart(primary["short"], short_style); 5752 institution_long = this._composeOneInstitutionPart([primary, secondary, tertiary], long_style); 5503 5753 institution = [institution_short, institution_long]; 5504 5754 break; 5505 5755 case "long-short": 5506 long_style = this._getLongStyle( v, j);5756 long_style = this._getLongStyle(primary, v, j); 5507 5757 short_style = this._getShortStyle(); 5508 institution_short = this._renderOneInstitutionPart( this.institutions[v][j]["short"], short_style);5509 institution_long = this._ renderOneInstitutionPart(this.institutions[v][j]["long"], long_style);5758 institution_short = this._renderOneInstitutionPart(primary["short"], short_style); 5759 institution_long = this._composeOneInstitutionPart([primary, secondary, tertiary], long_style, true); 5510 5760 institution = [institution_long, institution_short]; 5511 5761 break; 5512 5762 default: 5513 long_style = this._getLongStyle( v, j);5514 institution = [this._ renderOneInstitutionPart(this.institutions[v][j]["long"], long_style)];5763 long_style = this._getLongStyle(primary, v, j); 5764 institution = [this._composeOneInstitutionPart([primary, secondary, tertiary], long_style)]; 5515 5765 break; 5516 5766 } … … 5519 5769 } 5520 5770 }; 5771 CSL.NameOutput.prototype._composeOneInstitutionPart = function (names, style) { 5772 var primary = false, secondary = false, tertiary = false; 5773 if (names[0]) { 5774 primary = this._renderOneInstitutionPart(names[0]["long"], style); 5775 } 5776 if (names[1]) { 5777 secondary = this._renderOneInstitutionPart(names[1]["long"], style); 5778 } 5779 if (names[2]) { 5780 tertiary = this._renderOneInstitutionPart(names[2]["long"], style); 5781 } 5782 var institutionblob; 5783 if (secondary || tertiary) { 5784 var multiblob = this._join([secondary, tertiary], ", "); 5785 var group_tok = new CSL.Token(); 5786 group_tok.strings.prefix = " ["; 5787 group_tok.strings.suffix = "]"; 5788 this.state.output.openLevel(group_tok); 5789 this.state.output.append(multiblob); 5790 this.state.output.closeLevel(); 5791 multiblob = this.state.output.pop(); 5792 institutionblob = this._join([primary, multiblob], ""); 5793 } else { 5794 institutionblob = primary; 5795 } 5796 return institutionblob; 5797 } 5521 5798 CSL.NameOutput.prototype._renderOneInstitutionPart = function (blobs, style) { 5522 5799 for (var i = 0, ilen = blobs.length; i < ilen; i += 1) { 5523 5800 if (blobs[i]) { 5524 this.state.output.append(blobs[i], style, true); 5801 var str = blobs[i]; 5802 if (this.state.tmp.strip_periods) { 5803 str = str.replace(/\./g, ""); 5804 } else { 5805 for (var j = 0, jlen = style.decorations.length; j < jlen; j += 1) { 5806 if ("@strip-periods" === style.decorations[j][0] && "true" === style.decorations[j][1]) { 5807 str = str.replace(/\./g, ""); 5808 break; 5809 } 5810 } 5811 } 5812 this.state.tmp.group_context.value()[2] = true; 5813 this.state.tmp.can_substitute.replace(false, CSL.LITERAL); 5814 this.state.output.append(str, style, true); 5525 5815 blobs[i] = this.state.output.pop(); 5526 5816 } 5527 5817 } 5528 return this._join(blobs, this.name.strings.delimiter); 5818 if ("undefined" === typeof this.institution.strings["part-separator"]) { 5819 this.institution.strings["part-separator"] = this.name.strings.delimiter; 5820 } 5821 return this._join(blobs, this.institution.strings["part-separator"]); 5529 5822 }; 5530 5823 CSL.NameOutput.prototype._renderPersonalNames = function (values, pos) { … … 5533 5826 var names = []; 5534 5827 for (var i = 0, ilen = values.length; i < ilen; i += 1) { 5535 var val = values[i]; 5536 names.push(this._renderOnePersonalName(val, pos, i)); 5828 var name = values[i]; 5829 var j, ret, optLangTag, jlen, key, localesets; 5830 if (this.state.tmp.extension) { 5831 localesets = ["sort"]; 5832 } else if (name.isInstitution) { 5833 localesets = this.state.opt['cite-lang-prefs'].institutions; 5834 } else { 5835 localesets = this.state.opt['cite-lang-prefs'].persons; 5836 } 5837 slot = {primary:false,secondary:false,tertiary:false}; 5838 if (localesets) { 5839 var slotnames = ["primary", "secondary", "tertiary"]; 5840 for (var j = 0, jlen = slotnames.length; j < jlen; j += 1) { 5841 if (localesets.length - 1 < j) { 5842 break; 5843 } 5844 slot[slotnames[j]] = 'locale-' + localesets[j]; 5845 } 5846 } else { 5847 slot.primary = 'locale-translat'; 5848 } 5849 if (this.state.tmp.sort_key_flag || (this.state.tmp.area !== "bibliography" 5850 && !(this.state.tmp.area === "citation" 5851 && this.state.opt.xclass === "note" 5852 && this.item && !this.item.position))) { 5853 slot.secondary = false; 5854 slot.tertiary = false; 5855 } 5856 var res = this.getName(name, slot.primary, true); 5857 var primary = this._renderOnePersonalName(res.name, pos, i); 5858 secondary = false; 5859 if (slot.secondary) { 5860 res = this.getName(name, slot.secondary, false, res.usedOrig); 5861 if (res.name) { 5862 secondary = this._renderOnePersonalName(res.name, pos, i); 5863 } 5864 } 5865 tertiary = false; 5866 if (slot.tertiary) { 5867 res = this.getName(name, slot.tertiary, false, res.usedOrig); 5868 if (res.name) { 5869 tertiary = this._renderOnePersonalName(res.name, pos, i); 5870 } 5871 } 5872 var personblob; 5873 if (secondary || tertiary) { 5874 var multiblob = this._join([secondary, tertiary], ", "); 5875 var group_tok = new CSL.Token(); 5876 group_tok.strings.prefix = " ["; 5877 group_tok.strings.suffix = "]"; 5878 this.state.output.openLevel(group_tok); 5879 this.state.output.append(multiblob); 5880 this.state.output.closeLevel(); 5881 multiblob = this.state.output.pop(); 5882 personblob = this._join([primary, multiblob], ""); 5883 } else { 5884 personblob = primary; 5885 } 5886 names.push(personblob); 5537 5887 } 5538 5888 ret = this.joinPersons(names, pos); … … 5571 5921 if (this.state.opt["demote-non-dropping-particle"] === "never") { 5572 5922 first = this._join([non_dropping_particle, family, dropping_particle], " "); 5573 merged = this._join([first, given], sort_sep);5574 blob = this._join([merged, suffix], suffix_sep);5923 merged = this._join([first, given], " "); 5924 blob = this._join([merged, suffix], " "); 5575 5925 } else { 5576 5926 second = this._join([given, dropping_particle, non_dropping_particle], " "); 5577 merged = this._join([family, second], sort_sep);5578 blob = this._join([merged, suffix], suffix_sep);5927 merged = this._join([family, second], " "); 5928 blob = this._join([merged, suffix], " "); 5579 5929 } 5580 5930 } else if (this.name.strings["name-as-sort-order"] === "all" || (this.name.strings["name-as-sort-order"] === "first" && i === 0)) { 5931 if (["Lord", "Lady"].indexOf(name.given) > -1) { 5932 sort_sep = ", "; 5933 } 5581 5934 if (["always", "display-and-sort"].indexOf(this.state.opt["demote-non-dropping-particle"]) > -1) { 5582 5935 second = this._join([given, dropping_particle], (name["comma-dropping-particle"] + " ")); … … 5628 5981 blob = this._join([given, second], (name["comma-dropping-particle"] + " ")); 5629 5982 } 5983 this.state.tmp.group_context.value()[2] = true; 5984 this.state.tmp.can_substitute.replace(false, CSL.LITERAL); 5630 5985 this.state.tmp.name_node.children.push(blob); 5631 5986 return blob; … … 5642 5997 literal:value.literal, 5643 5998 family:value.family, 5999 isInstitution:value.isInstitution, 5644 6000 given:value.given, 5645 6001 suffix:value.suffix, … … 5650 6006 "parse-names":value["parse-names"], 5651 6007 "comma-dropping-particle": "", 5652 block_initialize:value.block_initialize 6008 block_initialize:value.block_initialize, 6009 multi:value.multi 5653 6010 }; 5654 6011 this._parseName(name); 5655 6012 return name; 5656 };5657 CSL.NameOutput.prototype._transformNameset = function (nameset) {5658 for (var i = 0, ilen = nameset.length; i < ilen; i += 1) {5659 nameset[i] = this.state.transform.name(this.state, nameset[i], this.state.opt["locale-pri"]);5660 nameset[i] = this._normalizeNameInput(nameset[i]);5661 }5662 6013 }; 5663 6014 CSL.NameOutput.prototype._stripPeriods = function (tokname, str) { … … 5736 6087 return false; 5737 6088 }; 5738 CSL.NameOutput.prototype._getLongStyle = function ( v, i) {6089 CSL.NameOutput.prototype._getLongStyle = function (name, v, i) { 5739 6090 var long_style, short_style; 5740 if ( this.institutions[v][i]["short"].length) {6091 if (name["short"].length) { 5741 6092 if (this.institutionpart["long-with-short"]) { 5742 6093 long_style = this.institutionpart["long-with-short"]; … … 5814 6165 } 5815 6166 }; 6167 CSL.NameOutput.prototype.getName = function (name, slotLocaleset, fallback, stopOrig) { 6168 if (stopOrig && slotLocaleset === 'locale-orig') { 6169 return {name:false,usedOrig:stopOrig}; 6170 } 6171 if (!name.family) { 6172 name.family = ""; 6173 } 6174 if (!name.given) { 6175 name.given = ""; 6176 } 6177 var static_ordering_freshcheck = false; 6178 var block_initialize = false; 6179 var transliterated = false; 6180 var static_ordering_val = this.getStaticOrder(name); 6181 var foundTag = true; 6182 if (slotLocaleset !== 'locale-orig') { 6183 foundTag = false; 6184 if (name.multi) { 6185 var langTags = this.state.opt[slotLocaleset] 6186 for (i = 0, ilen = langTags.length; i < ilen; i += 1) { 6187 langTag = langTags[i]; 6188 if (name.multi._key[langTag]) { 6189 foundTag = true; 6190 name = name.multi._key[langTag]; 6191 transliterated = true; 6192 if (!this.state.opt['locale-use-original-name-format'] && false) { 6193 static_ordering_freshcheck = true; 6194 } else { 6195 if ((name.family.replace('"','','g') + name.given).match(CSL.ROMANESQUE_REGEXP)) { 6196 block_initialize = true; 6197 } 6198 } 6199 break; 6200 } 6201 } 6202 } 6203 } 6204 if (!fallback && !foundTag) { 6205 return {name:false,usedOrig:stopOrig}; 6206 } 6207 if (!name.family) { 6208 name.family = ""; 6209 } 6210 if (!name.given) { 6211 name.given = ""; 6212 } 6213 name = { 6214 family:name.family, 6215 given:name.given, 6216 "non-dropping-particle":name["non-dropping-particle"], 6217 "dropping-particle":name["dropping-particle"], 6218 suffix:name.suffix, 6219 "static-ordering":static_ordering_val, 6220 "parse-names":name["parse-names"], 6221 "comma-suffix":name["comma-suffix"], 6222 "comma-dropping-particle":name["comma-dropping-particle"], 6223 transliterated:transliterated, 6224 block_initialize:block_initialize, 6225 literal:name.literal, 6226 isInstitution:name.isInstitution, 6227 }; 6228 if (static_ordering_freshcheck && 6229 !this.getStaticOrder(name, true)) { 6230 name["static-ordering"] = false; 6231 } 6232 if (!name.literal && (!name.given && name.family && name.isInstitution)) { 6233 name.literal = name.family; 6234 } 6235 if (name.literal) { 6236 delete name.family; 6237 delete name.given; 6238 } 6239 name = this._normalizeNameInput(name); 6240 var usedOrig; 6241 if (stopOrig) { 6242 usedOrig = stopOrig; 6243 } else { 6244 usedOrig = !foundTag; 6245 } 6246 return {name:name,usedOrig:usedOrig}; 6247 } 6248 CSL.NameOutput.prototype.fixupInstitution = function (name, varname, listpos) { 6249 name = this._splitInstitution(name, varname, listpos); 6250 if (this.institution.strings["reverse-order"]) { 6251 name["long"].reverse(); 6252 } 6253 var long_form = name["long"]; 6254 var short_form = long_form.slice(); 6255 if (this.state.sys.getAbbreviation) { 6256 var jurisdiction = this.Item.jurisdiction; 6257 for (var j = 0, jlen = long_form.length; j < jlen; j += 1) { 6258 jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-part", long_form[j]); 6259 if (this.state.transform.abbrevs[jurisdiction]["institution-part"][long_form[j]]) { 6260 short_form[j] = this.state.transform.abbrevs[jurisdiction]["institution-part"][long_form[j]]; 6261 } 6262 } 6263 } 6264 name["short"] = short_form; 6265 return name; 6266 } 6267 CSL.NameOutput.prototype.getStaticOrder = function (name, refresh) { 6268 var static_ordering_val = false; 6269 if (!refresh && name["static-ordering"]) { 6270 static_ordering_val = true; 6271 } else if (!(name.family.replace('"', '', 'g') + name.given).match(CSL.ROMANESQUE_REGEXP)) { 6272 static_ordering_val = true; 6273 } else if (name.multi && name.multi.main && name.multi.main.slice(0,2) == 'vn') { 6274 static_ordering_val = true; 6275 } else { 6276 if (this.state.opt['auto-vietnamese-names'] 6277 && (CSL.VIETNAMESE_NAMES.exec(name.family + " " + name.given) 6278 && CSL.VIETNAMESE_SPECIALS.exec(name.family + name.given))) { 6279 static_ordering_val = true; 6280 } 6281 } 6282 return static_ordering_val; 6283 } 6284 CSL.NameOutput.prototype._splitInstitution = function (value, v, i) { 6285 var ret = {}; 6286 var splitInstitution = value.literal.replace(/\s*\|\s*/g, "|"); 6287 splitInstitution = splitInstitution.split("|"); 6288 if (this.institution.strings.form === "short" && this.state.sys.getAbbreviation) { 6289 var jurisdiction = this.Item.jurisdiction; 6290 for (var j = splitInstitution.length; j > 0; j += -1) { 6291 var str = splitInstitution.slice(0, j).join("|"); 6292 jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-entire", str); 6293 if (this.state.transform.abbrevs[jurisdiction]["institution-entire"][str]) { 6294 var splitLst = this.state.transform.abbrevs[jurisdiction]["institution-entire"][str]; 6295 var splitSplitLst = splitLst.split(/>>[0-9]{4}>>/); 6296 var m = splitLst.match(/>>([0-9]{4})>>/); 6297 splitLst = splitSplitLst.pop(); 6298 if (splitSplitLst.length > 0 && this.Item.issued && this.Item.issued.year) { 6299 for (var k=m.length - 1; k > 0; k += -1) { 6300 if (parseInt(this.Item.issued.year, 10) >= parseInt(m[k], 10)) { 6301 break; 6302 } 6303 splitLst = splitSplitLst.pop(); 6304 } 6305 } 6306 splitLst = splitLst.replace(/\s*\|\s*/g, "|"); 6307 splitLst = splitLst.split("|"); 6308 splitInstitution = splitLst.concat(splitInstitution.slice(j)); 6309 } 6310 } 6311 } 6312 splitInstitution.reverse(); 6313 ret["long"] = this._trimInstitution(splitInstitution, v, i); 6314 return ret; 6315 }; 6316 CSL.NameOutput.prototype._trimInstitution = function (subunits, v, i) { 6317 var use_first = false; 6318 var append_last = false; 6319 var stop_last = false; 6320 var s = subunits.slice(); 6321 if (this.institution) { 6322 if ("undefined" !== typeof this.institution.strings["use-first"]) { 6323 use_first = this.institution.strings["use-first"]; 6324 } 6325 if ("undefined" !== typeof this.institution.strings["stop-last"]) { 6326 s = s.slice(0, this.institution.strings["stop-last"]); 6327 subunits = subunits.slice(0, this.institution.strings["stop-last"]); 6328 } 6329 if ("undefined" !== typeof this.institution.strings["use-last"]) { 6330 append_last = this.institution.strings["use-last"]; 6331 } 6332 } 6333 if (false === use_first) { 6334 if (this.persons[v].length === 0) { 6335 use_first = this.institution.strings["substitute-use-first"]; 6336 } 6337 if (!use_first) { 6338 use_first = 0; 6339 } 6340 } 6341 if (false === append_last) { 6342 if (!use_first) { 6343 append_last = subunits.length; 6344 } else { 6345 append_last = 0; 6346 } 6347 } 6348 if (use_first > subunits.length - append_last) { 6349 use_first = subunits.length - append_last; 6350 } 6351 if (stop_last) { 6352 append_last = 0; 6353 } 6354 subunits = subunits.slice(0, use_first); 6355 s = s.slice(use_first); 6356 if (append_last) { 6357 if (append_last > s.length) { 6358 append_last = s.length; 6359 } 6360 if (append_last) { 6361 subunits = subunits.concat(s.slice((s.length - append_last))); 6362 } 6363 } 6364 return subunits; 6365 }; 5816 6366 CSL.NameOutput.prototype.setEtAlParameters = function () { 5817 6367 var i, ilen, j, jlen; … … 5867 6417 myterm = node.strings.term; 5868 6418 } 5869 var plural = 0; 5870 if ("locator" === node.strings.term) { 5871 if (item && item.locator) { 5872 if (state.opt.development_extensions.locator_parsing_for_plurals) { 5873 if (!state.tmp.shadow_numbers.locator) { 5874 state.processNumber(false, item, "locator"); 5875 } 5876 plural = state.tmp.shadow_numbers.locator.plural; 5877 } else { 5878 plural = CSL.evaluateStringPluralism(item.locator); 5879 } 5880 } 5881 } else if (["page", "page-first"].indexOf(node.variables[0]) > -1) { 5882 plural = CSL.evaluateStringPluralism(Item[myterm]); 5883 } else { 5884 if (!state.tmp.shadow_numbers[myterm]) { 5885 state.processNumber(false, Item, myterm); 5886 } 5887 plural = state.tmp.shadow_numbers[myterm].plural; 6419 var plural = node.strings.plural; 6420 if ("number" !== typeof plural) { 6421 if ("locator" === node.strings.term) { 6422 if (item && item.locator) { 6423 if (state.opt.development_extensions.locator_parsing_for_plurals) { 6424 if (!state.tmp.shadow_numbers.locator) { 6425 state.processNumber(false, item, "locator"); 6426 } 6427 plural = state.tmp.shadow_numbers.locator.plural; 6428 } else { 6429 plural = CSL.evaluateStringPluralism(item.locator); 6430 } 6431 } 6432 } else if (["page", "page-first"].indexOf(node.variables[0]) > -1) { 6433 plural = CSL.evaluateStringPluralism(Item[myterm]); 6434 } else { 6435 if (!state.tmp.shadow_numbers[myterm]) { 6436 state.processNumber(false, Item, myterm); 6437 } 6438 plural = state.tmp.shadow_numbers[myterm].plural; 6439 } 5888 6440 } 5889 6441 return CSL.castLabel(state, node, myterm, plural); 5890 6442 }; 5891 6443 CSL.evaluateStringPluralism = function (str) { 5892 if (str && str.match(/(?:[0-9],\s*[0-9]|\s+and\s+|&|[0-9]\s*[\-\u2013]\s*[0-9])/)) { 5893 return 1; 5894 } else { 5895 return 0; 5896 } 6444 if (str) { 6445 var m = str.match(/(?:[0-9],\s*[0-9]|\s+and\s+|&|([0-9]+)\s*[\-\u2013]\s*([0-9]+))/) 6446 if (m && (!m[1] || parseInt(m[1]) < parseInt(m[2]))) { 6447 return 1 6448 } 6449 } 6450 return 0; 5897 6451 }; 5898 6452 CSL.castLabel = function (state, node, term, plural, mode) { … … 5910 6464 return ret; 5911 6465 }; 5912 CSL.PublisherOutput = function (state ) {6466 CSL.PublisherOutput = function (state, group_tok) { 5913 6467 this.state = state; 6468 this.group_tok = group_tok; 5914 6469 this.varlist = []; 5915 6470 }; … … 5923 6478 CSL.PublisherOutput.prototype.composeAndBlob = function () { 5924 6479 this.and_blob = {}; 5925 var and_term ;5926 if (this. and === "text") {6480 var and_term = false; 6481 if (this.group_tok.strings.and === "text") { 5927 6482 and_term = this.state.getTerm("and"); 5928 } else if (this. and === "symbol") {6483 } else if (this.group_tok.strings.and === "symbol") { 5929 6484 and_term = "&"; 5930 6485 } … … 5934 6489 this.state.output.append(and_term, tok, true); 5935 6490 var no_delim = this.state.output.pop(); 5936 tok.strings.prefix = this. name_delimiter;6491 tok.strings.prefix = this.group_tok.strings["subgroup-delimiter"]; 5937 6492 this.state.output.append(and_term, tok, true); 5938 6493 var with_delim = this.state.output.pop(); 5939 if (this.delimiter_precedes_last === "always") { 5940 this.and_blob.single = with_delim; 5941 } else if (this.delimiter_precedes_last === "never") { 5942 this.and_blob.single = no_delim; 5943 this.and_blob.multiple = no_delim; 5944 } else { 5945 this.and_blob.single = no_delim; 5946 this.and_blob.multiple = with_delim; 6494 this.and_blob.single = false; 6495 this.and_blob.multiple = false; 6496 if (and_term) { 6497 if (this.group_tok.strings["subgroup-delimiter-precedes-last"] === "always") { 6498 this.and_blob.single = with_delim; 6499 } else if (this.group_tok.strings["subgroup-delimiter-precedes-last"] === "never") { 6500 this.and_blob.single = no_delim; 6501 this.and_blob.multiple = no_delim; 6502 } else { 6503 this.and_blob.single = no_delim; 6504 this.and_blob.multiple = with_delim; 6505 } 5947 6506 } 5948 6507 }; … … 5969 6528 var blobs = this["publisher-list"]; 5970 6529 var delim = this.name_delimiter; 5971 var publishers = this._join(blobs, delim, this.and_blob.single, this.and_blob.multiple, this.group_tok);6530 var publishers = this._join(blobs, this.group_tok.strings["subgroup-delimiter"], this.and_blob.single, this.and_blob.multiple, this.group_tok); 5972 6531 this.state.output.append(publishers, "literal"); 5973 6532 }; … … 6112 6671 this.and_term = "&"; 6113 6672 } 6673 state.build.and_term = this.and_term; 6114 6674 if (CSL.STARTSWITH_ROMANESQUE_REGEXP.test(this.and_term)) { 6115 6675 this.and_prefix_single = " "; … … 6137 6697 this.ellipsis_prefix_multiple = this.strings.delimiter; 6138 6698 this.ellipsis_suffix = " "; 6139 }6140 if (this.strings["delimiter-precedes-et-al"] === "always") {6141 this.and_prefix_single = this.strings.delimiter;6142 } else if (this.strings["delimiter-precedes-last"] === "never") {6143 if (this.and_prefix_multiple) {6144 this.and_prefix_multiple = " ";6145 }6146 6699 } 6147 6700 func = function (state, Item) { … … 6212 6765 if (this.tokentype === CSL.START) { 6213 6766 state.build.names_flag = true; 6214 func = function (state, Item) { 6767 state.build.names_level += 1; 6768 func = function (state, Item, item) { 6215 6769 state.tmp.can_substitute.push(true); 6216 };6217 this.execs.push(func);6218 func = function (state, Item, item) {6219 6770 state.parallel.StartVariable("names"); 6220 };6221 this.execs.push(func);6222 func = function (state, Item, item) {6223 6771 state.nameOutput.init(this); 6224 6772 }; … … 6229 6777 var key = ["family", "given", "et-al"][i]; 6230 6778 this[key] = state.build[key]; 6231 state.build[key] = undefined; 6232 } 6779 if (state.build.names_level === 1) { 6780 state.build[key] = undefined; 6781 } 6782 } 6783 state.build.names_level += -1; 6233 6784 this.label = state.build.name_label; 6234 6785 state.build.name_label = undefined; … … 6347 6898 var values = state.tmp.shadow_numbers[varname].values; 6348 6899 var blob; 6900 var newstr = "" 6349 6901 if (state.opt["page-range-format"] 6350 6902 && !this.strings.prefix && !this.strings.suffix 6351 6903 && !this.strings.form) { 6352 var newstr = ""6353 6904 for (var i = 0, ilen = values.length; i < ilen; i += 1) { 6354 6905 newstr += values[i][1]; 6355 6906 } 6356 newstr = state.fun.page_mangler(newstr); 6907 } 6908 if (newstr && !newstr.match(/^[-.\u20130-9]+$/)) { 6357 6909 state.output.append(newstr, this); 6358 6910 } else { 6359 6911 state.output.openLevel("empty"); 6360 6912 for (var i = 0, ilen = values.length; i < ilen; i += 1) { 6361 var blob = new CSL[values[i][0]](values[i][1], values[i][2] );6913 var blob = new CSL[values[i][0]](values[i][1], values[i][2], Item.id); 6362 6914 if (i > 0) { 6363 6915 blob.strings.prefix = blob.strings.prefix.replace(/^\s*/, ""); … … 6366 6918 blob.strings.suffix = blob.strings.suffix.replace(/\s*$/, ""); 6367 6919 } 6368 state.output.append(blob, "literal" );6920 state.output.append(blob, "literal", false, false, true); 6369 6921 } 6370 6922 state.output.closeLevel("empty"); … … 6384 6936 state.opt.sort_citations = true; 6385 6937 } 6386 state.build.sort_flag = true; 6387 state.build.area_return = state.build.area; 6388 state.build.area = state.build.area + "_sort"; 6938 state.build.area = state.build.root + "_sort"; 6939 state.build.extension = "_sort"; 6940 var func = function (state, Item) { 6941 } 6942 this.execs.push(func); 6389 6943 } 6390 6944 if (this.tokentype === CSL.END) { 6391 state.build.area = state.build.area_return; 6392 state.build.sort_flag = false; 6393 } 6945 state.build.area = state.build.root; 6946 state.build.extension = ""; 6947 } 6948 target.push(this); 6394 6949 } 6395 6950 }; … … 6432 6987 if ("citation-number" === this.variables_real[0] || "year-suffix" === this.variables_real[0] || "citation-label" === this.variables_real[0]) { 6433 6988 if (this.variables_real[0] === "citation-number") { 6434 if (state.build. area=== "citation") {6989 if (state.build.root === "citation") { 6435 6990 state.opt.update_mode = CSL.NUMERIC; 6436 6991 } 6437 if (state.build. area=== "bibliography") {6992 if (state.build.root === "bibliography") { 6438 6993 state.opt.bib_mode = CSL.NUMERIC; 6439 6994 } … … 6465 7020 state.output.append(state.opt.citation_number_slug, this); 6466 7021 } else { 6467 number = new CSL.NumericBlob(num, this );7022 number = new CSL.NumericBlob(num, this, Item.id); 6468 7023 state.output.append(number, "literal"); 6469 7024 } … … 6483 7038 if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix !== false && !state.tmp.just_looking) { 6484 7039 num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10); 6485 number = new CSL.NumericBlob(num, this );7040 number = new CSL.NumericBlob(num, this, Item.id); 6486 7041 formatter = new CSL.Util.Suffixator(CSL.SUFFIX_CHARS); 6487 7042 number.setFormatter(formatter); 6488 7043 state.output.append(number, "literal"); 6489 7044 firstoutput = false; 6490 len = state.tmp. term_sibling.mystack.length;7045 len = state.tmp.group_context.mystack.length; 6491 7046 for (pos = 0; pos < len; pos += 1) { 6492 flag = state.tmp. term_sibling.mystack[pos];7047 flag = state.tmp.group_context.mystack[pos]; 6493 7048 if (!flag[2] && (flag[1] || (!flag[1] && !flag[0]))) { 6494 7049 firstoutput = true; … … 6522 7077 } else { 6523 7078 if (this.strings.term) { 6524 func = function (state, Item ) {7079 func = function (state, Item, item) { 6525 7080 var gender = state.opt.gender[Item.type]; 6526 7081 var term = this.strings.term; … … 6528 7083 var myterm; 6529 7084 if (term !== "") { 6530 flag = state.tmp. term_sibling.value();7085 flag = state.tmp.group_context.value(); 6531 7086 flag[0] = true; 6532 state.tmp. term_sibling.replace(flag);7087 state.tmp.group_context.replace(flag); 6533 7088 } 6534 7089 if (!state.tmp.term_predecessor) { … … 6566 7121 if (form === "short") { 6567 7122 state.transform.init(this, this.variables_real[0], this.variables_real[0]); 6568 } else {6569 state.transform.init(this, this.variables_real[0]);6570 }6571 if (state.build.area.slice(-5) === "_sort") {6572 state.transform.init(this, this.variables_real[0], this.variables_real[0]);6573 state.transform.setTransformLocale("locale-sort");6574 state.transform.setTransformFallback(true);6575 func = state.transform.getOutputFunction(this.variables);6576 } else if (form === "short") {6577 if (["title", "container-title", "collection-title"].indexOf(this.variables_real[0]) > -1) {6578 state.transform.setTransformLocale("locale-sec");6579 } else {6580 state.transform.setTransformLocale("locale-pri");6581 }6582 state.transform.setTransformFallback(true);6583 state.transform.setAbbreviationFallback(true);6584 7123 if (this.variables_real[0] === "container-title") { 6585 7124 state.transform.setAlternativeVariableName("journalAbbreviation"); 6586 7125 } else if (this.variables_real[0] === "title") { 6587 7126 state.transform.setAlternativeVariableName("shortTitle"); 6588 } else if (["publisher", "publisher-place", "event-place", "edition"].indexOf(this.variables_real[0]) > -1) {6589 state.transform.setTransformLocale("default-locale");6590 7127 } 6591 func = state.transform.getOutputFunction(this.variables); 6592 } else if (["title-short","title", "container-title", "collection-title"].indexOf(this.variables_real[0]) > -1) { 6593 state.transform.setTransformLocale("locale-sec"); 7128 } else { 7129 state.transform.init(this, this.variables_real[0]); 7130 } 7131 if (state.build.extension) { 7132 state.transform.init(this, this.variables_real[0], this.variables_real[0]); 6594 7133 state.transform.setTransformFallback(true); 6595 7134 func = state.transform.getOutputFunction(this.variables); 6596 7135 } else { 6597 state.transform.setTransformLocale("locale-pri");6598 7136 state.transform.setTransformFallback(true); 6599 if (["publisher", "publisher-place", "edition"].indexOf(this.variables_real[0]) > -1) { 6600 state.transform.setTransformLocale("default-locale"); 6601 } 7137 state.transform.setAbbreviationFallback(true); 6602 7138 func = state.transform.getOutputFunction(this.variables); 6603 }7139 } 6604 7140 if (this.variables_real[0] === "container-title") { 6605 7141 var xfunc = function (state, Item, item) { … … 6616 7152 var locator = "" + item[this.variables[0]]; 6617 7153 locator = locator.replace(/--*/g,"\u2013"); 6618 state.output.append(locator, this); 7154 var m = locator.match(/^([0-9]+)\s*\u2013\s*([0-9]+)$/) 7155 if (m) { 7156 if (parseInt(m[1]) >= parseInt(m[2])) { 7157 locator = m[1] + "-" + m[2]; 7158 } 7159 } 7160 state.output.append(locator, this, false, false, true); 6619 7161 } 6620 7162 }; … … 6629 7171 value = value.slice(0, idx); 6630 7172 } 6631 state.output.append(value, this );7173 state.output.append(value, this, false, false, true); 6632 7174 } 6633 7175 }; … … 6637 7179 if (value) { 6638 7180 value = state.fun.page_mangler(value); 6639 state.output.append(value, this );7181 state.output.append(value, this, false, false, true); 6640 7182 } 6641 7183 }; … … 6652 7194 } else if (this.variables_real[0] === "hereinafter") { 6653 7195 func = function (state, Item) { 6654 var hereinafter_key = state.transform.getHereinafter(Item); 6655 var value = state.transform.abbrevs.hereinafter[hereinafter_key]; 6656 if (hereinafter_key) { 7196 var hereinafter_info = state.transform.getHereinafter(Item); 7197 var value = state.transform.abbrevs[hereinafter_info[0]].hereinafter[hereinafter_info[1]]; 7198 if (value) { 7199 state.tmp.group_context.value()[2] = true; 7200 state.output.append(value, this); 7201 } 7202 }; 7203 } else if (this.variables_real[0] === "URL") { 7204 func = function (state, Item) { 7205 var value; 7206 if (this.variables[0]) { 7207 value = state.getVariable(Item, this.variables[0], form); 7208 if (value) { 7209 state.output.append(value, this, false, false, true); 7210 } 7211 } 7212 }; 7213 } else if (this.variables_real[0] === "section") { 7214 func = function (state, Item) { 7215 var value; 7216 value = state.getVariable(Item, this.variables[0], form); 7217 if (value) { 7218 if ((Item.type === "bill" || Item.type === "legislation") 7219 && state.opt.development_extensions.parse_section_variable) { 7220 value = "" + value; 7221 var m = value.match(CSL.STATUTE_SUBDIV_GROUPED_REGEX); 7222 if (m) { 7223 var splt = value.split(CSL.STATUTE_SUBDIV_PLAIN_REGEX); 7224 var lst = []; 7225 if (!lst[0]) { 7226 var parsed = false; 7227 for (var i=1, ilen=splt.length; i < ilen; i += 1) { 7228 var subdiv = m[i - 1].replace(/^\s*/, ""); 7229 subdiv = CSL.STATUTE_SUBDIV_STRINGS[subdiv]; 7230 var plural = false; 7231 if (splt[i].match(/(?:&|, | and )/)) { 7232 plural = true; 7233 } 7234 subdiv = state.getTerm(subdiv, "symbol", plural); 7235 if (subdiv) { 7236 parsed = true; 7237 } 7238 lst.push(subdiv); 7239 lst.push(splt[i].replace(/\s*,*\s*$/, "").replace(/^\s*,*\s*/, "")); 7240 } 7241 if (parsed) { 7242 value = lst.join(" "); 7243 } 7244 } 7245 } 7246 } 6657 7247 state.output.append(value, this); 6658 7248 } … … 6678 7268 func = function (state, Item) { 6679 7269 var flag; 6680 flag = state.tmp. term_sibling.value();7270 flag = state.tmp.group_context.value(); 6681 7271 flag[0] = true; 6682 state.tmp. term_sibling.replace(flag);7272 state.tmp.group_context.replace(flag); 6683 7273 state.output.append(this.strings.value, this); 6684 7274 }; … … 6692 7282 }; 6693 7283 CSL.Attributes = {}; 7284 CSL.Attributes["@has-year-only"] = function (state, arg) { 7285 trydates = arg.split(/\s+/); 7286 func = function (state, Item, item) { 7287 var ret = []; 7288 for (var i = 0, ilen = trydates.length; i < ilen; i += 1) { 7289 var trydate = Item[trydates[i]]; 7290 if (!trydate || trydate.month || trydate.season) { 7291 ret.push(false) 7292 } else { 7293 ret.push(true) 7294 } 7295 } 7296 return ret; 7297 }; 7298 this.tests.push(func); 7299 } 7300 CSL.Attributes["@has-month-or-season-only"] = function (state, arg) { 7301 trydates = arg.split(/\s+/); 7302 func = function (state, Item, item) { 7303 var ret = []; 7304 for (var i = 0, ilen = trydates.length; i < ilen; i += 1) { 7305 var trydate = Item[trydates[i]]; 7306 if (!trydate || (!trydate.month && !trydate.season) || trydate.day) { 7307 ret.push(false) 7308 } else { 7309 ret.push(true) 7310 } 7311 } 7312 return ret; 7313 }; 7314 this.tests.push(func); 7315 } 7316 CSL.Attributes["@has-day-only"] = function (state, arg) { 7317 trydates = arg.split(/\s+/); 7318 func = function (state, Item, item) { 7319 var ret = []; 7320 for (var i = 0, ilen = trydates.length; i < ilen; i += 1) { 7321 var trydate = Item[trydates[i]]; 7322 if (!trydate || !trydate.day) { 7323 ret.push(false) 7324 } else { 7325 ret.push(true) 7326 } 7327 } 7328 return ret; 7329 }; 7330 this.tests.push(func); 7331 } 7332 CSL.Attributes["@part-separator"] = function (state, arg) { 7333 this.strings["part-separator"] = arg; 7334 } 7335 CSL.Attributes["@context"] = function (state, arg) { 7336 var func = function (state, Item) { 7337 var area = state.tmp.area.slice(0, arg.length); 7338 var result = false; 7339 if (area === arg) { 7340 result = true; 7341 } 7342 return result; 7343 }; 7344 this.tests.push(func); 7345 }; 6694 7346 CSL.Attributes["@trigger-fields"] = function (state, arg) { 6695 7347 var mylst = arg.split(/\s+/); … … 6772 7424 this.variables.push(variables[pos]); 6773 7425 } 6774 if ("hereinafter" === variables[pos] ) {6775 var hereinafter_ key= state.transform.getHereinafter(Item);6776 state.transform.loadAbbreviation( "hereinafter", hereinafter_key);7426 if ("hereinafter" === variables[pos] && state.sys.getAbbreviation) { 7427 var hereinafter_info = state.transform.getHereinafter(Item); 7428 state.transform.loadAbbreviation(hereinafter_info[0], "hereinafter", hereinafter_info[1]); 6777 7429 } 6778 7430 if (state.tmp.can_block_substitute) { … … 6790 7442 if (variable === "page-first") { 6791 7443 variable = "page"; 7444 } 7445 if (variable === "authority" 7446 && "string" === typeof Item[variable] 7447 && "names" === this.name) { 7448 Item[variable] = [{family:Item[variable],isInstitution:true}] 6792 7449 } 6793 7450 if (this.strings.form === "short" && !Item[variable]) { … … 6841 7498 } else if ("object" === typeof Item[variable]) { 6842 7499 if (Item[variable].length) { 6843 output = true;6844 7500 } 6845 7501 break; … … 6855 7511 } 6856 7512 } 6857 flag = state.tmp. term_sibling.value();7513 flag = state.tmp.group_context.value(); 6858 7514 if (output) { 6859 7515 if (variable !== "citation-number" || state.tmp.area !== "bibliography") { … … 6861 7517 } 6862 7518 flag[2] = true; 6863 state.tmp. term_sibling.replace(flag);7519 state.tmp.group_context.replace(flag); 6864 7520 state.tmp.can_substitute.replace(false, CSL.LITERAL); 6865 7521 } else { … … 6877 7533 x = false; 6878 7534 myitem = Item; 6879 if (item && ["locator", " first-reference-note-number", "locator-date"].indexOf(variable) > -1) {7535 if (item && ["locator", "locator-revision", "first-reference-note-number", "locator-date"].indexOf(variable) > -1) { 6880 7536 myitem = item; 6881 7537 } 6882 if (myitem[variable]) { 7538 if (variable === "hereinafter" && state.sys.getAbbreviation) { 7539 var hereinafter_info = state.transform.getHereinafter(myitem); 7540 state.transform.loadAbbreviation(hereinafter_info[0], "hereinafter", hereinafter_info[1]); 7541 if (state.transform.abbrevs[hereinafter_info[0]].hereinafter[hereinafter_info[1]]) { 7542 x = true 7543 } 7544 } else if (myitem[variable]) { 6883 7545 if ("number" === typeof myitem[variable] || "string" === typeof myitem[variable]) { 6884 7546 x = true; … … 6987 7649 var lex = arg.split(/\s+/); 6988 7650 var func = function (state, Item) { 7651 var mylex = false; 6989 7652 var ret = false; 6990 var mylex = false;6991 7653 if (Item.jurisdiction) { 6992 7654 mylex = Item.jurisdiction; 6993 7655 } else if (Item.language) { 6994 var m = Item.language.match(/^.*-x-lex-([. a-zA-Z]+).*$/);7656 var m = Item.language.match(/^.*-x-lex-([.;a-zA-Z]+).*$/); 6995 7657 if (m) { 6996 7658 mylex = m[1]; 6997 7659 } 6998 7660 } 6999 for (var i = 0, ilen = lex.length; i < ilen; i += 1) { 7000 if (mylex === lex[i]) { 7001 ret = true; 7002 break; 7661 if (mylex) { 7662 var mylexlst = mylex.split(";"); 7663 outerLoop: for (var i = 0, ilen = lex.length; i < ilen; i += 1) { 7664 if (!lex[i]) { 7665 continue; 7666 } 7667 var lexlst = lex[i].split(";"); 7668 innerLoop: for (var j = 0, jlen = lexlst.length; j < jlen; j += 1) { 7669 if (mylexlst[j] && mylexlst[j] === lexlst[j] && j === lexlst.length - 1) { 7670 ret = true; 7671 break outerLoop; 7672 } 7673 } 7003 7674 } 7004 7675 } … … 7041 7712 } 7042 7713 } 7043 if (!state.tmp.shadow_numbers[variables[pos]].numeric) { 7714 if (!state.tmp.shadow_numbers[variables[pos]].numeric 7715 && !(variables[pos] === 'title' 7716 && Item[variables[pos]] 7717 && Item[variables[pos]].slice(-1) === "" + parseInt(Item[variables[pos]].slice(-1)))) { 7044 7718 numeric = false; 7045 7719 break; … … 7125 7799 var tryposition; 7126 7800 state.opt.update_mode = CSL.POSITION; 7127 var factory = function (tryposition) { 7128 return function (state, Item, item) { 7129 if (state.tmp.area === "bibliography" || state.tmp.area === "bibliography_sort") { 7130 return false; 7131 } 7132 if (item && "undefined" === typeof item.position) { 7133 item.position = 0; 7134 } 7135 if (item && typeof item.position === "number") { 7136 if (item.position === 0 && tryposition === 0) { 7137 return true; 7138 } else if (tryposition > 0 && item.position >= tryposition) { 7139 return true; 7140 } 7141 } else if (tryposition === 0) { 7801 if ("near-note" === arg) { 7802 var near_note_func = function (state, Item, item) { 7803 if (item && item["near-note"]) { 7142 7804 return true; 7143 7805 } 7144 7806 return false; 7145 7807 }; 7146 }; 7147 var near_note_func = function (state, Item, item) { 7148 if (item && item["near-note"]) { 7149 return true; 7150 } 7151 return false; 7152 }; 7153 var lst = arg.split(/\s+/); 7154 for (var i = 0, ilen = lst.length; i < ilen; i += 1) { 7155 if (lst[i] === "first") { 7156 tryposition = CSL.POSITION_FIRST; 7157 } else if (lst[i] === "subsequent") { 7158 tryposition = CSL.POSITION_SUBSEQUENT; 7159 } else if (lst[i] === "ibid") { 7160 tryposition = CSL.POSITION_IBID; 7161 } else if (lst[i] === "ibid-with-locator") { 7162 tryposition = CSL.POSITION_IBID_WITH_LOCATOR; 7163 } 7164 var func = factory(tryposition); 7165 this.tests.push(func); 7166 if (lst[i] === "near-note") { 7167 this.tests.push(near_note_func); 7168 } 7169 } 7170 }; 7808 this.tests.push(near_note_func); 7809 } else { 7810 var factory = function (tryposition) { 7811 return function (state, Item, item) { 7812 if (state.tmp.area === "bibliography") { 7813 return false; 7814 } 7815 if (item && "undefined" === typeof item.position) { 7816 item.position = 0; 7817 } 7818 if (item && typeof item.position === "number") { 7819 if (item.position === 0 && tryposition === 0) { 7820 return true; 7821 } else if (tryposition > 0 && item.position >= tryposition) { 7822 return true; 7823 } 7824 } else if (tryposition === 0) { 7825 return true; 7826 } 7827 return false; 7828 }; 7829 }; 7830 var lst = arg.split(/\s+/); 7831 for (var i = 0, ilen = lst.length; i < ilen; i += 1) { 7832 if (lst[i] === "first") { 7833 tryposition = CSL.POSITION_FIRST; 7834 } else if (lst[i] === "subsequent") { 7835 tryposition = CSL.POSITION_SUBSEQUENT; 7836 } else if (lst[i] === "ibid") { 7837 tryposition = CSL.POSITION_IBID; 7838 } else if (lst[i] === "ibid-with-locator") { 7839 tryposition = CSL.POSITION_IBID_WITH_LOCATOR; 7840 } 7841 var func = factory(tryposition); 7842 this.tests.push(func); 7843 } 7844 } 7845 } 7171 7846 CSL.Attributes["@disambiguate"] = function (state, arg) { 7172 7847 if (this.tokentype === CSL.START && ["if", "else-if"].indexOf(this.name) > -1) { … … 7199 7874 state.setOpt(this, "name-form", arg); 7200 7875 }; 7876 CSL.Attributes["@subgroup-delimiter"] = function (state, arg) { 7877 this.strings["subgroup-delimiter"] = arg; 7878 }; 7879 CSL.Attributes["@subgroup-delimiter-precedes-last"] = function (state, arg) { 7880 this.strings["subgroup-delimiter-precedes-last"] = arg; 7881 }; 7201 7882 CSL.Attributes["@name-delimiter"] = function (state, arg) { 7202 7883 state.setOpt(this, "name-delimiter", arg); … … 7338 8019 CSL.Attributes["@default-locale"] = function (state, arg) { 7339 8020 var lst, len, pos, m, ret; 7340 m = arg.match(/-x-(sort| pri|sec|name)-/g);8021 m = arg.match(/-x-(sort|translit|translat)-/g); 7341 8022 if (m) { 7342 8023 for (pos = 0, len = m.length; pos < len; pos += 1) { … … 7344 8025 } 7345 8026 } 7346 lst = arg.split(/-x-(?:sort| pri|sec|name)-/);8027 lst = arg.split(/-x-(?:sort|translit|translat)-/); 7347 8028 ret = [lst[0]]; 7348 8029 for (pos = 1, len = lst.length; pos < len; pos += 1) { … … 7383 8064 this.strings["use-first"] = parseInt(arg, 10); 7384 8065 }; 8066 CSL.Attributes["@stop-last"] = function (state, arg) { 8067 this.strings["stop-last"] = parseInt(arg, 10) * -1; 8068 } 8069 CSL.Attributes["@oops"] = function (state, arg) { 8070 this.strings.oops = arg; 8071 } 7385 8072 CSL.Attributes["@use-last"] = function (state, arg) { 7386 if (arg.match(/^[0-9]+$/)) { 7387 this.strings["use-last"] = parseInt(arg, 10); 7388 } 8073 this.strings["use-last"] = parseInt(arg, 10); 7389 8074 }; 7390 8075 CSL.Attributes["@reverse-order"] = function (state, arg) { … … 7529 8214 }; 7530 8215 CSL.Transform = function (state) { 7531 var debug = false, abbreviations, token, fieldname, subsection, opt;8216 var debug = false, abbreviations, token, fieldname, abbrev_family, opt; 7532 8217 this.abbrevs = {}; 7533 this.abbrevs["container-title"] = {}; 7534 this.abbrevs["collection-title"] = {}; 7535 this.abbrevs.institution = {}; 7536 this.abbrevs.nickname = {}; 7537 this.abbrevs.place = {}; 7538 this.abbrevs.title = {}; 7539 this.abbrevs.hereinafter = {}; 7540 this.abbrevs.classic = {}; 7541 function init(t, f, x) { 7542 token = t; 7543 fieldname = f; 7544 subsection = x; 8218 this.abbrevs["default"] = new CSL.AbbreviationSegments(); 8219 function init(mytoken, myfieldname, myabbrev_family) { 8220 token = mytoken; 8221 fieldname = myfieldname; 8222 abbrev_family = myabbrev_family; 7545 8223 opt = { 7546 8224 abbreviation_fallback: false, 7547 8225 alternative_varname: false, 7548 transform_locale: false,7549 8226 transform_fallback: false 7550 8227 }; 7551 8228 } 7552 8229 this.init = init; 7553 function abbreviate(state, Item, altvar, basevalue, my subsection, use_field) {8230 function abbreviate(state, Item, altvar, basevalue, myabbrev_family, use_field) { 7554 8231 var value; 7555 if (!my subsection) {8232 if (!myabbrev_family) { 7556 8233 return basevalue; 7557 8234 } 7558 if (["publisher-place", "event-place"].indexOf(mysubsection) > -1) { 7559 mysubsection = "place"; 7560 } 7561 if (["publisher", "authority"].indexOf(mysubsection) > -1) { 7562 mysubsection = "institution"; 7563 } 7564 state.transform.loadAbbreviation(mysubsection, basevalue); 8235 if (["publisher-place", "event-place", "subjurisdiction"].indexOf(myabbrev_family) > -1) { 8236 myabbrev_family = "place"; 8237 } 8238 if (["publisher", "authority"].indexOf(myabbrev_family) > -1) { 8239 myabbrev_family = "institution-part"; 8240 } 8241 if (["genre", "event", "medium"].indexOf(myabbrev_family) > -1) { 8242 myabbrev_family = "title"; 8243 } 8244 if (["title-short"].indexOf(myabbrev_family) > -1) { 8245 myabbrev_family = "title"; 8246 } 7565 8247 value = ""; 7566 if (state.transform.abbrevs[mysubsection] && basevalue) { 7567 if (state.transform.abbrevs[mysubsection][basevalue]) { 7568 value = state.transform.abbrevs[mysubsection][basevalue]; 7569 } else if ("string" != typeof state.transform.abbrevs[mysubsection][basevalue]) { 7570 } 7571 } 7572 if (!value && Item[altvar] && use_field) { 8248 if (state.sys.getAbbreviation) { 8249 var jurisdiction = state.transform.loadAbbreviation(Item.jurisdiction, myabbrev_family, basevalue); 8250 if (state.transform.abbrevs[jurisdiction][myabbrev_family] && basevalue && state.sys.getAbbreviation) { 8251 if (state.transform.abbrevs[jurisdiction][myabbrev_family][basevalue]) { 8252 value = state.transform.abbrevs[jurisdiction][myabbrev_family][basevalue]; 8253 } 8254 } 8255 } 8256 if (!value && altvar && Item[altvar] && use_field) { 7573 8257 value = Item[altvar]; 7574 8258 } … … 7578 8262 return value; 7579 8263 } 7580 function getTextSubField(Item, field, locale_type, use_default ) {8264 function getTextSubField(Item, field, locale_type, use_default, stopOrig) { 7581 8265 var m, lst, opt, o, oo, pos, key, ret, len, myret, opts; 8266 var usedOrig = stopOrig; 7582 8267 if (!Item[field]) { 7583 return "";7584 } 7585 ret = "";8268 return {name:"", usedOrig:stopOrig}; 8269 } 8270 ret = {name:"", usedOrig:stopOrig}; 7586 8271 opts = state.opt[locale_type]; 7587 if ("undefined" === typeof opts) { 7588 opts = state.opt["default-locale"]; 8272 if (locale_type === 'locale-orig') { 8273 if (stopOrig) { 8274 ret = {name:"", usedOrig:stopOrig}; 8275 } else { 8276 ret = {name:Item[field], usedOrig:false}; 8277 } 8278 return ret; 8279 } else if (use_default && ("undefined" === typeof opts || opts.length === 0)) { 8280 return {name:Item[field], usedOrig:true}; 7589 8281 } 7590 8282 for (var i = 0, ilen = opts.length; i < ilen; i += 1) { … … 7592 8284 o = opt.split(/[\-_]/)[0]; 7593 8285 if (opt && Item.multi && Item.multi._keys[field] && Item.multi._keys[field][opt]) { 7594 ret = Item.multi._keys[field][opt];8286 ret.name = Item.multi._keys[field][opt]; 7595 8287 break; 7596 8288 } else if (o && Item.multi && Item.multi._keys[field] && Item.multi._keys[field][o]) { 7597 ret = Item.multi._keys[field][o];8289 ret.name = Item.multi._keys[field][o]; 7598 8290 break; 7599 8291 } 7600 8292 } 7601 if (!ret && use_default) {7602 ret = Item[field];8293 if (!ret.name && use_default) { 8294 ret = {name:Item[field], usedOrig:true}; 7603 8295 } 7604 8296 return ret; … … 7612 8304 } 7613 8305 this.setAlternativeVariableName = setAlternativeVariableName; 7614 function setTransformLocale(s) {7615 opt.transform_locale = s;7616 }7617 this.setTransformLocale = setTransformLocale;7618 8306 function setTransformFallback(b) { 7619 8307 opt.transform_fallback = b; 7620 8308 } 7621 8309 this.setTransformFallback = setTransformFallback; 7622 function loadAbbreviation( vartype, key) {8310 function loadAbbreviation(jurisdiction, category, orig) { 7623 8311 var pos, len; 7624 if (!this.abbrevs[vartype] || !key) { 7625 return; 7626 } 7627 if (state.sys.getAbbreviation && !this.abbrevs[vartype][key]) { 7628 state.sys.getAbbreviation(this.abbrevs, vartype, key); 7629 } 8312 if (!jurisdiction) { 8313 jurisdiction = "default"; 8314 } 8315 if (!orig) { 8316 if (!this.abbrevs[jurisdiction]) { 8317 this.abbrevs[jurisdiction] = new CSL.AbbreviationSegments(); 8318 } 8319 return jurisdiction; 8320 } 8321 if (state.sys.getAbbreviation) { 8322 var tryList = ['default']; 8323 if (jurisdiction !== 'default') { 8324 var workLst = jurisdiction.split(/\s*;\s*/); 8325 for (var i=0, ilen=workLst.length; i < ilen; i += 1) { 8326 tryList.push(workLst.slice(0,i+1).join(';')); 8327 } 8328 } 8329 for (var i=tryList.length - 1; i > -1; i += -1) { 8330 if (!this.abbrevs[tryList[i]]) { 8331 this.abbrevs[tryList[i]] = new CSL.AbbreviationSegments(); 8332 } 8333 if (!this.abbrevs[tryList[i]][category][orig]) { 8334 state.sys.getAbbreviation(state.opt.styleID, this.abbrevs, tryList[i], category, orig); 8335 } 8336 if (this.abbrevs[tryList[i]][category][orig]) { 8337 if (i < tryList.length) { 8338 this.abbrevs[jurisdiction][category][orig] = this.abbrevs[tryList[i]][category][orig]; 8339 } 8340 break; 8341 } 8342 } 8343 } 8344 return jurisdiction; 7630 8345 } 7631 8346 this.loadAbbreviation = loadAbbreviation; 7632 function publisherCheck (varname, primary, tok) { 8347 function publisherCheck (tok, Item, primary, myabbrev_family) { 8348 var varname = tok.variables[0]; 7633 8349 if (state.publisherOutput && primary) { 7634 8350 if (["publisher","publisher-place"].indexOf(varname) === -1) { … … 7639 8355 var lst = primary.split(/;\s*/); 7640 8356 if (lst.length === state.publisherOutput[varname + "-list"].length) { 7641 state.tmp[varname + "-list"] = lst; 8357 state.publisherOutput[varname + "-list"] = lst; 8358 } 8359 for (var i = 0, ilen = lst.length; i < ilen; i += 1) { 8360 lst[i] = abbreviate(state, Item, false, lst[i], myabbrev_family, true); 7642 8361 } 7643 8362 state.tmp[varname + "-token"] = tok; … … 7648 8367 } 7649 8368 function getOutputFunction(variables) { 7650 var mytoken, mysubsection, myfieldname, abbreviation_fallback, alternative_varname, transform_locale, transform_fallback, getTextSubfield; 7651 mytoken = CSL.Util.cloneToken(token); // the token isn't needed, is it? 7652 mysubsection = subsection; 8369 var myabbrev_family, myfieldname, abbreviation_fallback, alternative_varname, transform_locale, transform_fallback, getTextSubfield; 8370 myabbrev_family = abbrev_family; 7653 8371 myfieldname = fieldname; 7654 8372 abbreviation_fallback = opt.abbreviation_fallback; 7655 8373 alternative_varname = opt.alternative_varname; 7656 transform_locale = opt.transform_locale;7657 8374 transform_fallback = opt.transform_fallback; 7658 if (transform_locale === "locale-sec") { 7659 return function (state, Item) { 7660 var primary, secondary, primary_tok, secondary_tok, key; 7661 if (!variables[0]) { 7662 return null; 7663 } 7664 if (state.tmp["publisher-list"]) { 7665 if (variables[0] === "publisher") { 7666 state.tmp["publisher-token"] = this; 7667 } else if (variables[0] === "publisher-place") { 7668 state.tmp["publisher-place-token"] = this; 7669 } 7670 return null; 7671 } 7672 if (state.opt["locale-suppress-title-transliteration"] 7673 || !((state.tmp.area === 'bibliography' 7674 || (state.opt.xclass === "note" && 7675 state.tmp.area === "citation")) 7676 ) 7677 ) { 7678 primary = Item[myfieldname]; 7679 } else { 7680 primary = getTextSubField(Item, myfieldname, "locale-pri", transform_fallback); 7681 } 7682 if (mysubsection) { 7683 primary = abbreviate(state, Item, alternative_varname, primary, mysubsection, true); 7684 } 7685 secondary = getTextSubField(Item, myfieldname, "locale-sec"); 7686 if ("demote" === this["leading-noise-words"]) { 7687 primary = CSL.demoteNoiseWords(primary); 7688 secondary = CSL.demoteNoiseWords(secondary); 7689 } 7690 if (secondary && ((state.tmp.area === 'bibliography' || (state.opt.xclass === "note" && state.tmp.area === "citation")))) { 7691 if (mysubsection) { 7692 secondary = abbreviate(state, Item, alternative_varname, secondary, mysubsection, true); 7693 } 7694 primary_tok = CSL.Util.cloneToken(this); 7695 primary_tok.strings.suffix = ""; 7696 secondary_tok = new CSL.Token("text", CSL.SINGLETON); 7697 secondary_tok.strings.suffix = "]" + this.strings.suffix; 7698 secondary_tok.strings.prefix = " ["; 7699 state.output.append(primary, primary_tok); 7700 state.output.append(secondary, secondary_tok); 7701 } else { 7702 state.output.append(primary, this); 7703 } 8375 var localesets; 8376 var langPrefs = CSL.LangPrefsMap[myfieldname]; 8377 if (!langPrefs) { 8378 localesets = false; 8379 } else { 8380 localesets = state.opt['cite-lang-prefs'][langPrefs]; 8381 } 8382 return function (state, Item, item, usedOrig) { 8383 var primary, secondary, tertiary, primary_tok, group_tok, key; 8384 if (!variables[0]) { 7704 8385 return null; 7705 }; 7706 } else { 7707 return function (state, Item) { 7708 var primary; 7709 if (!variables[0]) { 7710 return null; 7711 } 7712 primary = getTextSubField(Item, myfieldname, transform_locale, transform_fallback); 7713 primary = abbreviate(state, Item, alternative_varname, primary, mysubsection, true); 7714 if (publisherCheck(variables[0], primary, this)) { 7715 return null; 7716 } else { 7717 if ("demote" === this["leading-noise-words"]) { 7718 primary = CSL.demoteNoiseWords(primary); 7719 } 7720 state.output.append(primary, this); 8386 } 8387 var slot = {primary:false, secondary:false, tertiary:false}; 8388 if (state.tmp.area.slice(-5) === "_sort") { 8389 slot.primary = 'locale-sort'; 8390 } else { 8391 if (localesets) { 8392 var slotnames = ["primary", "secondary", "tertiary"]; 8393 for (var i = 0, ilen = slotnames.length; i < ilen; i += 1) { 8394 if (localesets.length - 1 < i) { 8395 break; 8396 } 8397 if (localesets[i]) { 8398 slot[slotnames[i]] = 'locale-' + localesets[i]; 8399 } 8400 } 8401 } else { 8402 slot.primary = 'locale-translat'; 8403 } 8404 } 8405 if ((state.tmp.area !== "bibliography" 8406 && !(state.tmp.area === "citation" 8407 && state.opt.xclass === "note" 8408 && item && !item.position)) 8409 || myabbrev_family) { 8410 slot.secondary = false; 8411 slot.tertiary = false; 8412 } 8413 if (state.tmp["publisher-list"]) { 8414 if (variables[0] === "publisher") { 8415 state.tmp["publisher-token"] = this; 8416 } else if (variables[0] === "publisher-place") { 8417 state.tmp["publisher-place-token"] = this; 7721 8418 } 7722 8419 return null; 7723 }; 7724 } 8420 } 8421 var res = getTextSubField(Item, myfieldname, slot.primary, true); 8422 primary = res.name; 8423 if (publisherCheck(this, Item, primary, myabbrev_family)) { 8424 return null; 8425 } 8426 secondary = false; 8427 tertiary = false; 8428 if (slot.secondary) { 8429 res = getTextSubField(Item, myfieldname, slot.secondary, false, res.usedOrig); 8430 secondary = res.name; 8431 } 8432 if (slot.tertiary) { 8433 res = getTextSubField(Item, myfieldname, slot.tertiary, false, res.usedOrig); 8434 tertiary = res.name; 8435 } 8436 if (myabbrev_family) { 8437 primary = abbreviate(state, Item, alternative_varname, primary, myabbrev_family, true); 8438 secondary = abbreviate(state, Item, false, secondary, myabbrev_family, true); 8439 tertiary = abbreviate(state, Item, false, tertiary, myabbrev_family, true); 8440 } 8441 if ("demote" === this["leading-noise-words"]) { 8442 primary = CSL.demoteNoiseWords(state, primary); 8443 secondary = CSL.demoteNoiseWords(state, secondary); 8444 tertiary = CSL.demoteNoiseWords(state, tertiary); 8445 } 8446 if (secondary || tertiary) { 8447 primary_tok = CSL.Util.cloneToken(this); 8448 primary_tok.strings.suffix = ""; 8449 state.output.append(primary, primary_tok); 8450 group_tok = new CSL.Token(); 8451 group_tok.strings.prefix = " ["; 8452 group_tok.strings.delimiter = ", "; 8453 group_tok.strings.suffix = "]" + this.strings.suffix; 8454 state.output.openLevel(group_tok); 8455 if (secondary) { 8456 state.output.append(secondary); 8457 } 8458 if (tertiary) { 8459 state.output.append(tertiary); 8460 } 8461 state.output.closeLevel(); 8462 } else { 8463 state.output.append(primary, this); 8464 } 8465 return null; 8466 }; 7725 8467 } 7726 8468 this.getOutputFunction = getOutputFunction; 7727 function getStaticOrder (name, refresh) {7728 var static_ordering_val = false;7729 if (!refresh && name["static-ordering"]) {7730 static_ordering_val = true;7731 } else if (!(name.family.replace('"', '', 'g') + name.given).match(CSL.ROMANESQUE_REGEXP)) {7732 static_ordering_val = true;7733 } else if (name.multi && name.multi.main && name.multi.main.slice(0,2) == 'vn') {7734 static_ordering_val = true;7735 } else {7736 if (state.opt['auto-vietnamese-names']7737 && (CSL.VIETNAMESE_NAMES.exec(name.family + " " + name.given)7738 && CSL.VIETNAMESE_SPECIALS.exec(name.family + name.given))) {7739 static_ordering_val = true;7740 }7741 }7742 return static_ordering_val;7743 }7744 function getName (state, name, langTags) {7745 var i, ret, optLangTag, ilen, key, langTag;7746 if (state.tmp.area.slice(-5) === "_sort") {7747 langTags = state.opt["locale-sort"];7748 }7749 if ("string" === typeof langTags) {7750 langTags = [langTags];7751 }7752 if (!name.family) {7753 name.family = "";7754 }7755 if (!name.given) {7756 name.given = "";7757 }7758 var static_ordering_freshcheck = false;7759 var block_initialize = false;7760 var transliterated = false;7761 var static_ordering_val = getStaticOrder(name);7762 if (langTags && name.multi) {7763 for (i = 0, ilen = langTags.length; i < ilen; i += 1) {7764 langTag = langTags[i];7765 if (name.multi._key[langTag]) {7766 name = name.multi._key[langTag];7767 transliterated = true;7768 if (!state.opt['locale-use-original-name-format']) {7769 static_ordering_freshcheck = true;7770 } else {7771 if ((name.family.replace('"','','g') + name.given).match(CSL.ROMANESQUE_REGEXP)) {7772 block_initialize = true;7773 }7774 }7775 break;7776 }7777 }7778 }7779 name = {7780 family:name.family,7781 given:name.given,7782 "non-dropping-particle":name["non-dropping-particle"],7783 "dropping-particle":name["dropping-particle"],7784 suffix:name.suffix,7785 "static-ordering":static_ordering_val,7786 "parse-names":name["parse-names"],7787 "comma-suffix":name["comma-suffix"],7788 "comma-dropping-particle":name["comma-dropping-particle"],7789 transliterated:transliterated,7790 block_initialize:block_initialize,7791 literal:name.literal,7792 isInstitution:name.isInstitution7793 };7794 if (static_ordering_freshcheck &&7795 !getStaticOrder(name, true)) {7796 name["static-ordering"] = false;7797 }7798 if (!name.literal && (!name.given && name.family && name.isInstitution)) {7799 name.literal = name.family;7800 }7801 if (name.literal) {7802 delete name.family;7803 delete name.given;7804 }7805 return name;7806 }7807 this.name = getName;7808 8469 function getHereinafter (Item) { 7809 8470 var hereinafter_author_title = []; … … 7834 8495 } 7835 8496 } 8497 var jurisdiction = "default"; 7836 8498 if (Item.jurisdiction) { 7837 hereinafter_metadata.push("jurisdiction:" + Item.jurisdiction);8499 jurisdiction = Item.jurisdiction; 7838 8500 } 7839 8501 hereinafter_metadata = hereinafter_metadata.join(", "); … … 7842 8504 } 7843 8505 var hereinafter_key = hereinafter_author_title.join(", ") + hereinafter_metadata; 7844 return hereinafter_key;8506 return [jurisdiction, hereinafter_key]; 7845 8507 } 7846 8508 this.getHereinafter = getHereinafter; … … 7851 8513 this.try_cite = true; 7852 8514 this.use_parallels = true; 8515 this.midVars = ["hereinafter", "section", "volume", "container-title", "collection-number", "issue", "page", "page-first", "locator"]; 7853 8516 }; 7854 8517 CSL.Parallel.prototype.isMid = function (variable) { 7855 return ["section", "volume", "container-title", "issue", "page", "page-first", "locator"].indexOf(variable) > -1;8518 return (this.midVars.indexOf(variable) > -1); 7856 8519 }; 7857 8520 CSL.Parallel.prototype.StartCitation = function (sortedItems, out) { … … 7869 8532 this.out = this.state.output.queue; 7870 8533 } 8534 this.master_was_neutral_cite = true; 7871 8535 } 7872 8536 }; … … 7882 8546 } 7883 8547 this.try_cite = true; 7884 len = CSL.PARALLEL_MATCH_VARS.length; 7885 for (pos = 0; pos < len; pos += 1) { 7886 x = CSL.PARALLEL_MATCH_VARS[pos]; 7887 if (!Item[x] || CSL.PARALLEL_TYPES.indexOf(Item.type) === -1) { 7888 this.try_cite = false; 7889 if (this.in_series) { 7890 this.in_series = false; 7891 } 8548 var has_required_var = false; 8549 for (var i = 0, ilen = CSL.PARALLEL_MATCH_VARS.length; i < ilen; i += 1) { 8550 if (Item[CSL.PARALLEL_MATCH_VARS[i]]) { 8551 has_required_var = true; 7892 8552 break; 8553 } 8554 } 8555 if (!has_required_var || CSL.PARALLEL_TYPES.indexOf(Item.type) === -1) { 8556 this.try_cite = true; 8557 if (this.in_series) { 8558 this.in_series = false; 7893 8559 } 7894 8560 } … … 7935 8601 CSL.Parallel.prototype.StartVariable = function (variable) { 7936 8602 if (this.use_parallels && (this.try_cite || this.force_collapse)) { 7937 this.variable = variable; 8603 if (variable === "container-title" && this.sets.value().length === 0) { 8604 this.master_was_neutral_cite = false; 8605 } 7938 8606 this.data = {}; 7939 8607 this.data.value = ""; … … 7942 8610 if (this.target === "front" && is_mid) { 7943 8611 this.target = "mid"; 7944 } else if (this.target === "mid" && !is_mid && this.cite.Item.title ) {8612 } else if (this.target === "mid" && !is_mid && this.cite.Item.title && variable !== "names") { 7945 8613 this.target = "back"; 7946 8614 } else if (this.target === "back" && is_mid) { … … 7948 8616 this.in_series = false; 7949 8617 } 8618 if (variable === "names") { 8619 this.variable = variable + ":" + this.target; 8620 } else { 8621 this.variable = variable; 8622 } 7950 8623 if (variable === "number") { 7951 this.cite.front.push( variable);8624 this.cite.front.push(this.variable); 7952 8625 } else if (CSL.PARALLEL_COLLAPSING_MID_VARSET.indexOf(variable) > -1) { 7953 this.cite.front.push( variable);8626 this.cite.front.push(this.variable); 7954 8627 } else { 7955 this.cite[this.target].push( variable);8628 this.cite[this.target].push(this.variable); 7956 8629 } 7957 8630 } … … 7983 8656 if (this.sets.value().length > 0) { 7984 8657 var prev = this.sets.value()[(this.sets.value().length - 1)]; 8658 if (this.target === "front" && this.variable === "issued") { 8659 if (this.data.value && this.master_was_neutral_cite) { 8660 this.target = "mid"; 8661 } 8662 } 7985 8663 if (this.target === "front") { 7986 if (!(!prev[this.variable] && !this.data.value) && (!prev[this.variable] || this.data.value !== prev[this.variable].value)) { 7987 this.in_series = false; 8664 if ((prev[this.variable] || this.data.value) && (!prev[this.variable] || this.data.value !== prev[this.variable].value)) { 8665 if ("issued" !== this.variable) { 8666 this.in_series = false; 8667 } 7988 8668 } 7989 8669 } else if (this.target === "mid") { … … 8020 8700 use_journal_info = true; 8021 8701 } 8702 if (this.cite.front_collapse["collection-number"] === false) { 8703 use_journal_info = true; 8704 } 8022 8705 if (this.cite.front_collapse.section === false) { 8023 8706 use_journal_info = true; … … 8036 8719 if (container_title_pos > -1) { 8037 8720 this.cite.front = this.cite.front.slice(0,container_title_pos).concat(this.cite.front.slice(container_title_pos + 1)); 8721 } 8722 collection_number_pos = this.cite.front.indexOf("collection-number"); 8723 if (collection_number_pos > -1) { 8724 this.cite.front = this.cite.front.slice(0,collection_number_pos).concat(this.cite.front.slice(collection_number_pos + 1)); 8038 8725 } 8039 8726 } … … 8054 8741 } 8055 8742 } else { 8056 this.cite.back_forceme = this.sets.value().slice(-1)[0].back_forceme; 8743 var idx = this.cite.front.indexOf("issued"); 8744 if (idx === -1 || this.master_was_neutral_cite) { 8745 this.cite.back_forceme = this.sets.value().slice(-1)[0].back_forceme; 8746 } 8747 if (idx > -1) { 8748 var prev = this.sets.value()[this.sets.value().length - 1]; 8749 if (!prev.issued) { 8750 this.cite.front = this.cite.front.slice(0, idx).concat(this.cite.front.slice(idx + 1)); 8751 } 8752 } 8753 if (this.master_was_neutral_cite && this.cite.mid.indexOf("names:mid") > -1) { 8754 this.cite.front.push("names:mid"); 8755 } 8057 8756 } 8058 8757 this.sets.value().push(this.cite); … … 8150 8849 b = cite[varname].blobs[ppos]; 8151 8850 b[0].blobs = b[0].blobs.slice(0, b[1]).concat(b[0].blobs.slice((b[1] + 1))); 8851 this.state.tmp.has_purged_parallel = true; 8852 if (b[0] && b[0].strings && "string" == typeof b[0].strings.oops 8853 && b[0].parent && b[0].parent) { 8854 b[0].parent.parent.strings.delimiter = b[0].strings.oops; 8855 } 8152 8856 } 8153 8857 } … … 8209 8913 this.levelname = levelname; 8210 8914 if (token) { 8211 this.strings = { };8915 this.strings = {"prefix":"","suffix":""}; 8212 8916 for (key in token.strings) { 8213 8917 if (token.strings.hasOwnProperty(key)) { … … 8248 8952 } 8249 8953 }; 8250 CSL.NumericBlob = function (num, mother_token) { 8954 CSL.NumericBlob = function (num, mother_token, id) { 8955 this.id = id; 8251 8956 this.alldecor = []; 8252 8957 this.num = num; … … 8289 8994 }; 8290 8995 CSL.NumericBlob.prototype.checkNext = function (next) { 8291 if (! next || !next.num || this.type !== next.type || next.num !== (this.num + 1)) { 8996 if (next && this.id == next.id) { 8997 this.status = CSL.START; 8998 } else if (! next || !next.num || this.type !== next.type || next.num !== (this.num + 1)) { 8292 8999 if (this.status === CSL.SUCCESSOR_OF_SUCCESSOR) { 8293 9000 this.status = CSL.END; … … 8412 9119 } 8413 9120 namelist = namelist.replace(/\s*\-\s*/g, "-").replace(/\s+/g, " "); 9121 namelist = namelist.replace(/-([a-z])/g, "\u2013$1") 8414 9122 mm = namelist.match(/[\-\s]+/g); 8415 9123 lst = namelist.split(/[\-\s]+/); … … 8443 9151 ret = CSL.Util.Names.doInitialize(state, lst, terminator); 8444 9152 } 9153 ret = ret.replace(/\u2013([a-z])/g, "-$1") 8445 9154 return ret; 8446 9155 }; … … 8451 9160 if (namelist[i].length > 1 && namelist[i].slice(-1) === ".") { 8452 9161 namelist[i] = namelist[i].slice(0, -1); 9162 isAbbrev.push(true); 9163 } else if (namelist[i].length === 1 && namelist[i].toUpperCase() === namelist[i]) { 8453 9164 isAbbrev.push(true); 8454 9165 } else { … … 8790 9501 func = function (state, Item) { 8791 9502 var i, ilen; 8792 var text_esc = CSL.getSafeEscape(state .opt.mode, state.tmp.area);9503 var text_esc = CSL.getSafeEscape(state); 8793 9504 var printing = !state.tmp.suppress_decorations; 8794 9505 if (printing && state.tmp.area === "bibliography") { … … 8905 9616 if ((num / 10) % 10 === 1 || (num > 10 && num < 20)) { 8906 9617 str += this.suffixes[gender][3]; 8907 } else if (num % 10 === 1 ) {9618 } else if (num % 10 === 1 && num % 100 !== 11) { 8908 9619 str += this.suffixes[gender][0]; 8909 } else if (num % 10 === 2 ) {9620 } else if (num % 10 === 2 && num % 100 !== 12) { 8910 9621 str += this.suffixes[gender][1]; 8911 } else if (num % 10 === 3 ) {9622 } else if (num % 10 === 3 && num % 100 !== 13) { 8912 9623 str += this.suffixes[gender][2]; 8913 9624 } else { … … 8965 9676 num = num.slice(1, -1); 8966 9677 } 8967 num = num.replace(/\s*\-\s*/, "\u2013", "g"); 9678 if (num.indexOf("&") > -1 || num.indexOf("--") > -1) { 9679 this.tmp.shadow_numbers[variable].plural = 1; 9680 } 8968 9681 if (this.variable === "page-first") { 8969 9682 m = num.split(/\s*(?:&|,|-)\s*/); … … 8975 9688 } 8976 9689 } 8977 var lst = num.split(/(?:,\s+|\s* [\-\u2013]\s*|\s*&\s*)/);8978 var m = num.match(/(,\s+|\s* [\-\u2013]\s*|\s*&\s*)/g);9690 var lst = num.split(/(?:,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/); 9691 var m = num.match(/(,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/g); 8979 9692 var elements = []; 8980 9693 for (var i = 0, ilen = lst.length - 1; i < ilen; i += 1) { … … 8990 9703 if (elements[i]) { 8991 9704 if (elements[i].match(/[0-9]/)) { 8992 count = count + 1; 9705 if (elements[i - 1] && elements[i - 1].match(/^\s*\\*[\-\u2013]+\s*$/)) { 9706 var middle = this.tmp.shadow_numbers[variable].values.slice(-1); 9707 if (middle[0][1].indexOf("\\") == -1) { 9708 if (elements[i - 2] && ("" + elements[i - 2]).match(/[0-9]+$/) 9709 && elements[i].match(/^[0-9]+/) 9710 && parseInt(elements[i - 2]) < parseInt(elements[i].replace(/[^0-9].*/,""))) { 9711 var start = this.tmp.shadow_numbers[variable].values.slice(-2); 9712 middle[0][1] = "\u2013"; 9713 if (this.opt["page-range-format"] ) { 9714 var newstr = this.fun.page_mangler(start[0][1] +"-"+elements[i]); 9715 newstr = newstr.split(/\u2013/); 9716 elements[i] = newstr[1]; 9717 } 9718 count = count + 1; 9719 } 9720 if (middle[0][1].indexOf("--") > -1) { 9721 middle[0][1] = middle[0][1].replace(/--*/, "\u2013"); 9722 } 9723 } else { 9724 middle[0][1] = middle[0][1].replace(/\\/, "", "g"); 9725 } 9726 } else { 9727 count = count + 1; 9728 } 8993 9729 } 8994 9730 var subelements = elements[i].split(/\s+/); … … 9015 9751 this.tmp.shadow_numbers[variable].values.push(["NumericBlob", elements[i], node]); 9016 9752 } else { 9017 this.tmp.shadow_numbers[variable].values.push(["Blob", elements[i], node]); 9753 var str = elements[i]; 9754 if (this.sys.getAbbreviation) { 9755 var jurisdiction = this.transform.loadAbbreviation(ItemObject.jurisdiction, "number", elements[i]); 9756 if (this.transform.abbrevs[jurisdiction].number[str]) { 9757 str = this.transform.abbrevs[jurisdiction].number[str]; 9758 } 9759 } 9760 this.tmp.shadow_numbers[variable].values.push(["Blob", str, node]); 9018 9761 } 9019 9762 } … … 9028 9771 } else { 9029 9772 this.tmp.shadow_numbers[variable].numeric = numeric; 9030 }9773 } 9031 9774 if (count > 1) { 9032 9775 this.tmp.shadow_numbers[variable].plural = 1; … … 9050 9793 return ret; 9051 9794 }; 9052 listify = function (str ) {9795 listify = function (str, hyphens) { 9053 9796 var m, lst, ret; 9054 9797 str = str.replace("\u2013", "-", "g"); 9055 m = str.match(/([a-zA-Z]*[0-9]+\s*-\s*[a-zA-Z]*[0-9]+)/g); 9056 lst = str.split(/[a-zA-Z]*[0-9]+\s*-\s*[a-zA-Z]*[0-9]+/); 9798 var rexm = new RegExp("([a-zA-Z]*[0-9]+" + hyphens + "[a-zA-Z]*[0-9]+)", "g"); 9799 var rexlst = new RegExp("[a-zA-Z]*[0-9]+" + hyphens + "[a-zA-Z]*[0-9]+"); 9800 m = str.match(rexm); 9801 lst = str.split(rexlst); 9057 9802 if (lst.length === 0) { 9058 9803 ret = m; … … 9060 9805 ret = [lst[0]]; 9061 9806 for (pos = 1, len = lst.length; pos < len; pos += 1) { 9062 ret.push(m[pos - 1] );9807 ret.push(m[pos - 1].replace(/\s*\-\s*/, "-", "g")); 9063 9808 ret.push(lst[pos]); 9064 9809 } … … 9066 9811 return ret; 9067 9812 }; 9068 expand = function (str ) {9813 expand = function (str, hyphens) { 9069 9814 str = "" + str; 9070 lst = listify(str );9815 lst = listify(str, hyphens); 9071 9816 len = lst.length; 9072 9817 for (pos = 1; pos < len; pos += 2) { … … 9143 9888 return stringify(lst); 9144 9889 }; 9890 var sniff = function (str, func, minchars, isyear) { 9891 var ret; 9892 str = "" + str; 9893 var lst; 9894 if (!str.match(/[^\-\u20130-9 ,&]/)) { 9895 lst = expand(str, "-"); 9896 ret = func(lst, minchars, isyear); 9897 } else { 9898 lst = expand(str, "\\s+\\-\\s+"); 9899 ret = func(lst, minchars, isyear); 9900 } 9901 return ret; 9902 } 9145 9903 if (!state.opt["page-range-format"]) { 9146 9904 ret_func = function (str) { … … 9149 9907 } else if (state.opt["page-range-format"] === "expanded") { 9150 9908 ret_func = function (str) { 9151 var lst = expand(str); 9152 return stringify(lst); 9909 return sniff(str, stringify); 9153 9910 }; 9154 9911 } else if (state.opt["page-range-format"] === "minimal") { 9155 9912 ret_func = function (str) { 9156 var lst = expand(str); 9157 return minimize(lst); 9913 return sniff(str, minimize); 9158 9914 }; 9159 9915 } else if (state.opt["page-range-format"] === "minimal-two") { 9160 9916 ret_func = function (str, isyear) { 9161 var lst = expand(str); 9162 return minimize(lst, 2, isyear); 9917 return sniff(str, minimize, 2, isyear); 9163 9918 }; 9164 9919 } else if (state.opt["page-range-format"] === "chicago") { 9165 9920 ret_func = function (str) { 9166 var lst = expand(str); 9167 return chicago(lst); 9921 return sniff(str, chicago); 9168 9922 }; 9169 9923 } … … 9266 10020 }; 9267 10021 CSL.Util.FlipFlopper.prototype.init = function (str, blob) { 9268 this.txt_esc = CSL.getSafeEscape(this.state.opt.mode, this.state.tmp.area); 9269 str = this._normalizeString(str); 10022 this.txt_esc = CSL.getSafeEscape(this.state); 9270 10023 if (!blob) { 9271 10024 this.strs = this.getSplitStrings(str); … … 9279 10032 }; 9280 10033 CSL.Util.FlipFlopper.prototype._normalizeString = function (str) { 9281 for (var i = 0, ilen = 2; i < ilen; i += 1) { 9282 str = str.replace(this.quotechars[i + 2], this.quotechars[0]); 9283 str = str.replace(this.quotechars[i + 4], this.quotechars[1]); 10034 if (str.indexOf(this.quotechars[0]) > -1) { 10035 for (var i = 0, ilen = 2; i < ilen; i += 1) { 10036 if (this.quotechars[i + 2]) { 10037 str = str.replace(this.quotechars[i + 2], this.quotechars[0]); 10038 } 10039 } 10040 } 10041 if (str.indexOf(this.quotechars[1]) > -1) { 10042 for (var i = 0, ilen = 2; i < ilen; i += 1) { 10043 if (this.quotechars[i + 4]) { 10044 str = str.replace(this.quotechars[i + 4], this.quotechars[1]); 10045 } 10046 } 9284 10047 } 9285 10048 return str; … … 9287 10050 CSL.Util.FlipFlopper.prototype.getSplitStrings = function (str) { 9288 10051 var strs, pos, len, newstr, head, tail, expected_closers, expected_openers, expected_flips, tagstack, badTagStack, posA, sameAsOpen, openRev, flipRev, tag, ibeenrunned, posB, wanted_closer, posC, sep, resplice, params, lenA, lenB, lenC, badTagPos, mx, myret; 10052 str = this._normalizeString(str); 9289 10053 mx = str.match(this.allTagsRexMatch); 9290 10054 strs = str.split(this.allTagsRexSplit); … … 9493 10257 }; 9494 10258 CSL.Output.Formatters = {}; 9495 CSL.getSafeEscape = function( outputModeOpt, outputArea) {9496 if (["bibliography", "citation"].indexOf( outputArea) > -1) {9497 return CSL.Output.Formats[ outputModeOpt].text_escape;10259 CSL.getSafeEscape = function(state) { 10260 if (["bibliography", "citation"].indexOf(state.tmp.area) > -1) { 10261 return CSL.Output.Formats[state.opt.mode].text_escape; 9498 10262 } else { 9499 10263 return function (txt) { return txt; }; … … 9544 10308 CSL.Output.Formatters.title = function (state, string) { 9545 10309 var str, words, isAllUpperCase, newString, lastWordIndex, previousWordIndex, upperCaseVariant, lowerCaseVariant, pos, skip, notfirst, notlast, aftercolon, len, idx, tmp, skipword, ppos, mx, lst, myret; 10310 var SKIP_WORDS = state.locale[state.opt.lang].opts["skip-words"]; 9546 10311 str = CSL.Output.Formatters.doppelString(string, CSL.TAG_ESCAPE); 9547 10312 if (!string) { … … 9566 10331 var totallyskip = false; 9567 10332 if (!isAllUpperCase || (words.length === 1 && words[pos].length < 4)) { 9568 if (words[pos] === upperCaseVariant) {10333 if (words[pos] !== lowerCaseVariant) { 9569 10334 totallyskip = true; 9570 10335 } … … 9572 10337 if (isAllUpperCase || words[pos] === lowerCaseVariant) { 9573 10338 skip = false; 9574 for (var i = 0, ilen = CSL.SKIP_WORDS.length; i < ilen; i += 1) {9575 skipword = CSL.SKIP_WORDS[i];10339 for (var i = 0, ilen = SKIP_WORDS.length; i < ilen; i += 1) { 10340 skipword = SKIP_WORDS[i]; 9576 10341 idx = lowerCaseVariant.indexOf(skipword); 9577 10342 if (idx > -1) { … … 9634 10399 return ""; 9635 10400 }; 9636 CSL.demoteNoiseWords = function (fld) { 10401 CSL.demoteNoiseWords = function (state, fld) { 10402 var SKIP_WORDS = state.locale[state.opt.lang].opts["skip-words"]; 9637 10403 if (fld) { 9638 10404 fld = fld.split(/\s+/); … … 9640 10406 var toEnd = []; 9641 10407 for (var j = fld.length - 1; j > -1; j += -1) { 9642 if ( CSL.SKIP_WORDS.indexOf(fld[j].toLowerCase()) > -1) {10408 if (SKIP_WORDS.indexOf(fld[j].toLowerCase()) > -1) { 9643 10409 toEnd.push(fld.pop()); 9644 10410 } else { … … 9852 10618 this.ambigcites = {}; 9853 10619 this.sorter = new CSL.Registry.Comparifier(state, "bibliography_sort"); 9854 this.getSortedIds = function ( generatedItems) {10620 this.getSortedIds = function () { 9855 10621 ret = []; 9856 10622 for (i = 0, ilen = this.reflist.length; i < ilen; i += 1) { … … 9870 10636 var i, ilen; 9871 10637 this.oldseq = {}; 10638 var tmphash = {}; 10639 for (i = myitems.length - 1; i > -1; i += -1) { 10640 if (tmphash[myitems[i]]) { 10641 myitems = myitems.slice(0, i).concat(myitems.slice(i + 1)); 10642 } else { 10643 tmphash[myitems[i]] = true; 10644 } 10645 } 9872 10646 if (uncited_flag && this.mylist && this.mylist.length) { 9873 10647 this.uncited = myitems; … … 9951 10725 } 9952 10726 if (this.state.sys.getAbbreviation) { 9953 for (var field in this.state.transform.abbrevs ) {10727 for (var field in this.state.transform.abbrevs["default"]) { 9954 10728 switch (field) { 9955 10729 case "place": 9956 10730 if (Item["publisher-place"]) { 9957 this.state. sys.getAbbreviation(this.state.transform.abbrevs, field, Item["publisher-place"]);10731 this.state.transform.loadAbbreviation(Item.jurisdiction, "place", Item["publisher-place"]); 9958 10732 } else if (Item["event-place"]) { 9959 this.state. sys.getAbbreviation(this.state.transform.abbrevs, field, Item["event-place"]);10733 this.state.transform.loadAbbreviation(Item.jurisdiction, "place", Item["event-place"]); 9960 10734 } 9961 10735 break; 9962 case "institution ":10736 case "institution-part": 9963 10737 for (var creatorVar in CSL.CREATORS) { 9964 10738 for (var creatorList in Item[creatorVar]) { … … 9970 10744 } 9971 10745 if (subOrganizations) { 9972 subOrganizations = subOrganizations.split(/\s* ,\s*/);10746 subOrganizations = subOrganizations.split(/\s*|\s*/); 9973 10747 for (k = 0, klen = subOrganizations.length; k < klen; k += 1) { 9974 this.state.sys.getAbbreviation(this.state.transform.abbrevs, field, subOrganizations[k]); 10748 this.state.transform.loadAbbreviation(Item.jurisdiction, "institution-part", subOrganizations[k]); 10749 } 9975 10750 } 9976 10751 } … … 9978 10753 } 9979 10754 } 10755 break; 10756 default: 10757 if (Item[field]) { 10758 this.state.transform.loadAbbreviation(Item.jurisdiction, field, Item[field]); 10759 } 10760 break; 9980 10761 } 9981 break; 9982 default: 9983 if (Item[field]) { 9984 this.state.sys.getAbbreviation(this.state.transform.abbrevs, field, Item[field]); 9985 } 9986 break; 9987 } 9988 } 10762 } 9989 10763 } 9990 10764 akey = CSL.getAmbiguousCite.call(this.state, Item); … … 10047 10821 regtoken.ambig = undefined; 10048 10822 Item = this.state.retrieveItem(key); 10823 var akey = regtoken.ambig; 10049 10824 if ("undefined" === typeof akey) { 10050 10825 akey = CSL.getAmbiguousCite.call(this.state, Item); … … 10167 10942 }; 10168 10943 CSL.getSortKeys = function (Item, key_type) { 10169 var area, strip_prepositions, use_parallels, len, pos;10944 var area, extension, strip_prepositions, use_parallels, len, pos; 10170 10945 area = this.tmp.area; 10946 extension = this.tmp.extension; 10171 10947 strip_prepositions = CSL.Util.Sort.strip_prepositions; 10172 10948 this.tmp.area = key_type; 10949 this.tmp.extension = "_sort"; 10173 10950 this.tmp.disambig_override = true; 10174 10951 this.tmp.disambig_request = false; … … 10185 10962 } 10186 10963 this.tmp.area = area; 10964 this.tmp.extension = extension; 10187 10965 return this[key_type].keys; 10188 10966 }; … … 10217 10995 return 2; 10218 10996 } 10219 nameobj = state.transform.name(state, nameobj, state.opt["locale-pri"]); 10997 var res = state.nameOutput.getName(nameobj, "locale-translit", true); 10998 nameobj = res.name; 10220 10999 set_keys(this.state, "" + item_id, nameobj); 10221 11000 param = 2; … … 10234 11013 return param; 10235 11014 } 10236 if (gdropt_orig === "by-cite" && param < request_base) {10237 param =request_base;11015 if (gdropt_orig === "by-cite" && param <= request_base) { 11016 return request_base; 10238 11017 } 10239 11018 if (!dagopt) { … … 10403 11182 }; 10404 11183 addname = function (item_id, nameobj, pos) { 10405 nameobj = state.transform.name(state, nameobj, state.opt["locale-pri"]); 11184 var res = state.nameOutput.getName(nameobj, "locale-translit", true); 11185 nameobj = res.name; 10406 11186 if (state.opt["givenname-disambiguation-rule"] 10407 11187 && state.opt["givenname-disambiguation-rule"].slice(0, 8) === "primary-" … … 10453 11233 this.ambigcites = state.registry.ambigcites; 10454 11234 this.configModes(); 10455 this. clashes = [1, 0];11235 this.debug = false; 10456 11236 }; 10457 11237 CSL.Disambiguation.prototype.run = function(akey) { … … 10468 11248 this.gnameset = 0; 10469 11249 this.gname = 0; 11250 this.clashes = [1, 0]; 10470 11251 while(this.lists[pos][1].length) { 10471 11252 this.listpos = pos; … … 10473 11254 this.base = this.lists[pos][0]; 10474 11255 } 10475 if (this.rerun) {10476 this.rerun = false;10477 } else {10478 this.scanItems(this.lists[pos], 0);10479 }10480 11256 var names_used = []; 10481 11257 ismax = this.incrementDisambig(); 10482 11258 this.scanItems(this.lists[pos], 1); 10483 if (this.clashes[1] < this.clashes[0]) {10484 this.base.better = this.base.names.slice();10485 }10486 11259 this.evalScan(ismax); 10487 11260 } … … 10502 11275 ItemCite = tempResult[3]; 10503 11276 this.partners.push(Item); 10504 this.clashes[phase] = 0;10505 11277 this.nonpartners = []; 11278 var clashes = 0; 10506 11279 for (pos = 1, len = list[1].length; pos < len; pos += 1) { 10507 11280 otherItem = list[1][pos]; … … 10509 11282 var otherItemCite = otherItemData[3]; 10510 11283 if (ItemCite === otherItemCite) { 10511 this.clashes[phase]+= 1;11284 clashes += 1; 10512 11285 this.partners.push(otherItem); 10513 11286 } else { … … 10515 11288 } 10516 11289 } 11290 this.clashes[0] = this.clashes[1]; 11291 this.clashes[1] = clashes; 10517 11292 }; 10518 11293 CSL.Disambiguation.prototype.evalScan = function (ismax) { … … 10528 11303 this.lists[this.listpos] = [this.base, []]; 10529 11304 } else if (this.clashes[1] === 0) { 10530 mybase = CSL.cloneAmbigConfig(this.base);10531 mybase.year_suffix = false;10532 this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, mybase);11305 this.betterbase = CSL.cloneAmbigConfig(this.base); 11306 this.betterbase.year_suffix = false; 11307 this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, this.betterbase); 10533 11308 this.lists[this.listpos] = [this.base, []]; 10534 11309 } else if (this.nonpartners.length === 1) { 10535 mybase = CSL.cloneAmbigConfig(this.base);10536 mybase.year_suffix = false;10537 this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, mybase);11310 this.betterbase = CSL.cloneAmbigConfig(this.base); 11311 this.betterbase.year_suffix = false; 11312 this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, this.betterbase); 10538 11313 this.lists[this.listpos] = [this.base, this.partners]; 10539 11314 } else if (this.clashes[1] < this.clashes[0]) { 11315 this.betterbase = CSL.cloneAmbigConfig(this.base); 10540 11316 this.lists[this.listpos] = [this.base, this.partners]; 10541 if (this.nonpartners.length === 1) { 10542 this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, this.base); 10543 } else { 10544 this.lists.push([this.base, this.nonpartners]); 10545 } 11317 this.lists.push([this.base, this.nonpartners]); 10546 11318 } else { 10547 if (ismax || this.advance_mode) { 10548 if (ismax) { 10549 var better = this.lists[this.listpos][0].better; 10550 if (better) { 10551 this.base.names = better.slice(); 10552 } else { 10553 this.base = new CSL.AmbigConfig(); 10554 } 10555 this.lists[this.listpos] = [this.base, this.nonpartners]; 10556 } 11319 if (ismax) { 11320 if (this.betterbase) { 11321 this.base = CSL.cloneAmbigConfig(this.betterbase); 11322 } 11323 this.lists[this.listpos] = [this.base, this.nonpartners]; 10557 11324 for (pos = 0, len = this.partners.length; pos < len; pos += 1) { 10558 11325 this.state.registry.registerAmbigToken(this.akey, "" + this.partners[pos].id, this.base); 10559 11326 } 10560 } else {10561 this.rerun = true;10562 }10563 }10564 };10565 CSL.Disambiguation.prototype.disGivens = function (ismax) {10566 var pos, len, mybase;10567 if (this.clashes[1] === 0 && this.nonpartners.length === 1) {10568 if (this.clashes[0] === 1) {10569 this.base = this.decrementNames();10570 }10571 mybase = CSL.cloneAmbigConfig(this.base);10572 mybase.year_suffix = false;10573 this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, this.base);10574 this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, mybase);10575 this.lists[this.listpos] = [this.base, []];10576 } else if (this.clashes[1] === 0) {10577 if (this.clashes[0] === 1) {10578 this.base = this.decrementNames();10579 }10580 mybase = CSL.cloneAmbigConfig(this.base);10581 mybase.year_suffix = false;10582 this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, mybase);10583 this.lists[this.listpos] = [this.base, this.nonpartners];10584 } else if (this.nonpartners.length === 1) {10585 if (this.clashes[0] === 1) {10586 this.base = this.decrementNames();10587 }10588 mybase = CSL.cloneAmbigConfig(this.base);10589 mybase.year_suffix = false;10590 this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, mybase);10591 this.lists[this.listpos] = [this.base, this.partners];10592 } else if (this.clashes[1] < this.clashes[0]) {10593 this.lists[this.listpos] = [this.base, this.partners];10594 if (this.nonpartners.length === 1) {10595 this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, this.base);10596 } else {10597 this.lists.push([this.base, this.nonpartners]);10598 }10599 } else {10600 this.base = CSL.cloneAmbigConfig(this.oldbase);10601 if (ismax || this.advance_mode) {10602 if (ismax) {10603 var better = this.lists[this.listpos][0].better;10604 if (better) {10605 this.base.names = better.slice();10606 } else {10607 this.base = new CSL.AmbigConfig();10608 }10609 this.lists[this.listpos] = [this.base, this.nonpartners];10610 }10611 for (pos = 0, len = this.partners.length; pos < len; pos += 1) {10612 this.state.registry.registerAmbigToken(this.akey, "" + this.partners[pos].id, this.base);10613 }10614 } else {10615 this.rerun = true;10616 11327 } 10617 11328 } … … 10619 11330 CSL.Disambiguation.prototype.disExtraText = function () { 10620 11331 var pos, len, mybase; 10621 if (this.clashes[1] === 0) {10622 mybase = CSL.cloneAmbigConfig(this.base);10623 mybase.year_suffix = false;11332 mybase = CSL.cloneAmbigConfig(this.base); 11333 mybase.year_suffix = false; 11334 if (this.clashes[1] === 0 || this.clashes[1] < this.clashes[0]) { 10624 11335 this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, mybase); 10625 if (this.nonpartners.length === 1) {10626 this.state.registry.registerAmbigToken(this.akey, "" + this. nonpartners[0].id, mybase);10627 this.lists[this.listpos] = [this.base,[]];10628 } else{10629 this. lists[this.listpos] = [this.base, this.nonpartners];11336 for (var i=0, ilen=this.partners.length; i < ilen; i += 1) { 11337 this.state.registry.registerAmbigToken(this.akey, "" + this.partners[i].id, mybase); 11338 } 11339 for (var i=0, ilen=this.nonpartners.length; i < ilen; i += 1) { 11340 this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[i].id, mybase); 10630 11341 } 10631 11342 } else { 10632 this.base.disambiguate = false; 10633 this.lists[this.listpos] = [this.base, this.lists[this.listpos][1].slice(1)]; 10634 } 11343 for (var i=0, ilen=this.partners.length; i < ilen; i += 1) { 11344 this.state.registry.registerAmbigToken(this.akey, "" + this.partners[i].id, this.betterbase); 11345 } 11346 } 11347 this.lists[this.listpos] = [this.base, []]; 10635 11348 }; 10636 11349 CSL.Disambiguation.prototype.disYears = function () { 10637 11350 var pos, len, tokens, token, item; 10638 11351 tokens = []; 10639 for (pos = 0, len = this.lists[this.listpos][1].length; pos < len; pos += 1) { 10640 token = this.registry[this.lists[this.listpos][1][pos].id]; 10641 tokens.push(token); 11352 if (this.clashes[1]) { 11353 for (pos = 0, len = this.lists[this.listpos][1].length; pos < len; pos += 1) { 11354 token = this.registry[this.lists[this.listpos][1][pos].id]; 11355 tokens.push(token); 11356 } 10642 11357 } 10643 11358 tokens.sort(this.state.registry.sorter.compareKeys); … … 10659 11374 CSL.Disambiguation.prototype.incrementDisambig = function () { 10660 11375 var val, maxed; 10661 maxed = false; 10662 this.oldbase = CSL.cloneAmbigConfig(this.base); 10663 if (this.advance_mode) { 10664 this.modeindex += 1; 10665 this.advance_mode = false; 10666 } 10667 if (!maxed && "disNames" === this.modes[this.modeindex]) { 10668 if (this.base.names[this.nnameset] < this.maxvals[this.nnameset]) { 10669 this.base.names[this.nnameset] += 1; 11376 var maxed = false; 11377 if ("disNames" === this.modes[this.modeindex]) { 11378 var increment_name = false; 11379 var increment_nameset = false; 11380 if (this.state.opt["disambiguate-add-givenname"] && this.state.opt["givenname-disambiguation-rule"] === "by-cite") { 11381 if (this.base.givens[this.gnameset][this.gname] < 2) { 11382 this.base.givens[this.gnameset][this.gname] += 1; 11383 } else { 11384 this.base.givens[this.gnameset][this.gname] = this.betterbase.givens[this.gnameset][this.gname]; 11385 if (this.gname < this.base.names[this.gnameset]) { 11386 this.gname += 1; 11387 this.base.names[this.gnameset] += 1; 11388 this.base.givens[this.gnameset][this.gname] += 1; 11389 } else { 11390 increment_name = true; 11391 } 11392 } 10670 11393 } else { 10671 if (this.nnameset < (this.base.names.length - 1)) { 10672 this.nnameset += 1; 10673 } 10674 if (this.base.names[this.nnameset] < this.maxvals[this.nnameset]) { 10675 this.base.names[this.nnameset] += 1; 10676 } 10677 } 10678 if (this.nnameset === (this.base.names.length - 1) && this.base.names[this.nnameset] === this.maxvals[this.nnameset]) { 10679 if (this.modeindex === (this.modes.length - 1)) { 10680 return true; 10681 } else { 10682 maxed = false; 10683 } 10684 } 10685 } 10686 if (!maxed && "disGivens" === this.modes[this.modeindex]) { 10687 if (this.gname < this.maxvals[this.gnameset]) { 10688 if (this.base.givens[this.gnameset][this.gname] === this.minval) { 10689 this.base.givens[this.gnameset][this.gname] += 1; 10690 } 10691 this.base.givens[this.gnameset][this.gname] += 1; 10692 this.gname += 1; 10693 } else { 10694 if (this.gnameset < (this.base.givens.length - 1)) { 10695 this.gnameset += 1; 10696 this.gname = 0; 10697 } 10698 if (this.gname < this.maxvals[this.gnameset]) { 10699 this.base.givens[this.gnameset][this.gname] += 1; 10700 this.gname += 1; 10701 } 10702 } 10703 } 10704 if (!maxed && "disExtraText" === this.modes[this.modeindex]) { 10705 maxed = false; 11394 increment_name = true; 11395 } 11396 if (this.state.opt["disambiguate-add-names"]) { 11397 if (increment_name) { 11398 if (this.base.names[this.gnameset] < this.maxvals[this.gnameset]) { 11399 this.gname += 1; 11400 this.base.names[this.gnameset] += 1; 11401 } else { 11402 increment_nameset = true; 11403 } 11404 } 11405 if (increment_nameset) { 11406 if (this.gnameset < this.base.names.length - 1) { 11407 this.gnameset += 1; 11408 this.gname = 0; 11409 if (this.state.opt["disambiguate-add-givenname"] && this.state.opt["givenname-disambiguation-rule"] === "by-cite") { 11410 this.base.givens[this.gnameset][this.gname] += 1; 11411 } else if (this.base.names[this.gnameset] < this.maxvals[this.gnameset]) { 11412 this.gname += 1; 11413 this.base.names[this.gnameset] += 1; 11414 } 11415 } else { 11416 maxed = true; 11417 this.base = CSL.cloneAmbigConfig(this.betterbase); 11418 if (this.modeindex < this.modes.length - 1) { 11419 this.modeindex += 1; 11420 } 11421 } 11422 } 11423 } else if (increment_name) { 11424 maxed = true; 11425 if (this.modeindex < this.modes.length - 1) { 11426 this.modeindex += 1; 11427 } 11428 } 11429 } 11430 if ("disExtraText" === this.modes[this.modeindex]) { 10706 11431 this.base.disambiguate = true; 10707 if (this.modeindex === (this.modes.length - 1)) { 10708 return true; 10709 } else { 10710 maxed = false; 10711 } 10712 } 10713 if (!maxed && "disYears" === this.modes[this.modeindex]) { 10714 maxed = false; 10715 } 10716 if (!maxed && this.modes[this.modeindex] === "disGivens") { 10717 if ((this.gnameset >= (this.base.names.length - 1) && ("undefined" === typeof this.maxvals[this.gnameset] || this.gname === this.maxvals[this.gnameset])) || this.base.names.length === 0) { 10718 if (this.modeindex === (this.modes.length - 1)) { 10719 maxed = true; 10720 } else { 10721 this.advance_mode = true; 10722 } 10723 } 10724 } 10725 if (!maxed && this.modes[this.modeindex] === "disNames") { 10726 if ((this.nnameset >= (this.base.names.length - 1) && ("undefined" === typeof this.maxvals[this.nnameset] ||this.base.names[this.nnameset] === this.maxvals[this.nnameset])) || this.base.names.length === 0) { 10727 if (this.modeindex === (this.modes.length - 1)) { 10728 maxed = true; 10729 } else { 10730 this.advance_mode = true; 10731 } 10732 } 11432 } 11433 if ("disYears" === this.modes[this.modeindex]) { 10733 11434 } 10734 11435 return maxed; … … 10746 11447 this.lists = []; 10747 11448 this.base = false; 11449 this.betterbase = false; 10748 11450 this.akey = akey; 10749 this.advance_mode = false;10750 11451 myItemBundles = []; 10751 11452 this.old_desc = {}; … … 10755 11456 var myItem = this.state.retrieveItem("" + myIds[i]); 10756 11457 var myDesc = this.getItemDesc(myItem); 11458 if (!this.betterbase) { 11459 this.betterbase = CSL.cloneAmbigConfig(myDesc[0]); 11460 this.base = myDesc[0]; 11461 this.maxvals = myDesc[1]; 11462 this.minval = myDesc[2]; 11463 } 10757 11464 myItemBundles.push([myDesc, myItem]); 10758 11465 this.old_desc[myIds[i]] = [this.state.registry.registry[myIds[i]].disambig.year_suffix, this.state.registry.registry[myIds[i]].disambig.disambiguate]; … … 10786 11493 var dagopt, gdropt; 10787 11494 this.modes = []; 10788 if (this.state.opt["disambiguate-add-names"]) {10789 this.modes.push("disNames");10790 }10791 11495 dagopt = this.state.opt["disambiguate-add-givenname"]; 10792 11496 gdropt = this.state.opt["givenname-disambiguation-rule"]; 10793 if ( dagopt && gdropt === "by-cite") {10794 this.modes.push("dis Givens");11497 if (this.state.opt['disambiguate-add-names'] || (dagopt && gdropt === "by-cite")) { 11498 this.modes.push("disNames"); 10795 11499 } 10796 11500 if (this.state.opt.has_disambiguate) { … … 10800 11504 this.modes.push("disYears"); 10801 11505 } 10802 };10803 CSL.Disambiguation.prototype.decrementNames = function () {10804 var base_return, do_me, i, j, pos, len, ppos, llen, ids;10805 base_return = CSL.cloneAmbigConfig(this.base);10806 do_me = false;10807 len = base_return.givens.length - 1;10808 for (pos = len; pos > -1; pos += -1) {10809 llen = base_return.givens[pos].length - 1;10810 for (ppos = llen; ppos > -1; ppos += -1) {10811 if (base_return.givens[pos][ppos] > this.oldbase.givens[pos][ppos]) {10812 do_me = true;10813 }10814 }10815 }10816 if (do_me) {10817 len = base_return.givens.length - 1;10818 for (pos = len; pos > -1; pos += -1) {10819 llen = base_return.givens[pos].length - 1;10820 for (ppos = llen; ppos > -1; ppos += -1) {10821 if (base_return.givens[pos][ppos] > this.oldbase.givens[pos][ppos]) {10822 break;10823 }10824 if (ppos < base_return.names[pos]) {10825 base_return.names[pos] += -1;10826 }10827 }10828 }10829 }10830 return base_return;10831 11506 }; 10832 11507 CSL.Registry.CitationReg = function (state) { -
kcite/trunk/kcite-citeproc/kcite.js
r473946 r506635 57 57 citeproc.setOutputFormat( "kcite" ); 58 58 59 // store all the ids that we are going to use. We register these with 60 // citeproc, which should mean that references which would otherwise 61 // be identical, can be disambiguated ("2011a, 2011b"). 62 var cite_ids = []; 63 59 64 // select all of the kcite citations 60 65 $(this).find(".kcite").each( function(index){ 61 62 var cite = sys.retrieveItem( $(this).attr( "kcite-id" ) ) 63 66 var cite_id = $(this).attr( "kcite-id" ); 67 var cite = sys.retrieveItem( cite_id ); 64 68 // not sure about closure semantics with jquery -- this might not be necessary 65 69 var kcite_element = $(this); 66 70 67 71 if( cite["resolved"] ){ 68 72 cite_ids.push( cite_id ); 73 69 74 // check here whether resolved == true before proceeding. 70 75 var citation_object = { … … 84 89 // TODO the citation object returned may include errors which we 85 90 // haven't checked for here. 86 87 88 91 task_queue.push( 89 92 function(){ 90 var citation_string = citeproc. 91 appendCitationCluster( citation_object )[ 0 ][ 1 ]; 93 var cite_id = kcite_element.attr( "kcite-id" ); 94 var cite = sys.retrieveItem( cite_id ); 95 96 // the true here should mean that citeproc always 97 // returns only a single element array. It doesn't 98 // seem to work, as ambiguous cases still return more. 99 var citation = citeproc. 100 appendCitationCluster( citation_object, true ); 101 // citeproc's wierd return values. Last element is citation we want. 102 // last element again is the HTML. 103 var citation_string = citation.pop().pop(); 92 104 93 105 var citation = "<a href=\"#" + 94 kcite_element.attr( "kcite-id" ) + "\">" + 95 citation_string + "</a>"; 96 106 cite_id + "\">" + 107 citation_string + "</a>" 108 + "<a href=\"" + cite["URL"] + "\">*</a>"; 109 97 110 kcite_element.html( citation ); 98 111 }); … … 122 135 123 136 137 124 138 } 125 139 }); 126 140 127 141 // update citeproc with all the ids we will use (which will happen 142 // when we tail recurse). 143 citeproc.updateItems( cite_ids ); 144 128 145 var kcite_bib_element = $(this); 129 146 … … 133 150 $.each( citeproc.makeBibliography()[ 1 ], 134 151 function(index,item){ 135 bib_string = bib_string + item 152 // URL linkify here 153 // this is not well done as it will be style dependant. 154 var http = item.lastIndexOf("http"); 155 var url = item.substring 156 ( http,item.lastIndexOf(".") ); 157 158 var bib_item = 159 item.substring( 0, http ) + 160 "<a href=\"" + url + "\">" 161 + url + "</a>."; 162 bib_string = bib_string + bib_item; 136 163 }); 137 164 … … 170 197 171 198 // tail-end recurse with timeout 172 setTimeout( iter, 2);199 setTimeout( iter, 0.5 ); 173 200 }; 174 201 -
kcite/trunk/kcite.php
r497290 r506635 37 37 static $bibliography; 38 38 39 // debug option -- ignore transients which disables the cache40 static $ignore_transients = false;41 39 // delete any transients as we are going, which deletes the cache 42 40 static $clear_transients = false; … … 67 65 68 66 //provide links to the bibliography in various formats 69 add_action('template_redirect', array(__CLASS__, 'bibliography_output')); 67 //add_action('template_redirect', array(__CLASS__, 'bibliography_output')); 68 70 69 //add settings menu link to sidebar 71 70 add_action('admin_menu', array(__CLASS__, 'refman_menu')); … … 77 76 array( __CLASS__, 'add_script' ) ); 78 77 78 79 add_option( "kcite-cache", true ); 79 80 } 80 81 … … 169 170 } 170 171 else{ 171 $in_text = "$source:$content"; 172 // this needs replacing with a URL 173 $stub = array 174 ( 175 "doi" => "http://dx.doi.org", 176 "pubmed" => "http://www.ncbi.nlm.nih.gov/pubmed", 177 "arxiv" => "http://arxiv.org/abs" 178 ); 179 180 $url = "$stub[$source]/$content"; 181 $in_text = "<a href=\"$url\">$url</a>"; 172 182 $anchor = self::$bibliography->add_cite( $cite ); 173 183 return "<span class=\"kcite\" kcite-id=\"ITEM-$anchor\">($in_text)</span>\n"; … … 193 203 194 204 // // get the metadata which we are going to use for the bibliography. 195 $cites = self:: get_arrays($cites);205 $cites = self::resolve_metadata($cites); 196 206 197 207 if( !get_option( "citeproc" ) ){ … … 373 383 * This can be used to build the JSON. 374 384 */ 375 private function get_arrays($cites) {385 private function resolve_metadata($cites) { 376 386 377 387 $start_time = time(); … … 390 400 391 401 if ($cite->source == 'doi') { 392 $cite = self::crossref_doi_lookup($cite); 402 // should work on datacite or crossref lookup 403 $cite = self::dx_doi_lookup($cite); 404 393 405 //failover to pubmed 394 406 if (!$cite->resolved) { 395 407 $cite = self::pubmed_doi_lookup($cite); 396 397 if (!$cite->resolved) { 398 $cite->error = true; 399 continue; 400 } 401 402 $cite = self::array_from_xml($cite); 408 } 409 410 if($cite->resolved && $cite->resolved_from=="crossref" ){ 411 $cite = self::get_crossref_metadata($cite); 412 continue; 413 } 414 415 if($cite->resolved && $cite->resolved_from=="datacite" ){ 416 $cite = self::parse_xml($cite); 417 $cite = self::get_datacite_metadata($cite); 418 continue; 419 } 420 421 if( $cite->resolved && $cite->resolved_from="pubmed" ){ 422 $cite = self::parse_xml($cite); 403 423 $cite = self::get_pubmed_metadata($cite); 404 424 continue; 405 425 } 406 426 407 $cite = self::array_from_xml($cite);408 $cite = self::get_crossref_metadata($cite);427 // doi we can't find. 428 $cite->error = true; 409 429 continue; 410 430 } … … 413 433 $cite = self::pubmed_id_lookup($cite); 414 434 415 if (!$cite->resolved) {435 if (!$cite->resolved) { 416 436 $cite->error = true; 417 437 continue; … … 419 439 420 440 421 $cite = self:: array_from_xml($cite);441 $cite = self::parse_xml($cite); 422 442 $cite = self::get_pubmed_metadata($cite); 423 443 continue; 424 444 } 425 426 // if we don't recognise the type if will remain unresolved. 427 // This is okay and will be dealt with later 428 } 429 445 446 if( $cite->source == "arxiv"){ 447 $cite = self::arxiv_id_lookup($cite); 448 if( !$cite->resolved){ 449 $cite->error = true; 450 continue; 451 } 452 $cite = self::parse_xml($cite); 453 $cite = self::get_arxiv_metadata($cite); 454 continue; 455 } 456 457 458 // if we don't recognise the type then we have an error 459 $cite->error = true; 460 } 430 461 431 462 return $cites; … … 436 467 * Attempt to resolve metadata for a citation object 437 468 * @param string $pub_doi A doi representing a reference 438 * @return 439 */ 440 private function crossref_doi_lookup($cite) { 441 //use CrossRef ID provided on the options page 442 $crossref = get_option('crossref_id'); 443 if (!$crossref) { 444 //automatically failover to pubmed without trying to connect to crossref 445 return $cite; 446 } 447 448 $trans_slug = "crossref-doi" . $cite->identifier; 449 450 // debug code -- blitz transients in the database 451 if( self::$clear_transients ){ 452 delete_transient( $trans_slug ); 453 } 454 455 // check for transients 456 if (false === (!self::$ignore_transients && $xml = get_transient( $trans_slug ))) { 457 458 // print( "crossref lookup:$trans_slug: " . date( "H:i:s", time() ) ."\n" ); 459 $url = "http://www.crossref.org/openurl/?noredirect=true&pid=" 460 .$crossref."&format=unixref&id=doi:".$cite->identifier; 461 $xml = file_get_contents($url, 0); 462 463 if (preg_match('/not found in CrossRef/', $xml)) { 464 //null will cause failover to PubMed (if no metadata in crossref) 465 return $cite; 466 } 467 468 469 if (preg_match('/login you supplied is not recognized/', $xml)) { 470 //null will cause failover to PubMed (if no valid login supplied) 471 return $cite; 472 } 473 474 // transient for 1 week -- need to option this. 475 set_transient( $trans_slug, $xml, 60*60*24*7 ); 476 } 477 478 479 480 $cite->resolved = true; 481 $cite->resolution_source=$xml; 482 $cite->resolved_from="crossref"; 469 * @return 470 */ 471 private function dx_doi_lookup($cite) { 472 473 // slug includes JSON so we ignore XML in the database from previous 474 // incarnations of kcite. 475 $crossref_trans_slug = "crossref-doi-json" . $cite->identifier; 476 $datacite_trans_slug = "datacite-doi-xml" . $cite->identifier; 477 478 // debug code -- blitz transients in the database 479 if( self::$clear_transients ){ 480 delete_transient( $crossref_trans_slug ); 481 delete_transient( $datacite_trans_slug ); 482 } 483 484 if(get_option("kcite-cache") && $json = get_transient($crossref_trans_slug)){ 485 $cite->resolved = true; 486 $cite->resolution_source=$json; 487 $cite->resolved_from="crossref"; 488 return $cite; 489 } 490 491 if(get_option("kcite-cache") && $xml = get_transient($datacite_trans_slug)){ 492 $cite->resolved = true; 493 $cite->resolution_source=$xml; 494 $cite->resolved_from="datacite"; 495 return $cite; 496 } 497 498 499 $url = "http://dx.doi.org/{$cite->identifier}"; 500 501 // get the metadata with negotiation 502 $ch = curl_init(); 503 curl_setopt ($ch, CURLOPT_URL, $url ); 504 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true ); 505 curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true ); 506 // the order here is important, as both datacite and crossrefs content negotiation is broken. 507 // crossref only return the highest match, but do check other content 508 // types. So, should return json. Datacite is broken, so only return the first 509 // content type, which should be XML. 510 curl_setopt ($ch, CURLOPT_HTTPHEADER, 511 array ( 512 "Accept: application/x-datacite+xml;q=0.9, application/citeproc+json;q=1.0" 513 )); 514 515 // debug 516 //$fh = fopen('/tmp/curl.log', 'w'); 517 //curl_setopt($ch, CURLOPT_STDERR, $fh ); 518 //curl_setopt($ch, CURLOPT_VERBOSE, true ); 519 520 $response = curl_exec ($ch); 521 $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); 522 $contenttype = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); 523 524 // it's probably not a DOI at all. Need to check some more here. 525 if( curl_errno( $ch ) == 404 ){ 526 curl_close($ch); 527 return $cite; 528 } 529 530 curl_close ($ch); 531 532 533 if( $contenttype == "application/citeproc+json" ){ 534 // crossref DOI 535 $cite->resolved = true; 536 $cite->resolution_source=$response; 537 $cite->resolved_from="crossref"; 538 539 // set the transient with a slug so we can distinguish from datacite 540 set_transient( $crossref_trans_slug, $response, 60*60*24*7 ); 541 542 return $cite; 543 } 544 545 if( $contenttype == "application/x-datacite+xml" ){ 546 //datacite DOI 547 $cite->resolved = true; 548 $cite->resolution_source=$response; 549 $cite->resolved_from="datacite"; 550 551 // set the transient with a slug so we can distinguish from crossref 552 set_transient( $datacite_trans_slug, $response, 60*60*24*7 ); 553 return $cite; 554 } 483 555 484 556 return $cite; … … 500 572 } 501 573 502 if (false === (!self::$ignore_transients && $id = get_transient( $trans_slug ))) { 574 if (false === (get_option( "cache" ) 575 && $id = get_transient( $trans_slug ))) { 503 576 504 577 // print( "pubmed_doi lookup:$trans_slug " . date( "H:i:s", time() ) . "\n" ); … … 511 584 512 585 if (preg_match('/PhraseNotFound/', $search_xml)) { 513 //handles DOI lookup failures514 $cite->error = true;515 586 return $cite; 516 587 } … … 548 619 } 549 620 550 if (false === ( !self::$ignore_transients&& $xml = get_transient( $trans_slug ))) {621 if (false === (get_option( "kcite-cache") && $xml = get_transient( $trans_slug ))) { 551 622 552 623 // print( "pubmed_id lookup: $trans_slug" . date( "H:i:s", time() ) . "\n" ); … … 562 633 set_transient( $trans_slug, $xml, 60*60*24*7 ); 563 634 } 564 635 565 636 $cite->resolved = true; 566 637 $cite->resolution_source = $xml; … … 569 640 } 570 641 642 643 private function arxiv_id_lookup($cite){ 644 $trans_slug = "arxiv-id" . $cite->identifier; 645 646 if( self::$clear_transients ){ 647 delete_transient( $trans_slug ); 648 } 649 if( false === (get_option( "kcite-cache") 650 && $xml = get_transient( $trans_slug ))) { 651 652 $fetch = "http://export.arxiv.org/oai2?verb=GetRecord&identifier=oai:arXiv.org:" . $cite->identifier . "&metadataPrefix=arXiv"; 653 654 $xml = file_get_contents( $fetch, 0 ); 655 // TODO failure handling here 656 set_transient( $trans_slug, $xml, 60*60*24*7 ); 657 } 658 659 $cite->resolved = true; 660 $cite->resolution_source = $xml; 661 $cite->resolved_from = "arxiv"; 662 663 return $cite; 664 } 665 571 666 /** 572 667 * Parses XML in a citation object into a PhP array … … 574 669 * @return Citation with parsedXML now containing SimpleXMLElement object 575 670 */ 576 private function array_from_xml($cite) {671 private function parse_xml($cite) { 577 672 $cite->parsedXML = new SimpleXMLElement( $cite->resolution_source ); 578 673 return $cite; … … 581 676 /** 582 677 * Badly named method, restful API showing just the JSON object for the reference list. 583 * Not fully functional at the moment; works if there are no rewrite rules.678 * This is not functional at the moment. 584 679 * 585 680 */ 586 function bibliography_output() {587 global $post;588 $uri = self::get_requested_uri();589 if ($uri[0] == 'json') {590 //render the json here591 $this_post = get_post($post->ID, ARRAY_A);592 $post_content = $this_post['post_content'];593 $dois = self::get_cites($post_content);594 $metadata = array();595 $metadata = self::get_arrays($dois[1]);596 $json = self::metadata_to_json($metadata);597 echo $json;598 exit;599 }600 elseif ($uri[0] == 'bib') {601 //render bibtex here602 exit;603 }604 elseif ($uri[0] == 'ris') {605 //render ris here606 exit; //prevents rest of page rendering607 }608 }681 // function bibliography_output() { 682 // global $post; 683 // $uri = self::get_requested_uri(); 684 // if ($uri[0] == 'json') { 685 // //render the json here 686 // $this_post = get_post($post->ID, ARRAY_A); 687 // $post_content = $this_post['post_content']; 688 // $dois = self::get_cites($post_content); 689 // $metadata = array(); 690 // $metadata = self::get_arrays($dois[1]); 691 // $json = self::metadata_to_json($metadata); 692 // echo $json; 693 // exit; 694 // } 695 // elseif ($uri[0] == 'bib') { 696 // //render bibtex here 697 // exit; 698 // } 699 // elseif ($uri[0] == 'ris') { 700 // //render ris here 701 // exit; //prevents rest of page rendering 702 // } 703 // } 609 704 610 705 … … 622 717 foreach ($cites as $cite) { 623 718 $item_string = "ITEM-".$item_number++; 719 720 if( $cite->json ){ 721 722 $item = $cite->json; 723 724 // add a few bits of additional metadata 725 $item["source"] = $cite->source; 726 $item["identifier"] = $cite->identifier; 727 $item["resolved"] = $cite->resolved; 728 $item["id"] = "$item_string"; 729 730 731 // we finished! 732 $citep[ $item_string ] = $item; 733 continue; 734 } 735 624 736 625 737 $item = array(); … … 628 740 $item["identifier"] = $cite->identifier; 629 741 $item["resolved"] = $cite->resolved; 630 742 631 743 // timed out overall, so don't have the metadata 632 744 if( $cite->timeout ){ … … 643 755 } 644 756 645 757 646 758 // just didn't resolve 647 759 if( !$cite->resolved ){ … … 667 779 } 668 780 $item[ "author" ] = $authors; 669 781 670 782 $item[ "container-title" ] = $cite->journal_title; 671 783 … … 676 788 $date_parts[] = (int)$cite->pub_date[ 'year' ]; 677 789 // month and day if existing or nothing 678 if( ((int)$cite->pub_date[ 'month' ]) > 0 ){ 790 791 if(array_key_exists( "month", $cite->pub_date)){ 679 792 $date_parts[] = (int)$cite->pub_date[ 'month' ]; 680 if( ((int)$cite->pub_date[ 'day' ]) > 0 ){681 $date_parts[] = (int)$cite->pub_date[ 'day' ];682 }793 } 794 if(array_key_exists( "day", $cite->pub_date)){ 795 $date_parts[] = (int)$cite->pub_date[ 'day' ]; 683 796 } 684 797 … … 686 799 $item[ "issued" ] = $issued; 687 800 } 688 801 689 802 if($cite->first_page){ 690 803 $item[ "page" ] = … … 695 808 $item[ "volume" ] = $cite->volume; 696 809 } 697 810 698 811 if( $cite->issue ){ 699 812 $item[ "issue" ] = $cite->issue; … … 706 819 $item[ "type" ] = "article-journal"; 707 820 821 if( $cite->url ){ 822 $item["URL"] = $cite->url; 823 } 824 708 825 709 826 $citep[ $item_string ] = $item; 710 827 711 828 } 712 829 … … 735 852 */ 736 853 private function get_crossref_metadata($cite) { 737 738 // dump the XML 739 //print( "<br> Resolved Data from crossref for:$cite->identifier<br>$cite->resolution_source<br>" ); 740 741 // shorted the method a little! 742 $article = $cite->parsedXML; 743 744 $journal = $article->children()->children()->children(); 745 746 foreach ($journal->children() as $child) { 747 if ($child->getName() == 'journal_metadata') { 748 $cite->journal_title = (string)$child->full_title; 749 $cite->abbrv_title = (string)$child->abbrev_title; 750 continue; 751 } 752 753 if ($child->getName() == 'journal_issue') { 754 $cite->issue = (string)$child->issue; 755 foreach ($child->children() as $issue_info) { 756 if ($issue_info->getName() == 'publication_date') { 757 758 759 $cite->pub_date['month'] = (string)$issue_info->month; 760 $cite->pub_date['day'] = (string)$issue_info->day; 761 $cite->pub_date['year'] = (string)$issue_info->year; 762 continue; 763 } 764 765 if ($issue_info->getName() == 'journal_volume') { 766 $cite->volume = (string)$issue_info->volume; 767 continue; 768 } 769 } 770 continue; 771 } 772 773 774 775 if ($child->getName() == 'journal_article') { 776 foreach ($child->children() as $details) { 777 if ($details->getName() == 'titles') { 778 $cite->title = (string)$details->children(); 779 continue; 780 } 781 782 if ($details->getName() == 'contributors') { 783 // pick out just the authors (not editors or what not) 784 $people = $details->xpath( '//person_name[@contributor_role="author"]' ); 785 foreach ($people as $person) { 786 787 $author = array(); 788 $author['given_name'] = (string)$person->given_name; 789 $author['surname'] = (string)$person->surname; 790 $cite->authors[] = $author; 791 } 792 continue; 793 } 794 795 796 if ($details->getName() == 'pages') { 797 $cite->first_page = (string)$details->first_page; 798 $cite->last_page = (string)$details->last_page; 799 continue; 800 } 801 802 if ($details->getName() == 'doi_data') { 803 $cite->reported_doi = (string)$details->doi; 804 $cite->resource = (string)$details->resource; 805 continue; 806 } 807 } 808 continue; 809 } 810 } 811 812 // Fix section -- need to mark these up as problematic in JSON 813 814 // crossref articles don't always have titles if they are old 815 if( ! $cite->title ){ 816 $cite->title = ""; 817 } 818 819 return $cite; 820 } 854 855 $json_decoded = json_decode( $cite->resolution_source, true ); 856 857 // crossref returns both url and raw DOI. We don't need the later, so delete it. 858 unset( $json_decoded[ "DOI" ] ); 859 $cite->json = $json_decoded; 860 861 862 return $cite; 863 } 864 865 private function get_datacite_metadata($cite){ 866 867 $article = $cite->parsedXML; 868 $namespaceN = $article->getNamespaces(); 869 870 // nasty name space hack 871 // datacite returns more than one form, but with different name spaces 872 // which breaks the xpath, even they are the same for my purposes. 873 $kn = ""; 874 if( $namespaceN[ "" ] == "http://datacite.org/schema/kernel-2.2" ){ 875 $kn = "kn:"; 876 $article->registerXpathNamespace( "kn", "http://datacite.org/schema/kernel-2.2" ); 877 } 878 879 if( $namespaceN[ "" ] == null ){ 880 // kernel 2.0 -- no namespace 881 // so do nothing. 882 } 883 884 $journalN = $article->xpath( "//${kn}publisher"); 885 // we get lots of newlines without trim 886 $cite->journal_title = trim( (string)$journalN[ 0 ] ); 887 888 // datacite can give multiple titles, it appear 889 $titleN = $article->xpath( "//${kn}title" ); 890 $cite->title = trim( (string)$titleN[ 0 ] ); 891 892 $authorN = $article->xpath( "//${kn}creators/${kn}creator/${kn}creatorName" ); 893 894 foreach( $authorN as $author ){ 895 // this is not the most high tech name parsing ever. 896 897 // names usualy come as Smith, J 898 list( $last, $first ) = 899 explode( ",", trim((string)$author) ); 900 901 // but sometimes are consortia names 902 if( $last == null ){ 903 $last = $author; 904 $first = ""; 905 } 906 907 $newauthor = array(); 908 $newauthor['surname'] = $last; 909 $newauthor['given_name'] = $first; 910 911 $cite->authors[] = $newauthor; 912 } 913 914 $yearN = $article->xpath( "//${kn}publicationYear" ); 915 $cite->pub_date[ 'year' ] = (string)$yearN[ 0 ]; 916 917 $cite->url = "http://dx.doi.org/" . $cite->identifier; 918 } 821 919 822 920 /** … … 834 932 835 933 $issueN = $article->xpath( "//Article/Journal/JournalIssue/Issue" ); 836 $cite->issue = (string)$issueN[ 0 ]; 934 if( count( $issueN ) > 0 ){ 935 $cite->issue = (string)$issueN[ 0 ]; 936 } 837 937 838 938 $journal_titleN = $article->xpath( "//Journal/Title" ); 839 $cite->journal_title = (string)$journal_titleN[ 0 ]; 939 if( count( $journal_titleN ) > 0 ){ 940 $cite->journal_title = (string)$journal_titleN[ 0 ]; 941 } 840 942 841 943 $volN = $article->xpath( "//Journal/Volume" ); 842 $cite->volume = (string)$volN[ 0 ]; 944 if( count( $volN ) > 0 ){ 945 $cite->volume = (string)$volN[ 0 ]; 946 } 843 947 844 948 $abbrN = $article->xpath( "//Journal/ISOAbbreviation" ); 845 $cite->abbrv_title = (string)$abbrN[ 0 ]; 949 if( count( $abbrN ) > 0 ){ 950 $cite->abbrv_title = (string)$abbrN[ 0 ]; 951 } 846 952 847 953 $artN = $article->xpath( "//ArticleTitle" ); 848 $cite->title = (string)$artN[ 0 ]; 954 if( count( $artN ) > 0 ){ 955 $cite->title = (string)$artN[ 0 ]; 956 } 849 957 850 958 $authN = $article->xpath( "//AuthorList/Author" ); … … 856 964 $cite->authors[] = $newauthor; 857 965 } 858 966 859 967 $artDN = $article->xpath( "//ArticleDate" ); 860 968 … … 865 973 } 866 974 867 $cite->pub_date[ 'month' ] = (string)$artDN[ 0 ]->Month;868 $cite->pub_date[ 'day' ] = (string)$artDN[ 0 ]->Day;869 $cite->pub_date[ 'year' ] = (string)$artDN[ 0 ]->Year;870 871 872 975 if( count( $artDN ) > 0 ){ 976 $cite->pub_date[ 'month' ] = (string)$artDN[ 0 ]->Month; 977 $cite->pub_date[ 'day' ] = (string)$artDN[ 0 ]->Day; 978 $cite->pub_date[ 'year' ] = (string)$artDN[ 0 ]->Year; 979 } 980 873 981 $elocN = $article->xpath( "//ELocationID" ); 874 $cite->reported_doi = (string)$elocN[ 0 ]; 875 982 if( count( $elocN ) > 0 ){ 983 $cite->reported_doi = (string)$elocN[ 0 ]; 984 } 985 986 $cite->url = "http://www.ncbi.nlm.nih.gov/pubmed/{$cite->identifier}"; 876 987 877 988 return $cite; 878 989 } 879 990 991 992 private function get_arxiv_metadata($cite){ 993 994 $article = $cite->parsedXML; 995 $article->registerXpathNamespace( "ar", "http://arxiv.org/OAI/arXiv/" ); 996 $article->registerXpathNamespace( "oai", "http://www.openarchives.org/OAI/2.0/" ); 997 $cite->journal_title = "arXiv"; 998 999 $titleN = $article->xpath( "//ar:title" ); 1000 $cite->title = (string)$titleN[ 0 ]; 1001 1002 $dateN = $article->xpath( "//ar:created" ); 1003 $rawdate = (string)$dateN[ 0 ]; 1004 1005 $cite->pub_date['month'] = substr( $rawdate, 5, 2 ); 1006 $cite->pub_date['day'] = substr( $rawdate, 8, 2 ); 1007 $cite->pub_date['year'] = substr( $rawdate, 0, 4 ); 1008 1009 $authorN = $article->xpath( "//ar:author" ); 1010 1011 foreach( $authorN as $author ){ 1012 $newauthor = array(); 1013 $newauthor['surname'] = (string)$author->keyname; 1014 $newauthor['given_name'] = (string)$author->forenames; 1015 $cite->authors[] = $newauthor; 1016 } 1017 1018 $cite->url = "http://arxiv.org/abs/" . $cite->identifier; 1019 1020 return $cite; 1021 } 1022 1023 880 1024 /** 881 1025 * Fetches the URI that the user requested to work out output format. … … 948 1092 } 949 1093 1094 if ($_POST['kcite-cache']){ 1095 if( $_POST['kcite-cache'] == "True"){ 1096 update_option( 'kcite-cache', true ); 1097 } 1098 else{ 1099 update_option( 'kcite-cache', false ); 1100 } 1101 } 1102 950 1103 if( $_POST['timeout']){ 951 1104 update_option( 'timeout', $_POST['timeout'] ); … … 980 1133 <th scope="row">Reference timeout<br/><font size='-2'>For how long should kcite attempt to gather bibliographic data before timing out</font></th> 981 1134 <td><input type='text' name="timeout" value='<?php echo get_option('timeout', 5) ?>'></td> 1135 1136 <tr> 1137 <th scope="row">Cache References<br/><font size='-2'>Should kcite cache reference metadata. Set to false for debugging</font></th> 1138 <td><select name='kcite-cache'> 1139 <option value='True' <?php if (get_option('kcite-cache')) echo 'selected="true"'; ?>>True</option> 1140 <option value='False' <?php if (!get_option('kcite-cache')) echo 'selected="true"'; ?>>False</option> 1141 </select> 1142 </td> 982 1143 </table> 983 1144 <p class="submit"> … … 1056 1217 public $resource; 1057 1218 public $issue; 1058 1219 public $url; 1059 1220 1060 1221 function equals($citation){ -
kcite/trunk/readme.txt
r497290 r506635 11 11 == Description == 12 12 13 Interprets the [cite] shortcode to produce citations from the appropriate sources, also produces a formatted bibliography at the foot of the post, with appropriate links to articles. 13 Interprets the [cite] shortcode to produce citations from the 14 appropriate sources, also produces a formatted bibliography at the foot of the 15 post, with appropriate links to articles. 14 16 15 The plugin uses the [CrossRef API](http://www.crossref.org/help/CrossRef_Help.htm) to retrieve metadata for Digital Object Identifiers (DOIs) and [NCBI eUtils](http://eutils.ncbi.nlm.nih.gov/) to retrieve metadata for PubMed Identifiers (PMIDs). 17 This plugin now uses multiple resources to retrieve metadata about the 18 references in question, including CrossRef, DataCite, arXiv and PubMed. 19 16 20 17 21 **Syntax** … … 21 25 PMID example - [cite source='pubmed']17237047[/cite] 22 26 23 Whichever 'source' is identified as the default (see Installation), will work without the source attribute being set in the shortcode. so: 27 Whichever 'source' is identified as the default (see Installation), will work 28 without the source attribute being set in the shortcode. so: 24 29 25 30 [cite]10.1021/jf904082b[/cite] … … 27 32 Will be interpreted correctly as long as DOI is set as the default metadata 28 33 source. 34 35 Kcite now supports DOIs from both [CrossRef](http://www.crossref.org) and 36 [DataCite](http://www.datacite.org). Identifiers from 37 [PubMed](http://www.pubmed.org) or [arXiv](http://www.arxiv.org) are directly 38 supported. 29 39 30 40 From Kcite 1.4, Citeproc-js … … 34 44 the reader to choose. 35 45 36 Kcite is developed at http://code.google.com/p/knowledgeblog/ in Mercurial. 37 46 Kcite is developed at http://code.google.com/p/knowledgeblog/ in Mercurial. To 47 contact the authors, please email knowledgeblog@googlegroups.com. 38 48 39 49 == Installation == 40 50 51 1. Kcite now requires the use of libcurl. 41 52 1. Unzip the downloaded .zip archive to the `/wp-content/plugins/` directory 42 53 1. Activate the plugin through the 'Plugins' menu in WordPress … … 44 55 45 56 == Changelog == 57 58 = 1.5 = 59 60 1. Kcite now requires the PHP libcurl support. You may need to install 61 additional packages on your web server. 62 1. From kcite 1.5, we have expanded the range of identifiers. 63 DataCite DOIs and arXiv IDs are now supported. 64 1. Crossref DOIs are now accessed via content negotiation. This should be less 65 buggy, and reduce server load as it removes a parsing/data integration 66 step. 67 1. DataCite DOIs come via content negotiation also, although still require XML 68 parsing. 69 1. Bug fix to in kcite.js should fix an occasional rendering bug. 70 1. Both bibliography and intext citation are now linked. The underlying HTML 71 is also linked, which should aid machine interpretability. 46 72 47 73 = 1.4.4 = … … 71 97 1. Fixed another regression caused by 1.2 fix. This should fix the error when 72 98 there is no bibliography. 99 73 100 = 1.2 = 74 101 1. Sadly 1.1 had a regression error in it, which mean it didn't
Note: See TracChangeset
for help on using the changeset viewer.