diff --git a/lib/citeproc-js/fixtures/local/citeprocjs_SubsequentSliceTwoNamesInstitution.txt b/lib/citeproc-js/fixtures/local/citeprocjs_SubsequentSliceTwoNamesInstitution.txt
index ee14588..62952f0 100644
--- a/lib/citeproc-js/fixtures/local/citeprocjs_SubsequentSliceTwoNamesInstitution.txt
+++ b/lib/citeproc-js/fixtures/local/citeprocjs_SubsequentSliceTwoNamesInstitution.txt
@@ -2,7 +2,11 @@
bibliography
<<===== MODE =====<<
-
+>>===== OPTIONS =====>>
+{
+ "etal_min_etal_usefirst_hack": true
+}
+<<===== OPTIONS =====<<
>>===== RESULT =====>>
diff --git a/lib/citeproc-js/fixtures/local/disambiguate_PreferSingleName.txt b/lib/citeproc-js/fixtures/local/disambiguate_PreferSingleName.txt
new file mode 100644
index 0000000..e7f483b
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/disambiguate_PreferSingleName.txt
@@ -0,0 +1,74 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+>>===== RESULT =====>>
+Kurtz Camembert et al. / Kurt Camembert et al.
+<<===== RESULT =====<<
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "1",
+ "type": "book",
+ "author": [
+ {
+ "family": "Camembert",
+ "given": "Kurtz"
+ },
+ {
+ "family": "Rossi",
+ "given": "Amadeus"
+ },
+ {
+ "family": "Ignoble",
+ "given": "Ignatius"
+ }
+ ]
+ },
+ {
+ "id": "2",
+ "type": "book",
+ "author": [
+ {
+ "family": "Camembert",
+ "given": "Kurt"
+ },
+ {
+ "family": "Rossi",
+ "given": "Amadeus"
+ },
+ {
+ "family": "Idiosyncratic",
+ "given": "Ignatius"
+ }
+ ]
+ }
+]
+<<===== INPUT =====<<
+
+>>===== CSL =====>>
+
+
+
+<<===== CSL =====<<
+
diff --git a/lib/citeproc-js/fixtures/local/disambiguate_WithConsolidation.txt b/lib/citeproc-js/fixtures/local/disambiguate_WithConsolidation.txt
new file mode 100644
index 0000000..9364043
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/disambiguate_WithConsolidation.txt
@@ -0,0 +1,128 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+
+
+>>===== RESULT =====>>
+>>[0] SchUG idF BGBl I 80/2020; SchUG idF BGBl I 117/2008.
+>>[1] SchUG idF BGBl I 80/2020; SchUG idF BGBl I 117/2008.
+<<===== RESULT =====<<
+
+
+>>===== CITATIONS =====>>
+[
+ [
+ {
+ "citationID": "CITATION-1",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ },
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ "properties": {
+ "noteIndex": 1
+ }
+ },
+ [],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-2",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ },
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ "properties": {
+ "noteIndex": 2
+ }
+ },
+ [
+ [
+ "CITATION-1",
+ 1
+ ]
+ ],
+ []
+ ]
+]
+<<===== CITATIONS =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "ITEM-1",
+ "type": "legislation",
+ "title": "Schulunterrichtsgesetz",
+ "references": "BGBl I 80/2020",
+ "shortTitle": "SchUG",
+ "jurisdiction": "at"
+ },
+ {
+ "id": "ITEM-2",
+ "type": "legislation",
+ "title": "Schulunterrichtsgesetz",
+ "references": "BGBl I 117/2008",
+ "shortTitle": "SchUG",
+ "jurisdiction": "at"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsAlwaysUseFirst.txt b/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsAlwaysUseFirst.txt
index bb31b55..50770b6 100644
--- a/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsAlwaysUseFirst.txt
+++ b/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsAlwaysUseFirst.txt
@@ -39,6 +39,7 @@ Noakes with Roe, Tiny Subcommittee, Big Ministry and Doe et al., Trivial Working
diff --git a/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsInTextImplicitChop.txt b/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsInTextImplicitChop.txt
index adf67d8..d865340 100644
--- a/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsInTextImplicitChop.txt
+++ b/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsInTextImplicitChop.txt
@@ -45,6 +45,7 @@ Noakes with Roe, Tiny Subcommittee, Big Ministry and Doe et al., Trivial Working
diff --git a/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsMaybeUseFirst.txt b/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsMaybeUseFirst.txt
index 8f47306..f9721e0 100644
--- a/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsMaybeUseFirst.txt
+++ b/lib/citeproc-js/fixtures/local/institutions_AffiliationSpoofingMixedPeopleAndOrganizationsMaybeUseFirst.txt
@@ -40,7 +40,7 @@ Doe et al., Big Ministry
institution-parts="long"
delimiter=", "
substitute-use-first="1"
- use-last="1"/>
+ use-first="1"/>
diff --git a/lib/citeproc-js/fixtures/local/institutions_FirstAndLast.txt b/lib/citeproc-js/fixtures/local/institutions_FirstAndLast.txt
index cb614b6..4ce0763 100644
--- a/lib/citeproc-js/fixtures/local/institutions_FirstAndLast.txt
+++ b/lib/citeproc-js/fixtures/local/institutions_FirstAndLast.txt
@@ -31,6 +31,7 @@ Tiny Subcommittee, Big Ministry
diff --git a/lib/citeproc-js/fixtures/local/institutions_FirstOnly.txt b/lib/citeproc-js/fixtures/local/institutions_FirstOnly.txt
index 61c036e..5cb3e42 100644
--- a/lib/citeproc-js/fixtures/local/institutions_FirstOnly.txt
+++ b/lib/citeproc-js/fixtures/local/institutions_FirstOnly.txt
@@ -31,7 +31,7 @@ Tiny Subcommittee
+ use-last="1"/>
diff --git a/lib/citeproc-js/fixtures/local/institutions_FirstOnlyOnShort.txt b/lib/citeproc-js/fixtures/local/institutions_FirstOnlyOnShort.txt
index 661b047..9b38bfd 100644
--- a/lib/citeproc-js/fixtures/local/institutions_FirstOnlyOnShort.txt
+++ b/lib/citeproc-js/fixtures/local/institutions_FirstOnlyOnShort.txt
@@ -5,7 +5,7 @@ citation
>>===== RESULT =====>>
-Some Court
+Some Court, or other
<<===== RESULT =====<<
>>===== ABBREVIATIONS =====>>
@@ -38,7 +38,7 @@ Some Court
-
+
@@ -51,10 +51,13 @@ Some Court
{
"author": [
{
- "literal": "somecourt"
+ "literal": "somecourt|or other"
}
],
- "type": "book"
+ "type": "book",
+ "issued": {
+ "date-parts": [[2000]]
+ }
}
]
<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/institutions_MixedPeopleAndOrganizationsAlwaysUseFirst.txt b/lib/citeproc-js/fixtures/local/institutions_MixedPeopleAndOrganizationsAlwaysUseFirst.txt
index d40edb6..20cfa36 100644
--- a/lib/citeproc-js/fixtures/local/institutions_MixedPeopleAndOrganizationsAlwaysUseFirst.txt
+++ b/lib/citeproc-js/fixtures/local/institutions_MixedPeopleAndOrganizationsAlwaysUseFirst.txt
@@ -35,6 +35,7 @@ Roe, Tiny Subcommittee of Big Ministry, et al. eds.
delimiter=", "
part-separator=" of "
use-first="1"
+ reverse-order="true"
use-last="1">
diff --git a/lib/citeproc-js/fixtures/local/institutions_MixedPeopleAndOrganizationsMaybeUseFirst.txt b/lib/citeproc-js/fixtures/local/institutions_MixedPeopleAndOrganizationsMaybeUseFirst.txt
index b20a87c..791b42c 100644
--- a/lib/citeproc-js/fixtures/local/institutions_MixedPeopleAndOrganizationsMaybeUseFirst.txt
+++ b/lib/citeproc-js/fixtures/local/institutions_MixedPeopleAndOrganizationsMaybeUseFirst.txt
@@ -42,8 +42,8 @@ substitute-use-first always includes the requested institution name parts.
delimiter=", "
delimiter-precedes-last="never"
part-separator=" of "
- substitute-use-first="1"
- use-last="1"/>
+ reverse-order="true"
+ use-first="1" use-last="1"/>
diff --git a/lib/citeproc-js/fixtures/local/juris_EarlyOSCOLA.txt b/lib/citeproc-js/fixtures/local/juris_EarlyOSCOLA.txt
index 93ccde0..2c9f01c 100644
--- a/lib/citeproc-js/fixtures/local/juris_EarlyOSCOLA.txt
+++ b/lib/citeproc-js/fixtures/local/juris_EarlyOSCOLA.txt
@@ -1481,7 +1481,7 @@ citation
-
+
diff --git a/lib/citeproc-js/fixtures/local/locale_AbbrevLangAndJurisModule.txt b/lib/citeproc-js/fixtures/local/locale_AbbrevLangAndJurisModule.txt
new file mode 100644
index 0000000..a516f1a
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/locale_AbbrevLangAndJurisModule.txt
@@ -0,0 +1,304 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+
+>>===== ABBREVIATIONS =====>>
+{
+ "default": {},
+ "us:c9": {
+ "institution-part": {
+ "court.appeals": "9th Cir."
+ }
+ }
+}
+<<===== ABBREVIATIONS =====<<
+
+>>===== RESULT =====>>
+>>[0] Smith v. Jones, 200 F. 100, 103 (9th Cir. 2000)
+>>[1] Id. at 110
+<<===== RESULT =====<<
+
+
+>>===== CITATIONS =====>>
+[
+ [
+ {
+ "citationID": "CITATION-1",
+ "citationItems": [
+ {
+ "id": "ITEM-1",
+ "locator": "103",
+ "label": "page"
+ }
+ ],
+ "properties": {
+ "noteIndex": 1
+ }
+ },
+ [],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-2",
+ "citationItems": [
+ {
+ "id": "ITEM-1",
+ "locator": "110",
+ "label": "page"
+ }
+ ],
+ "properties": {
+ "noteIndex": 2
+ }
+ },
+ [["CITATION-1",1]],
+ []
+ ]
+]
+<<===== CITATIONS =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "ITEM-1",
+ "type": "legal_case",
+ "title": "Smith v. Jones",
+ "title-short": "Smith",
+ "authority": "court.appeals",
+ "container-title": "F.",
+ "collection-number": "200",
+ "page": "100",
+ "jurisdiction": "us:c9",
+ "issued": {
+ "date-parts": [
+ [2000, 10, 1]
+ ]
+ }
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/locale_LoadTwoJurisPrefs.txt b/lib/citeproc-js/fixtures/local/locale_LoadTwoJurisPrefs.txt
new file mode 100644
index 0000000..09d516a
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/locale_LoadTwoJurisPrefs.txt
@@ -0,0 +1,54 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+The processor should load jurisdiction-preference for two locales
+for reference. This test does not (yet) actually exercise the
+preferences.
+
+>>===== RESULT =====>>
+BOGUS
+<<===== RESULT =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "ITEM-1",
+ "type": "book",
+ "title": "Title One",
+ "language": "fr"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/locale_SelectAbbrevs.txt b/lib/citeproc-js/fixtures/local/locale_SelectAbbrevs.txt
new file mode 100644
index 0000000..5659b89
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/locale_SelectAbbrevs.txt
@@ -0,0 +1,73 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+>>===== RESULT =====>>
+SCC
+CSC
+<<===== RESULT =====<<
+
+>>===== CITATION-ITEMS =====>>
+[
+ [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ [
+ {
+ "id": "ITEM-2"
+ }
+ ]
+]
+<<===== CITATION-ITEMS =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "ITEM-1",
+ "type": "legal_case",
+ "authority": "supreme.court",
+ "jurisdiction": "ca"
+ },
+ {
+ "id": "ITEM-2",
+ "type": "legal_case",
+ "authority": "supreme.court",
+ "jurisdiction": "ca",
+ "language": "fr"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/locale_abbrevEntireToPartFallback.txt b/lib/citeproc-js/fixtures/local/locale_abbrevEntireToPartFallback.txt
new file mode 100644
index 0000000..9f947b2
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/locale_abbrevEntireToPartFallback.txt
@@ -0,0 +1,767 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+>>===== RESULT =====>>
+HR 22 Juni 1995.
+<<===== RESULT =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "type": "legal_case",
+ "id": "ITEM-1",
+ "multi": {
+ "main": {},
+ "_keys": {}
+ },
+ "authority": "hoge",
+ "container-title": "Reporter Name",
+ "page": "567",
+ "title": "Netherlands Case",
+ "jurisdiction": "nl",
+ "issued": {
+ "date-parts": [
+ [
+ 1995,
+ 6,
+ 22
+ ]
+ ]
+ }
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/locator_PassThroughEnDash.txt b/lib/citeproc-js/fixtures/local/locator_PassThroughEnDash.txt
new file mode 100644
index 0000000..e542d25
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/locator_PassThroughEnDash.txt
@@ -0,0 +1,51 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+
+
+>>===== RESULT =====>>
+zu B. I. 3.–4., Rn. 21–22 der Gründe
+<<===== RESULT =====<<
+
+>>===== CITATION-ITEMS =====>>
+[
+ [
+ {
+ "id": "ITEM-1",
+ "locator": "zu B. I. 3.–4., Rn. 21–22 der Gründe"
+ }
+ ]
+]
+<<===== CITATION-ITEMS =====<<
+
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "ITEM-1",
+ "type": "book",
+ "archive": "Pickwick Papers"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/multilingual_DisableItalic.txt b/lib/citeproc-js/fixtures/local/multilingual_DisableItalic.txt
index b4ba99f..ff71aec 100644
--- a/lib/citeproc-js/fixtures/local/multilingual_DisableItalic.txt
+++ b/lib/citeproc-js/fixtures/local/multilingual_DisableItalic.txt
@@ -168,7 +168,7 @@ bibliography
-
+
diff --git a/lib/citeproc-js/fixtures/local/name_AffiliationSpoofingImplicitInstitution.txt b/lib/citeproc-js/fixtures/local/name_AffiliationSpoofingImplicitInstitution.txt
index df0177e..6a4633c 100644
--- a/lib/citeproc-js/fixtures/local/name_AffiliationSpoofingImplicitInstitution.txt
+++ b/lib/citeproc-js/fixtures/local/name_AffiliationSpoofingImplicitInstitution.txt
@@ -38,6 +38,7 @@ bibliography
+
@@ -51,21 +52,18 @@ bibliography
"author": [
{
"family": "Doe",
- "given": "John",
- "static-ordering": false
+ "given": "John"
},
{
"family": "Roe",
- "given": "Jane",
- "static-ordering": false
+ "given": "Jane"
},
{
"literal": "Multi-National United|Department of Alien Weapons Vivisection"
},
{
"family": "Noakes",
- "given": "John",
- "static-ordering": false
+ "given": "John"
}
],
"id": "ITEM-1",
diff --git a/lib/citeproc-js/fixtures/local/name_ImplicitInstitution.txt b/lib/citeproc-js/fixtures/local/name_ImplicitInstitution.txt
index 0ac7ee4..1e3803e 100644
--- a/lib/citeproc-js/fixtures/local/name_ImplicitInstitution.txt
+++ b/lib/citeproc-js/fixtures/local/name_ImplicitInstitution.txt
@@ -32,6 +32,7 @@ bibliography
+
@@ -45,21 +46,18 @@ bibliography
"author": [
{
"family": "Doe",
- "given": "John",
- "static-ordering": false
+ "given": "John"
},
{
"family": "Roe",
- "given": "Jane",
- "static-ordering": false
+ "given": "Jane"
},
{
"literal": "Multi-National United|Department of Alien Weapons Vivisection"
},
{
"family": "Noakes",
- "given": "John",
- "static-ordering": false
+ "given": "John"
}
],
"id": "ITEM-1",
diff --git a/lib/citeproc-js/fixtures/local/name_ItalicDelimiter.txt b/lib/citeproc-js/fixtures/local/name_ItalicDelimiter.txt
new file mode 100644
index 0000000..1bd0ca1
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/name_ItalicDelimiter.txt
@@ -0,0 +1,68 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+
+
+>>===== RESULT =====>>
+Smith/Brown/Jones (eds.)
+<<===== RESULT =====<<
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "ITEM-1",
+ "type": "book",
+ "editor": [
+ {
+ "family": "Smith",
+ "given": "Fred"
+ },
+ {
+ "family": "Brown",
+ "given": "George"
+ },
+ {
+ "family": "Jones",
+ "given": "Ted"
+ }
+ ]
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/number_CollapseWithEnDash.txt b/lib/citeproc-js/fixtures/local/number_CollapseWithEnDash.txt
new file mode 100644
index 0000000..e464e77
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/number_CollapseWithEnDash.txt
@@ -0,0 +1,44 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+
+
+>>===== RESULT =====>>
+437–72
+<<===== RESULT =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "page": "437–472",
+ "id": "ITEM-1"
+ }
+]
+<<===== INPUT =====<<
+
diff --git a/lib/citeproc-js/fixtures/local/number_DocketNumberHyphenOK.txt b/lib/citeproc-js/fixtures/local/number_DocketNumberHyphenOK.txt
new file mode 100644
index 0000000..52531e2
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/number_DocketNumberHyphenOK.txt
@@ -0,0 +1,100 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+
+
+>>===== RESULT =====>>
+Case type: 2:19-cv-00222
+Other type: 2:19-cv–00222
+<<===== RESULT =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+>>===== CITATION-ITEMS =====>>
+[
+ [
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ [
+ {
+ "id": "ITEM-1"
+ }
+ ]
+]
+<<===== CITATION-ITEMS =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "ITEM-1",
+ "type": "book",
+ "number": "2:19-cv-00222"
+ },
+ {
+ "id": "ITEM-2",
+ "type": "legal_case",
+ "multi": {
+ "main": {},
+ "_keys": {}
+ },
+ "authority": "district.court",
+ "note": "event-date: Jul 31, 2019",
+ "number": "2:19-cv-00222",
+ "title": "Smith v. State of Maine",
+ "URL": "https://www.courtlistener.com/docket/15675964/smith-v-state-of-maine/#entry-26",
+ "document-name": "Ord. Affirming Recommended Dec. of Magis. J.",
+ "document-number": "26",
+ "jurisdiction": "us:c1:me.d",
+ "accessed": {
+ "date-parts": [
+ [
+ "2020",
+ 12,
+ 31
+ ]
+ ]
+ },
+ "submitted": {
+ "date-parts": [
+ [
+ "2019",
+ 5,
+ 15
+ ]
+ ]
+ }
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/number_RomanUpperCase.txt b/lib/citeproc-js/fixtures/local/number_RomanUpperCase.txt
new file mode 100644
index 0000000..e4139d1
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/number_RomanUpperCase.txt
@@ -0,0 +1,54 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+
+
+>>===== RESULT =====>>
+IV.
+<<===== RESULT =====<<
+
+>>===== CITATION-ITEMS =====>>
+[
+ [
+ {
+ "id": "ITEM-1",
+ "locator": "iv"
+ }
+ ]
+]
+<<===== CITATION-ITEMS =====<<
+
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "ITEM-1",
+ "type": "book",
+ "title": "My Title"
+ }
+]
+<<===== INPUT =====<<
+
diff --git a/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote1.txt b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote1.txt
new file mode 100644
index 0000000..731b12f
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote1.txt
@@ -0,0 +1,100 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+>>===== DESCRIPTION =====>>
+Tests subsequent cite form constrained by near-note-distance
+inside the same note.
+<<===== DESCRIPTION =====<<
+
+
+>>===== RESULT =====>>
+>>[0] First-and-Last title (FULL); Second title (FULL); First-and-Last title, supra
+<<===== RESULT =====<<
+
+
+>>===== CITATIONS =====>>
+[
+ [
+ {
+ "citationID": "CITATION-1",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ },
+ {
+ "id": "ITEM-2"
+ },
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 1
+ }
+ },
+ [],
+ []
+ ]
+]
+<<===== CITATIONS =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "title": "First-and-Last title",
+ "edition": "2",
+ "id": "ITEM-1",
+ "type": "book"
+ },
+ {
+ "title": "Second title",
+ "edition": "3",
+ "id": "ITEM-2",
+ "type": "book"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote2.txt b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote2.txt
new file mode 100644
index 0000000..9ec3f14
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote2.txt
@@ -0,0 +1,123 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+>>===== DESCRIPTION =====>>
+Tests subsequent cite form within near-note-distance where first reference is in-text, and subsequent is in a note.
+The subsequent reference will render in full form because the in-text and note backref contexts are evaluated independently.
+<<===== DESCRIPTION =====<<
+
+>>===== RESULT =====>>
+..[0] First-and-Last title (FULL)
+..[1] Second title (FULL)
+>>[2] First-and-Last title (FULL)
+<<===== RESULT =====<<
+
+
+>>===== CITATIONS =====>>
+[
+ [
+ {
+ "citationID": "CITATION-1",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 0
+ }
+ },
+ [],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-2",
+ "citationItems": [
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ "properties": {
+ "noteIndex": 1
+ }
+ },
+ [["CITATION-1", 0]],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-3",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 2
+ }
+ },
+ [["CITATION-1", 0],["CITATION-2", 1]],
+ []
+ ]
+]
+<<===== CITATIONS =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "title": "First-and-Last title",
+ "id": "ITEM-1",
+ "type": "book"
+ },
+ {
+ "title": "Second title",
+ "id": "ITEM-2",
+ "type": "book"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote3.txt b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote3.txt
new file mode 100644
index 0000000..d6bba70
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote3.txt
@@ -0,0 +1,123 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+>>===== DESCRIPTION =====>>
+Tests subsequent cite form within near-note-distance where first reference is in a note and subsequent is in-text.
+The subsequent reference should render in full form, because the in-text and note backref contexts are evaluated independently.
+<<===== DESCRIPTION =====<<
+
+>>===== RESULT =====>>
+..[0] First-and-Last title (FULL)
+..[1] Second title (FULL)
+>>[2] First-and-Last title (FULL)
+<<===== RESULT =====<<
+
+
+>>===== CITATIONS =====>>
+[
+ [
+ {
+ "citationID": "CITATION-1",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 1
+ }
+ },
+ [],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-2",
+ "citationItems": [
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ "properties": {
+ "noteIndex": 0
+ }
+ },
+ [["CITATION-1", 1]],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-3",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 0
+ }
+ },
+ [["CITATION-1", 1],["CITATION-2", 0]],
+ []
+ ]
+]
+<<===== CITATIONS =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "title": "First-and-Last title",
+ "id": "ITEM-1",
+ "type": "book"
+ },
+ {
+ "title": "Second title",
+ "id": "ITEM-2",
+ "type": "book"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote4.txt b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote4.txt
new file mode 100644
index 0000000..7316af2
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote4.txt
@@ -0,0 +1,124 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+>>===== DESCRIPTION =====>>
+Tests subsequent cite form within near-note-distance where first reference and the subsequent reference are in separate notes.
+The subsequent reference should be in the near-note form, with a pointer to the note.
+<<===== DESCRIPTION =====<<
+
+
+>>===== RESULT =====>>
+..[0] First-and-Last title (FULL)
+..[1] Second title (FULL)
+>>[2] First-and-Last title, supra note 1
+<<===== RESULT =====<<
+
+
+>>===== CITATIONS =====>>
+[
+ [
+ {
+ "citationID": "CITATION-1",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 1
+ }
+ },
+ [],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-2",
+ "citationItems": [
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ "properties": {
+ "noteIndex": 2
+ }
+ },
+ [["CITATION-1", 1]],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-3",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 3
+ }
+ },
+ [["CITATION-1", 1],["CITATION-2", 2]],
+ []
+ ]
+]
+<<===== CITATIONS =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "title": "First-and-Last title",
+ "id": "ITEM-1",
+ "type": "book"
+ },
+ {
+ "title": "Second title",
+ "id": "ITEM-2",
+ "type": "book"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote5.txt b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote5.txt
new file mode 100644
index 0000000..2eddf35
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote5.txt
@@ -0,0 +1,139 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+>>===== DESCRIPTION =====>>
+Tests subsequent cite form within near-note-distance where first reference and the subsequent reference are in separate notes, separated by note-distance.
+The subsequent reference should be in full form.
+<<===== DESCRIPTION =====<<
+
+>>===== RESULT =====>>
+..[0] First-and-Last title (FULL)
+..[1] Second title (FULL)
+..[2] Second title, supra note 2
+>>[3] First-and-Last title (FULL)
+<<===== RESULT =====<<
+
+
+>>===== CITATIONS =====>>
+[
+ [
+ {
+ "citationID": "CITATION-1",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 1
+ }
+ },
+ [],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-2",
+ "citationItems": [
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ "properties": {
+ "noteIndex": 2
+ }
+ },
+ [["CITATION-1", 1]],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-3",
+ "citationItems": [
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ "properties": {
+ "noteIndex": 3
+ }
+ },
+ [["CITATION-1", 1],["CITATION-2", 2]],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-5",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 4
+ }
+ },
+ [["CITATION-1", 1],["CITATION-2", 2],["CITATION-3", 3]],
+ []
+ ]
+]
+<<===== CITATIONS =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "title": "First-and-Last title",
+ "id": "ITEM-1",
+ "type": "book"
+ },
+ {
+ "title": "Second title",
+ "id": "ITEM-2",
+ "type": "book"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote6.txt b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote6.txt
new file mode 100644
index 0000000..cb461e6
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/position_SubsequentInTextWithNote6.txt
@@ -0,0 +1,142 @@
+>>===== MODE =====>>
+citation
+<<===== MODE =====<<
+
+>>===== DESCRIPTION =====>>
+Tests subsequent cite form within near-note-distance where first reference and the subsequent reference are in separate notes, separated by note-distance (if counting in-text citations as notes).
+The near-note-distance constraint should be ignored, and the subsequent reference should be rendered in near-note short form, without a note pointer.
+<<===== DESCRIPTION =====<<
+
+>>===== RESULT =====>>
+..[0] First-and-Last title (FULL)
+..[1] Second title (FULL)
+..[2] ibid.
+>>[3] First-and-Last title, supra
+<<===== RESULT =====<<
+
+
+>>===== CITATIONS =====>>
+[
+ [
+ {
+ "citationID": "CITATION-1",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 0
+ }
+ },
+ [],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-2",
+ "citationItems": [
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ "properties": {
+ "noteIndex": 0
+ }
+ },
+ [["CITATION-1", 0]],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-3",
+ "citationItems": [
+ {
+ "id": "ITEM-2"
+ }
+ ],
+ "properties": {
+ "noteIndex": 0
+ }
+ },
+ [["CITATION-1", 0],["CITATION-2", 0]],
+ []
+ ],
+ [
+ {
+ "citationID": "CITATION-5",
+ "citationItems": [
+ {
+ "id": "ITEM-1"
+ }
+ ],
+ "properties": {
+ "noteIndex": 0
+ }
+ },
+ [["CITATION-1", 0],["CITATION-2", 0],["CITATION-3", 0]],
+ []
+ ]
+]
+<<===== CITATIONS =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "title": "First-and-Last title",
+ "id": "ITEM-1",
+ "type": "book"
+ },
+ {
+ "title": "Second title",
+ "id": "ITEM-2",
+ "type": "book"
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/sort_WithMacro.txt b/lib/citeproc-js/fixtures/local/sort_WithMacro.txt
new file mode 100644
index 0000000..95837db
--- /dev/null
+++ b/lib/citeproc-js/fixtures/local/sort_WithMacro.txt
@@ -0,0 +1,547 @@
+>>===== MODE =====>>
+bibliography
+<<===== MODE =====<<
+
+
+
+>>===== RESULT =====>>
+
+
Smith, Brad: Zenza .
+
Smith, Brad: Zenza (Woody Guthrie) [1950].
+
Smith, Brad: Zenza (Frank Zappa) [1950].
+
+<<===== RESULT =====<<
+
+
+>>===== CSL =====>>
+
+<<===== CSL =====<<
+
+
+>>===== INPUT =====>>
+[
+ {
+ "id": "ITEM-1",
+ "type": "song",
+ "composer": [
+ {
+ "family": "Smith",
+ "given": "Brad"
+ }
+ ],
+ "author": [
+ {
+ "family": "Zappa",
+ "given": "Frank"
+ }
+ ],
+ "title": "Zenza",
+ "original-date": { "date-parts": [[1950]]}
+ },
+ {
+ "id": "ITEM-2",
+ "type": "song",
+ "composer": [
+ {
+ "family": "Smith",
+ "given": "Brad"
+ }
+ ],
+ "title": "Zenza"
+ },
+ {
+ "id": "ITEM-3",
+ "type": "song",
+ "composer": [
+ {
+ "family": "Smith",
+ "given": "Brad"
+ }
+ ],
+ "author": [
+ {
+ "family": "Guthrie",
+ "given": "Woody"
+ }
+ ],
+ "title": "Zenza",
+ "original-date": { "date-parts": [[1950]]}
+ }
+]
+<<===== INPUT =====<<
diff --git a/lib/citeproc-js/fixtures/local/test_cms.txt b/lib/citeproc-js/fixtures/local/test_cms.txt
index 2678822..a5efabd 100644
--- a/lib/citeproc-js/fixtures/local/test_cms.txt
+++ b/lib/citeproc-js/fixtures/local/test_cms.txt
@@ -317,7 +317,7 @@ citation
-
+
diff --git a/lib/citeproc-js/package-lock.json b/lib/citeproc-js/package-lock.json
index a8c8386..bb0adb8 100644
--- a/lib/citeproc-js/package-lock.json
+++ b/lib/citeproc-js/package-lock.json
@@ -1,5 +1,13 @@
{
"name": "citeproc",
- "version": "2.2.11",
- "lockfileVersion": 1
+ "version": "2.4.49",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@citeproc-rs/wasm": {
+ "version": "0.0.0-canary-88f356a",
+ "resolved": "https://registry.npmjs.org/@citeproc-rs/wasm/-/wasm-0.0.0-canary-88f356a.tgz",
+ "integrity": "sha512-Gf+uiM9AIWrYdaZYfTWcVZJYoqnbjRzVOxF4fdnlf99JZ4zdcNPt8FdecMFAkpLKFASDIp+BS7EETpLPePmDOw=="
+ }
+ }
}
diff --git a/lib/citeproc-js/package.json b/lib/citeproc-js/package.json
index 8ee4d26..bb93b54 100644
--- a/lib/citeproc-js/package.json
+++ b/lib/citeproc-js/package.json
@@ -1,7 +1,7 @@
{
"name": "citeproc",
- "version": "2.4.39",
- "description": "The citeproc-js citation formatting module, in CommonJS format. This version is based on citeproc-js 1.4.39",
+ "version": "2.4.61",
+ "description": "The citeproc-js citation formatting module, in CommonJS format. This version is based on citeproc-js 1.4.61",
"main": "citeproc_commonjs.js",
"repository": {
"type": "git",
diff --git a/lib/citeproc-js/src/api_cite.js b/lib/citeproc-js/src/api_cite.js
index 5551984..f83c6f5 100644
--- a/lib/citeproc-js/src/api_cite.js
+++ b/lib/citeproc-js/src/api_cite.js
@@ -132,7 +132,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
}
Item = this.retrieveItem("" + item.id);
if (Item.id) {
- this.transform.loadAbbreviation("default", "hereinafter", Item.id);
+ this.transform.loadAbbreviation("default", "hereinafter", Item.id, Item.language);
}
item = CSL.parseLocator.call(this, item);
if (this.opt.development_extensions.consolidate_legal_items) {
@@ -351,17 +351,17 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
var citations;
if (this.opt.update_mode === CSL.POSITION) {
for (var i = 0; i < 2; i += 1) {
- citations = [textCitations, noteCitations][i];
var first_ref = {};
var last_ref = {};
var first_container_ref = {};
+ citations = [textCitations, noteCitations][i];
for (j = 0, jlen = citations.length; j < jlen; j += 1) {
var onecitation = citations[j];
if (!citations[j].properties.noteIndex) {
citations[j].properties.noteIndex = 0;
}
citations[j].properties.noteIndex = parseInt(citations[j].properties.noteIndex, 10);
- if (j > 0 && citations[j - 1].properties.noteIndex > citations[j].properties.noteIndex) {
+ if (j > 0 && onecitation.properties.noteIndex && citations[j - 1].properties.noteIndex > onecitation.properties.noteIndex) {
citationsInNote = {};
first_ref = {};
last_ref = {};
@@ -632,11 +632,10 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
}
if (suprame) {
item[1].position = CSL.POSITION_CONTAINER_SUBSEQUENT;
- if (first_ref[first_id]) {
- item[1].position = CSL.POSITION_SUBSEQUENT;
- }
- if (!first_ref[first_id]) {
+ if ("undefined" === typeof first_ref[first_id]) {
first_ref[first_id] = onecitation.properties.noteIndex;
+ } else {
+ item[1].position = CSL.POSITION_SUBSEQUENT;
}
}
if (suprame || ibidme) {
@@ -671,6 +670,8 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
item[1]["near-note"] = true;
}
last_ref[last_id] = onecitation.properties.noteIndex;
+ } else if (item[1].position !== CSL.POSITION_FIRST) {
+ item[1]["near-note"] = true;
}
if (onecitation.citationID != citation.citationID) {
for (n = 0, nlen = CSL.POSITION_TEST_VARS.length; n < nlen; n += 1) {
@@ -1112,7 +1113,7 @@ CSL.getCitationCluster = function (inputList, citation) {
//var use_layout_prefix = this.citation.opt.layout_prefix;
var suppressTrailingPunctuation = false;
- if (this.opt.xclass === "note" && this.citation.opt.suppressTrailingPunctuation) {
+ if (this.citation.opt.suppressTrailingPunctuation) {
suppressTrailingPunctuation = true;
}
if (citationID) {
diff --git a/lib/citeproc-js/src/attributes.js b/lib/citeproc-js/src/attributes.js
index 347735c..4c0371d 100644
--- a/lib/citeproc-js/src/attributes.js
+++ b/lib/citeproc-js/src/attributes.js
@@ -627,6 +627,22 @@ CSL.Attributes["@is-plural"] = function (state, arg) {
this.tests.push(func);
};
+CSL.Attributes["@is-multiple"] = function (state, arg) {
+ if (!this.tests) {this.tests = []; };
+ var func = function (Item) {
+ var val = ("" + Item[arg]);
+ var lst = val.split(/(?:,\s|\s(?:tot\sen\smet|līdz|oraz|and|bis|έως|και|och|až|do|en|et|in|ir|ja|og|sa|to|un|und|és|și|i|u|y|à|e|a|и|-|–)\s|—|\&)/);
+ if (lst.length > 1) {
+ return true;
+ }
+ return false;
+ };
+ this.tests.push(func);
+};
+
+
+
+
CSL.Attributes["@locale"] = function (state, arg) {
if (!this.tests) {this.tests = []; };
var ret, langspec, lang, lst, i, ilen;
@@ -896,6 +912,19 @@ CSL.Attributes["@has-subunit"] = function (state, arg) {
this.tests.push(maketest(arg));
}
+CSL.Attributes["@cite-form"] = function (state, arg) {
+ if (!this.tests) {this.tests = []; };
+ var maketest = function(citeForm) {
+ return function (Item) {
+ if (Item["cite-form"] === citeForm) {
+ return true;
+ }
+ return false;
+ };
+ };
+ this.tests.push(maketest(arg));
+}
+
CSL.Attributes["@disable-duplicate-year-suppression"] = function (state, arg) {
state.opt.disable_duplicate_year_suppression = arg.split(/\s+/);
}
@@ -946,6 +975,7 @@ CSL.Attributes["@parallel-last"] = function (state, arg) {
}
};
CSL.Attributes["@parallel-last-to-first"] = function (state, arg) {
+ state.opt.parallel.enable = true;
var vars = arg.split(/\s+/);
this.parallel_last_to_first = {};
for (var i=0,ilen=vars.length;i]*(>)/g, "$1 $2$3").replace(/(]*(>)/g, "$1 $2 $3;$4$5");
});
+ var rexNameStr = "(?:[-\\s]*<\\/*(?:span\s+class=\"no(?:case|decor)\"|i|sc|b|sub|sup)>[-\\s]*|[-\\s]+)";
+ var nameDoppel = new CSL.Doppeler(rexNameStr);
- var wordDoppel = new CSL.Doppeler("(?:[\u0020\u00A0\u2000-\u200B\u205F\u3000]+)");
+ var wordDoppel = new CSL.Doppeler("(?:[\u00A0\u0020\u00A0\u2000-\u200B\u205F\u3000]+)");
/**
* INTERNAL
@@ -279,7 +281,6 @@ CSL.Output.Formatters = (function () {
quoteState: [],
capitaliseWords: function(str, i, followingTag) {
if (str.trim()) {
- var words = str.split(/[ \u00A0]+/);
var wordle = wordDoppel.split(str);
var words = wordle.strings;
for (var j=0,jlen=words.length;j 1 && !CSL.toLocaleLowerCase.call(state, word).match(config.skipWordsRex)) {
+ let lcase = CSL.toLocaleLowerCase.call(state, word);
+ let capitalize = false;
+ if (word.length > 1 && !lcase.match(config.skipWordsRex)) {
// Capitalize every word that is not a stop-word
- words[j] = _capitalise.call(state, words[j]);
+ capitalize = true;
} else if (j === (words.length - 1) && followingTag === "-") {
- words[j] = _capitalise.call(state, words[j]);
+ capitalize = true;
} else if (config.isFirst) {
// Capitalize first word, even if a stop-word
- words[j] = _capitalise.call(state, words[j]);
+ capitalize = true;
} else if (config.afterPunct) {
// Capitalize after punctuation
- words[j] = _capitalise.call(state, words[j]);
+ capitalize = true;
+ }
+ // Don't capitalize if word already contains capitalization
+ if (capitalize && word === lcase) {
+ words[j] = _capitalise.call(state, word);
}
config.afterPunct = false;
config.isFirst = false;
@@ -327,18 +334,22 @@ CSL.Output.Formatters = (function () {
var config = {
quoteState: [],
capitaliseWords: function(str) {
- var words = str.split(" ");
+ var wordle = wordDoppel.split(str);
+ var words = wordle.strings;
for (var i=0,ilen=words.length;i -1; j--) {
+ if (state.opt.availableAbbrevDomains[country].indexOf(itemDomainPreference[j]) > -1) {
+ domain = itemDomainPreference[j];
+ break;
+ }
+ }
+ }
+ if (!domain && globalDomainPreference) {
+ for (var j=globalDomainPreference.length-1; j > -1; j--) {
+ if (state.opt.availableAbbrevDomains[country].indexOf(globalDomainPreference[j]) > -1) {
+ domain = globalDomainPreference[j];
+ break;
+ }
+ }
+ }
+ }
+ return domain;
+ },
+
FIELD_CATEGORY_REMAP: {
"title": "title",
"container-title": "container-title",
@@ -673,33 +698,61 @@ var CSL = {
NAME_VARIABLES: [
"author",
+ "chair",
"collection-editor",
+ "compiler",
"composer",
"container-author",
+ "contributor",
+ "curator",
"director",
"editor",
+ "editor-translator",
"editorial-director",
+ "executive-producer",
+ "guest",
+ "host",
"illustrator",
"interviewer",
+ "narrator",
+ "organizer",
"original-author",
+ "performer",
+ "producer",
"recipient",
"reviewed-author",
+ "script-writer",
+ "series-creator",
"translator",
"commenter"
],
CREATORS: [
"author",
+ "chair",
"collection-editor",
+ "compiler",
"composer",
"container-author",
+ "contributor",
+ "curator",
"director",
"editor",
+ "editor-translator",
"editorial-director",
+ "executive-producer",
+ "guest",
+ "host",
"illustrator",
"interviewer",
+ "narrator",
+ "organizer",
"original-author",
+ "performer",
+ "producer",
"recipient",
"reviewed-author",
+ "script-writer",
+ "series-creator",
"translator",
"commenter"
],
@@ -716,10 +769,13 @@ var CSL = {
"number",
"number-of-pages",
"number-of-volumes",
+ "part-number",
+ "printing-number",
+ "section",
+ "supplement-number",
"version",
"volume",
- // "section", ??? add this?
- "supplement",
+ "supplement", // maybe deprecated this? supplement-number should serve this purpose in standard CSL.
"citation-number"
],
//var x = new Array();
@@ -1424,6 +1480,9 @@ var CSL = {
},
INIT_JURISDICTION_MACROS: function (state, Item, item, macroName) {
+ if (Item["best-jurisdiction"]) {
+ return true;
+ }
if (!state.sys.retrieveStyleModule || !CSL.MODULE_MACROS[macroName] || !Item.jurisdiction) {
return false;
}
@@ -1434,48 +1493,13 @@ var CSL = {
// Okay. We have code for each of the novel modules in the
// hierarchy. Load them all into the processor.
for (var jurisdiction in res) {
- var macroCount = 0;
- state.juris[jurisdiction] = {};
- var myXml = CSL.setupXml(res[jurisdiction]);
- myXml.addMissingNameNodes(myXml.dataObj);
- myXml.addInstitutionNodes(myXml.dataObj);
- myXml.insertPublisherAndPlace(myXml.dataObj);
- myXml.flagDateMacros(myXml.dataObj);
- var myNodes = myXml.getNodesByName(myXml.dataObj, "law-module");
- for (var i=0,ilen=myNodes.length;i-1;i+=-1) {
// Might not want to be quite this restrictive.
if (this.citationreg.citationsByItemId) {
- if (!this.citationreg.citationsByItemId[this.mylist[i]] && !myhash[this.mylist[i]]) {
+ if ((!this.citationreg.citationsByItemId || !this.citationreg.citationsByItemId[this.mylist[i]]) && !myhash[this.mylist[i]]) {
delete this.myhash[this.mylist[i]];
+ delete this.uncited[this.mylist[i]];
this.mylist = this.mylist.slice(0,i).concat(this.mylist.slice(i+1));
}
}
diff --git a/lib/citeproc-js/src/state.js b/lib/citeproc-js/src/state.js
index 088ca4d..8c765e0 100644
--- a/lib/citeproc-js/src/state.js
+++ b/lib/citeproc-js/src/state.js
@@ -143,6 +143,8 @@ CSL.Engine.Opt = function () {
this.disable_duplicate_year_suppression = [];
this.use_context_condition = false;
+ this.jurisdiction_fallbacks = {};
+
this.development_extensions = {};
this.development_extensions.field_hack = true;
this.development_extensions.allow_field_hack_date_override = true;
@@ -172,6 +174,8 @@ CSL.Engine.Opt = function () {
this.development_extensions.implicit_short_title = false;
this.development_extensions.force_title_abbrev_fallback = false;
this.development_extensions.split_container_title = false;
+ this.development_extensions.legacy_institution_name_ordering = false;
+ this.development_extensions.etal_min_etal_usefirst_hack = false;
};
CSL.Engine.Tmp = function () {
diff --git a/lib/citeproc-js/src/util_date.js b/lib/citeproc-js/src/util_date.js
index 30afe28..d192833 100644
--- a/lib/citeproc-js/src/util_date.js
+++ b/lib/citeproc-js/src/util_date.js
@@ -15,9 +15,6 @@ CSL.dateAsSortKey = function (state, Item, isMacro) {
dp = Item[variable];
if ("undefined" === typeof dp) {
dp = {"date-parts": [[0]] };
- if (!dp.year) {
- state.tmp.empty_date = true;
- }
}
if ("undefined" === typeof this.dateparts) {
this.dateparts = ["year", "month", "day"];
@@ -30,32 +27,34 @@ CSL.dateAsSortKey = function (state, Item, isMacro) {
if ("undefined" === typeof dp) {
dp = {};
}
- for (i = 0, ilen = CSL.DATE_PARTS_INTERNAL.length; i < ilen; i += 1) {
- elem = CSL.DATE_PARTS_INTERNAL[i];
- value = 0;
- e = elem;
- if (e.slice(-4) === "_end") {
- e = e.slice(0, -4);
- }
- if (dp[elem] && this.dateparts.indexOf(e) > -1) {
- value = dp[elem];
- }
- if (elem.slice(0, 4) === "year") {
- yr = CSL.Util.Dates[e].numeric(state, value);
- var prefix = "Y";
- if (yr[0] === "-") {
- prefix = "X";
- yr = yr.slice(1);
- yr = 9999 - parseInt(yr, 10);
+ if (dp.year) {
+ for (i = 0, ilen = CSL.DATE_PARTS_INTERNAL.length; i < ilen; i += 1) {
+ elem = CSL.DATE_PARTS_INTERNAL[i];
+ value = 0;
+ e = elem;
+ if (e.slice(-4) === "_end") {
+ e = e.slice(0, -4);
+ }
+ if (dp[elem] && this.dateparts.indexOf(e) > -1) {
+ value = dp[elem];
}
- state.output.append(CSL.Util.Dates[elem.slice(0, 4)].numeric(state, (prefix + yr)), macroFlag);
- } else {
- value = CSL.Util.Dates[e]["numeric-leading-zeros"](state, value);
- // Ugh.
- if (!value) {
- value = "00";
+ if (elem.slice(0, 4) === "year") {
+ yr = CSL.Util.Dates[e].numeric(state, value);
+ var prefix = "1";
+ if (yr[0] === "-") {
+ prefix = "0";
+ yr = yr.slice(1);
+ yr = 9999 - parseInt(yr, 10);
+ }
+ state.output.append(CSL.Util.Dates[elem.slice(0, 4)].numeric(state, (prefix + yr)), macroFlag);
+ } else {
+ value = CSL.Util.Dates[e]["numeric-leading-zeros"](state, value);
+ // Ugh.
+ if (!value) {
+ value = "00";
+ }
+ state.output.append(value, macroFlag);
}
- state.output.append(value, macroFlag);
}
}
};
diff --git a/lib/citeproc-js/src/util_dates.js b/lib/citeproc-js/src/util_dates.js
index a011291..a6c53f5 100644
--- a/lib/citeproc-js/src/util_dates.js
+++ b/lib/citeproc-js/src/util_dates.js
@@ -67,6 +67,8 @@ CSL.Util.Dates.year.imperial = function (state, num, end) {
label = '\u5e73\u6210';
offset = 1988;
}
+ // This entire "imperial" code block should be cut. Scraped input
+ // for this will be too ratty to be useful anyway.
if (label && offset) {
var normalizedKey = label;
if (state.sys.normalizeAbbrevsKey) {
@@ -75,7 +77,9 @@ CSL.Util.Dates.year.imperial = function (state, num, end) {
normalizedKey = state.sys.normalizeAbbrevsKey("number", label);
}
if (!state.transform.abbrevs['default']['number'][normalizedKey]) {
- state.transform.loadAbbreviation('default', "number", normalizedKey);
+ // loadAbbreviation normally takes an item as fourth argument.
+ // It is not available here,
+ state.transform.loadAbbreviation('default', "number", normalizedKey, null);
}
if (state.transform.abbrevs['default']['number'][normalizedKey]) {
label = state.transform.abbrevs['default']['number'][normalizedKey];
diff --git a/lib/citeproc-js/src/util_locale.js b/lib/citeproc-js/src/util_locale.js
index a82c513..acbde7e 100644
--- a/lib/citeproc-js/src/util_locale.js
+++ b/lib/citeproc-js/src/util_locale.js
@@ -121,14 +121,33 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) {
// Xml: get a list of all "locale" nodes
//
nodes = myxml.getNodesByName(myxml.dataObj, "locale");
+ var foundLocale = false;
for (pos = 0, len = myxml.numberofnodes(nodes); pos < len; pos += 1) {
blob = nodes[pos];
//
// Xml: get locale xml:lang
//
- if (myxml.getAttributeValue(blob, 'lang', 'xml') === lang_in) {
+ // Iterate over all locales, but for non-matching nodes,
+ // we set jurisdiction_preference only (processing of the
+ // chosen one will process the attribute there,
+ // separately.
+ if (!foundLocale && myxml.getAttributeValue(blob, 'lang', 'xml') === lang_in) {
locale = blob;
- break;
+ foundLocale = true;
+ } else {
+ var lang = myxml.getAttributeValue(blob, 'lang', 'xml');
+ var style_options = myxml.getNodesByName(blob, 'style-options');
+ if (lang && style_options && style_options.length) {
+ var jurispref = myxml.getAttributeValue(style_options[0], 'jurisdiction-preference');
+ if (jurispref) {
+ if (!this.locale[lang]) {
+ this.locale[lang] = {
+ opts: {}
+ };
+ }
+ this.locale[lang].opts["jurisdiction-preference"] = jurispref.split(/\s+/);
+ }
+ }
}
}
}
diff --git a/lib/citeproc-js/src/util_modules.js b/lib/citeproc-js/src/util_modules.js
index f0245ae..6020f16 100644
--- a/lib/citeproc-js/src/util_modules.js
+++ b/lib/citeproc-js/src/util_modules.js
@@ -2,7 +2,12 @@ CSL.Engine.prototype.getJurisdictionList = function (jurisdiction) {
var jurisdictionList = [];
var jurisdictionElems = jurisdiction.split(":");
for (var j=jurisdictionElems.length;j>0;j--) {
- jurisdictionList.push(jurisdictionElems.slice(0,j).join(":"));
+ var composedID = jurisdictionElems.slice(0,j).join(":");
+ jurisdictionList.push(composedID);
+ if (this.opt.jurisdiction_fallbacks[composedID]) {
+ var fallback = this.opt.jurisdiction_fallbacks[composedID];
+ jurisdictionList.push(fallback);
+ }
}
if (jurisdictionList.indexOf("us") === -1) {
jurisdictionList.push("us");
@@ -10,6 +15,60 @@ CSL.Engine.prototype.getJurisdictionList = function (jurisdiction) {
return jurisdictionList;
};
+CSL.Engine.prototype.loadStyleModule = function (jurisdiction, xmlSource, skipFallback) {
+ var myFallback = null;
+ var macroCount = 0;
+ this.juris[jurisdiction] = {};
+ var myXml = CSL.setupXml(xmlSource);
+ myXml.addMissingNameNodes(myXml.dataObj);
+ myXml.addInstitutionNodes(myXml.dataObj);
+ myXml.insertPublisherAndPlace(myXml.dataObj);
+ myXml.flagDateMacros(myXml.dataObj);
+ var myNodes = myXml.getNodesByName(myXml.dataObj, "law-module");
+ for (var i=0,ilen=myNodes.length;i -1
- || (!name.match(CSL.STARTSWITH_ROMANESQUE_REGEXP)
+ || (!name.replace(/^(?:<[^>]+>)*/, "").match(CSL.STARTSWITH_ROMANESQUE_REGEXP)
&& !terminator.match("%s"))) {
return name;
}
- var namelist = name;
+
if (state.opt["initialize-with-hyphen"] === false) {
- namelist = namelist.replace(/\-/g, " ");
+ name = name.replace(/\-/g, " ");
}
- // Oh boy.
// We need to suss out what is a set of initials or abbreviation,
// so that they can be selectively normalized. Steps might be:
// (1) Split the string
@@ -67,50 +66,72 @@ CSL.Util.Names.initializeWith = function (state, name, terminator, normalizeOnly
// (a) Do the thing below, but only pushing terminator; or else
// (b) Do the thing below
- // (1) Split the string
- namelist = namelist.replace(/\s*\-\s*/g, "-").replace(/\s+/g, " ");
- namelist = namelist.replace(/-([a-z])/g, "\u2013$1");
+ name = name.replace(/\s*\-\s*/g, "-").replace(/\s+/g, " ");
+ name = name.replace(/-([a-z])/g, "\u2013$1");
- for (var i=namelist.length-2; i>-1; i += -1) {
- if (namelist.slice(i, i+1) === "." && namelist.slice(i+1, i+2) !== " ") {
- namelist = namelist.slice(0, i) + ". " + namelist.slice(i+1);
+ for (var i=name.length-2; i>-1; i += -1) {
+ if (name.slice(i, i+1) === "." && name.slice(i+1, i+2) !== " ") {
+ name = name.slice(0, i) + ". " + name.slice(i+1);
}
}
- // Workaround for Internet Explorer
- //namelist = namelist.split(/(\-|\s+)/);
- // Workaround for Internet Explorer
- mm = namelist.match(/[\-\s]+/g);
- lst = namelist.split(/[\-\s]+/);
- if (mm === null) {
- var mmm = lst[0].match(/[^\.]+$/);
+ // (1) Split the string
+ var nameSplits = CSL.Output.Formatters.nameDoppel.split(name);
+ var namelist = [];
+ namelist = [nameSplits.strings[0]];
+
+ if (nameSplits.tags.length === 0) {
+ var mmm = namelist[0].match(/[^\.]+$/);
if (mmm && mmm[0].length === 1 && mmm[0] !== mmm[0].toLowerCase()) {
- lst[0] += ".";
+ namelist[0] += ".";
}
}
- if (lst.length === 0) {
- // This doesn't make much sense, and may be impossible.
- namelist = mm;
- } else {
- namelist = [lst[0]];
- for (i = 1, ilen = lst.length; i < ilen; i += 1) {
- namelist.push(mm[i - 1]);
- namelist.push(lst[i]);
- }
+ for (i = 1, ilen = nameSplits.strings.length; i < ilen; i += 1) {
+ namelist.push(nameSplits.tags[i - 1]);
+ namelist.push(nameSplits.strings[i]);
}
- lst = namelist;
// Use doInitializeName or doNormalizeName, depending on requirements.
if (normalizeOnly) {
- ret = CSL.Util.Names.doNormalize(state, lst, terminator);
+ ret = this.doNormalize(state, namelist, terminator);
} else {
- ret = CSL.Util.Names.doInitialize(state, lst, terminator);
+ ret = this.doInitialize(state, namelist, terminator);
}
ret = ret.replace(/\u2013([a-z])/g, "-$1");
return ret;
};
+CSL.Util.Names.notag = function(str) {
+ return str.replace(/^(?:<[^>]+>)*/, "");
+};
+
+CSL.Util.Names.mergetag = function(state, tagstr, newstr) {
+ var m = tagstr.match(/(?:-*<[^>]+>-*)/g);
+ if (!m) {
+ return newstr;
+ } else {
+ tagstr = m.join("");
+ }
+ m = newstr.match(/^(.*[^\s])*(\s+)$/);
+ if (m) {
+ m[1] = m[1] ? m[1] : "";
+ newstr = m[1] + tagstr + m[2];
+ } else {
+ newstr = newstr + tagstr;
+ }
+ return newstr;
+};
+
+CSL.Util.Names.tagonly = function(state, str) {
+ var m = str.match(/(?:<[^>]+>)+/);
+ if (!m) {
+ return str;
+ } else {
+ return m.join("");
+ }
+};
+
CSL.Util.Names.doNormalize = function (state, namelist, terminator) {
var i, ilen;
// namelist is a flat list of given-name elements and space-like separators between them
@@ -118,8 +139,9 @@ CSL.Util.Names.doNormalize = function (state, namelist, terminator) {
// Flag elements that look like abbreviations
var isAbbrev = [];
for (i = 0, ilen = namelist.length; i < ilen; i += 1) {
- if (namelist[i].length > 1 && namelist[i].slice(-1) === ".") {
- namelist[i] = namelist[i].slice(0, -1);
+ if (this.notag(namelist[i]).length > 1 && this.notag(namelist[i]).slice(-1) === ".") {
+ // namelist[i] = namelist[i].slice(0, -1);
+ namelist[i] = namelist[i].replace(/^(.*)\.(.*)$/, "$1$2");
isAbbrev.push(true);
} else if (namelist[i].length === 1 && namelist[i].toUpperCase() === namelist[i]) {
isAbbrev.push(true);
@@ -134,19 +156,18 @@ CSL.Util.Names.doNormalize = function (state, namelist, terminator) {
// For all elements but the last
if (i < namelist.length - 2) {
// Start from scratch on space-like things following an abbreviation
- namelist[i + 1] = "";
-
+ namelist[i + 1] = this.tagonly(state, namelist[i+1]);
if (!isAbbrev[i+2]) {
- namelist[i + 1] = " ";
+ namelist[i + 1] = this.tagonly(state, namelist[i+1]) + " ";
}
// Add the terminator to the element
// If the following element is not a single-character abbreviation, remove a trailing zero-width non-break space, if present
// These ops may leave some duplicate cruft in the elements and separators. This will be cleaned at the end of the function.
if (namelist[i + 2].length > 1) {
- namelist[i] = namelist[i] + terminator.replace(/\ufeff$/, "");
+ namelist[i+1] = terminator.replace(/\ufeff$/, "") + namelist[i+1];
} else {
- namelist[i] = namelist[i] + terminator;
+ namelist[i+1] = this.mergetag(state, namelist[i+1], terminator);
}
}
// For the last element (if it is an abbreviation), just append the terminator
@@ -197,9 +218,9 @@ CSL.Util.Names.doInitialize = function (state, namelist, terminator) {
namelist[i] = terminator.replace("%s", namelist[i]);
} else {
if (namelist[i + 1].indexOf("-") > -1) {
- namelist[i + 1] = terminator + namelist[i + 1];
+ namelist[i + 1] = this.mergetag(state, namelist[i+1].replace("-", ""), terminator) + "-";
} else {
- namelist[i + 1] = terminator;
+ namelist[i + 1] = this.mergetag(state, namelist[i+1], terminator);
}
}
} else {
@@ -232,11 +253,3 @@ CSL.Util.Names.getRawName = function (name) {
}
return ret.join(" ");
};
-
-// deleted CSL.Util.Names.initNameSlices()
-// no longer used.
-
-// deleted CSL.Util.Names,rescueNameElements()
-// apparently not used.
-
-
diff --git a/lib/citeproc-js/src/util_names_divide.js b/lib/citeproc-js/src/util_names_divide.js
index afb75e0..5216c30 100644
--- a/lib/citeproc-js/src/util_names_divide.js
+++ b/lib/citeproc-js/src/util_names_divide.js
@@ -135,7 +135,7 @@ CSL.NameOutput.prototype._checkNickname = function (name) {
// The first argument does not have to be the exact variable name.
normalizedKey = this.state.sys.normalizeAbbrevsKey("author", author);
}
- this.state.transform.loadAbbreviation("default", "nickname", normalizedKey);
+ this.state.transform.loadAbbreviation("default", "nickname", normalizedKey, this.Item.language);
// XXX Why does this have to happen here?
var myLocalName = this.state.transform.abbrevs["default"].nickname[normalizedKey];
if (myLocalName) {
diff --git a/lib/citeproc-js/src/util_names_output.js b/lib/citeproc-js/src/util_names_output.js
index 48885d0..56068f7 100644
--- a/lib/citeproc-js/src/util_names_output.js
+++ b/lib/citeproc-js/src/util_names_output.js
@@ -388,7 +388,10 @@ CSL.NameOutput.prototype.outputNames = function () {
}
author_title = author_title.join(", ");
if (author_title && this.state.sys.getAbbreviation) {
- this.state.transform.loadAbbreviation("default", "classic", author_title);
+ if (this.state.sys.normalizeAbbrevsKey) {
+ author_title = this.state.sys.normalizeAbbrevsKey("classic", author_title);
+ }
+ this.state.transform.loadAbbreviation("default", "classic", author_title, this.Item.language);
if (this.state.transform.abbrevs["default"].classic[author_title]) {
this.state.tmp.done_vars.push("title");
this.state.output.append(this.state.transform.abbrevs["default"].classic[author_title], "empty", true);
diff --git a/lib/citeproc-js/src/util_names_render.js b/lib/citeproc-js/src/util_names_render.js
index 529be82..f5985b9 100644
--- a/lib/citeproc-js/src/util_names_render.js
+++ b/lib/citeproc-js/src/util_names_render.js
@@ -774,8 +774,8 @@ CSL.NameOutput.prototype._nameSuffix = function (name) {
var str = name.suffix, ret;
- if ("string" === typeof this.state.inheritOpt(this.name, "initialize-with")) {
- str = CSL.Util.Names.initializeWith(this.state, name.suffix, this.state.inheritOpt(this.name, "initialize-with"), true);
+ if (str && "string" === typeof this.state.inheritOpt(this.name, "initialize-with")) {
+ str = CSL.Util.Names.initializeWith(this.state, str, this.state.inheritOpt(this.name, "initialize-with"), true);
}
str = this._stripPeriods("family", str);
@@ -1010,56 +1010,95 @@ CSL.NameOutput.prototype.setRenderedName = function (name) {
};
CSL.NameOutput.prototype.fixupInstitution = function (name, varname, listpos) {
- name = this._splitInstitution(name, varname, listpos);
- // XXX This should be embedded in the institution name function.
- if (this.institution.strings["reverse-order"]) {
- name["long"].reverse();
+ if (!name.literal && name.family) {
+ name.literal = name.family;
+ delete name.family;
}
-
- var long_form = name["long"];
- var short_form = name["long"].slice();
- var use_short_form = false;
- var itemJurisdiction = this.Item.jurisdiction;
+ var longNameStr = name.literal;
+ var shortNameStr = longNameStr;
+ var ret = {
+ "long": longNameStr.split(/\s*\|\s*/),
+ "short": shortNameStr.split(/\s*\|\s*/),
+ };
if (this.state.sys.getAbbreviation) {
- var jurisdiction = itemJurisdiction;
- for (var j = 0, jlen = long_form.length; j < jlen; j += 1) {
- var abbrevKey = long_form[j];
- jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-part", abbrevKey);
- if (this.state.transform.abbrevs[jurisdiction]["institution-part"][abbrevKey]) {
- short_form[j] = this.state.transform.abbrevs[jurisdiction]["institution-part"][abbrevKey];
- use_short_form = true;
+ // Normalize longNameStr and shortNameStr
+ if (this.institution.strings.form === "short") {
+ let jurisdiction = this.Item.jurisdiction;
+ jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-entire", longNameStr, this.Item.language);
+ if (this.state.transform.abbrevs[jurisdiction]["institution-entire"][longNameStr]) {
+ longNameStr = this.state.transform.abbrevs[jurisdiction]["institution-entire"][longNameStr];
+ } else {
+ jurisdiction = this.Item.jurisdiction;
+ jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-part", longNameStr, this.Item.language);
+ if (this.state.transform.abbrevs[jurisdiction]["institution-part"][longNameStr]) {
+ longNameStr = this.state.transform.abbrevs[jurisdiction]["institution-part"][longNameStr];
+ }
}
+ longNameStr = this._quashChecks(jurisdiction, longNameStr);
}
- }
- if (use_short_form) {
- var delimiter = this.institution.strings.delimiter;
- var use_first = this.institution.strings["use-first"];
- if (use_first) {
- if (!delimiter) {
- delimiter = "|";
+ if (["short", "short-long", "long-short"].indexOf(this.institution.strings["institution-parts"]) > -1) {
+ let jurisdiction = this.Item.jurisdiction;
+ jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-part", shortNameStr, this.Item.language);
+ if (this.state.transform.abbrevs[jurisdiction]["institution-part"][shortNameStr]) {
+ shortNameStr = this.state.transform.abbrevs[jurisdiction]["institution-part"][shortNameStr];
}
- var buf = [];
- for (var i=0,ilen=short_form.length;i -1) {
+ if (shortNameStr === longNameStr) {
+ shortNameStr = "";
+ }
}
}
- name["short"] = short_form;
- } else {
- name["short"] = [];
- }
- // trimmer is not available in getAmbiguousCite
- if (!this.state.tmp.just_looking) {
- if (itemJurisdiction) {
- var trimmer = this.state.tmp.abbrev_trimmer;
- if (trimmer && trimmer[itemJurisdiction] && trimmer[itemJurisdiction][varname]) {
- for (var i=0,ilen=name["short"].length;i -1) {
+ for (var j=ret["short"].length-1; j>-1; j--) {
+ let jurisdiction = this.Item.jurisdiction;
+ var abbrevKey = ret["short"][j];
+ jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-part", abbrevKey, this.Item.language);
+ if (this.state.transform.abbrevs[jurisdiction]["institution-part"][abbrevKey]) {
+ ret["short"][j] = this.state.transform.abbrevs[jurisdiction]["institution-part"][abbrevKey];
+ }
+ if (ret["short"][j].indexOf("|") > -1) {
+ let retShort = ret["short"];
+ let splitShort = retShort[j].split(/\s*\|\s*/);
+ ret["short"] = retShort.slice(0, j).concat(splitShort).concat(retShort.slice(j+1));
+ }
+ }
+ }
+ if (this.state.opt.development_extensions.legacy_institution_name_ordering) {
+ ret["short"].reverse();
+ }
+ ret["short"] = this._trimInstitution(ret["short"]);
+ if (this.institution.strings["reverse-order"]) {
+ ret["short"].reverse();
+ }
+ // trimmer is not available in getAmbiguousCite
+ if (!this.state.tmp.just_looking) {
+ if (this.Item.jurisdiction) {
+ let jurisdiction = this.Item.jurisdiction;
+ var trimmer = this.state.tmp.abbrev_trimmer;
+ if (trimmer && trimmer[jurisdiction] && trimmer[jurisdiction][varname]) {
+ for (var i=0,ilen=ret["short"].length;i 0; j += -1) {
- var jurisdiction = itemJurisdiction;
- var str = splitInstitution.slice(0, j).join("|");
- var abbrevKey = str;
- jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-entire", abbrevKey);
- if (this.state.transform.abbrevs[jurisdiction]["institution-entire"][abbrevKey]) {
- var splitLst = this.state.transform.abbrevs[jurisdiction]["institution-entire"][abbrevKey];
-
- splitLst = this.state.transform.quashCheck(itemJurisdiction, splitLst);
-
- // If the abbreviation has date cut-offs, find the most recent
- // abbreviation within scope.
- var splitSplitLst = splitLst.split(/>>[0-9]{4}>>/);
- var m = splitLst.match(/>>([0-9]{4})>>/);
- splitLst = splitSplitLst.pop();
- if (splitSplitLst.length > 0 && this.Item["original-date"] && this.Item["original-date"].year) {
- for (var k=m.length - 1; k > 0; k += -1) {
- if (parseInt(this.Item["original-date"].year, 10) >= parseInt(m[k], 10)) {
- break;
- }
- splitLst = splitSplitLst.pop();
- }
+CSL.NameOutput.prototype._quashChecks = function (jurisdiction, str) {
+ var str = this.state.transform.quashCheck(jurisdiction, str);
+ // If the abbreviation has date cut-offs, find the most recent
+ // abbreviation within scope.
+ var lst = str.split(/>>[0-9]{4}>>/);
+ var m = str.match(/>>([0-9]{4})>>/);
+ str = lst.pop();
+ var date = this.Item["original-date"] ? this.Item["original-date"] : this.Item["issued"];
+ if (date) {
+ date = parseInt(date.year, 10);
+ date = isNaN(date) ? false : date;
+ }
+ if (date) {
+ if (lst.length > 0) {
+ for (var k=m.length-1; k>0; k--) {
+ if (date >= parseInt(m[k], 10)) {
+ break;
}
- splitLst = splitLst.replace(/\s*\|\s*/g, "|");
- splitInstitution = [splitLst];
- break;
+ str = lst.pop();
}
}
+ str = str.replace(/\s*\|\s*/g, "|");
}
- splitInstitution.reverse();
- //print("into _trimInstitution with splitInstitution, v, i = "+splitInstitution+", "+v+", "+i);
- ret["long"] = this._trimInstitution(splitInstitution, v, i);
- return ret;
-};
+ return str;
+}
-CSL.NameOutput.prototype._trimInstitution = function (subunits, v) {
- //
+CSL.NameOutput.prototype._trimInstitution = function (subunits) {
+ // Oh! Good catch in the tests. This happens before abbrevs.
+ // Won't work that way. Need to do abbrev substitute first,
+ // and apply this separately to long and to short.
var use_first = false;
- var append_last = false;
- var s = subunits.slice();
var stop_last = false;
+ var use_last = false;
+ var stop_first = false;
+ var s = subunits.slice();
if (this.institution) {
+ // If use_first, apply stop_last, then apply use_first;
+ // If use_last, apply stop_first, then apply use_last;
if ("undefined" !== typeof this.institution.strings["use-first"]) {
+ // this.state.sys.print("use-first OK");
use_first = this.institution.strings["use-first"];
}
- if ("undefined" !== typeof this.institution.strings["stop-last"]) {
- // stop-last is negative when present
- stop_last = this.institution.strings["stop-last"];
- } else if ("authority" === v && this.state.tmp.authority_stop_last) {
- stop_last = this.state.tmp.authority_stop_last;
- }
- if (stop_last) {
- s = s.slice(0, stop_last);
- subunits = subunits.slice(0, stop_last);
- }
if ("undefined" !== typeof this.institution.strings["use-last"]) {
- append_last = this.institution.strings["use-last"];
- }
- if ("authority" === v) {
- if (stop_last) {
- this.state.tmp.authority_stop_last = stop_last;
- }
- if (append_last) {
- this.state.tmp.authority_stop_last += (append_last * -1);
- }
- }
- }
- if (false === use_first) {
- if (this.persons[v].length === 0) {
- use_first = this.institution.strings["substitute-use-first"];
+ // this.state.sys.print("use-last OK");
+ use_last = this.institution.strings["use-last"];
}
- if (!use_first) {
- use_first = 0;
+ if ("undefined" !== typeof this.institution.strings["stop-first"]) {
+ // this.state.sys.print("stop-first OK");
+ stop_first = this.institution.strings["stop-first"];
}
- }
- if (false === append_last) {
- if (!use_first) {
- append_last = subunits.length;
- } else {
- append_last = 0;
+ if ("undefined" !== typeof this.institution.strings["stop-last"]) {
+ stop_last = this.institution.strings["stop-last"];
}
- }
- // Now that we've determined the value of append_last
- // (use-last), avoid overlaps.
- if (use_first > subunits.length - append_last) {
- use_first = subunits.length - append_last;
- }
- // This could be more clear. use-last takes priority
- // in the event of overlap, because of adjustment above
- subunits = subunits.slice(0, use_first);
- s = s.slice(use_first);
- if (append_last) {
- if (append_last > s.length) {
- append_last = s.length;
+ if (use_first) {
+ if (stop_last) {
+ s = s.slice(0, stop_last * -1);
+ }
+ s = s.slice(0, use_first);
}
- if (append_last) {
- subunits = subunits.concat(s.slice((s.length - append_last)));
+
+ if (use_last) {
+ var ss = subunits.slice();
+ if (use_first) {
+ stop_first = use_first;
+ } else {
+ s = [];
+ }
+ if (stop_first) {
+ ss = ss.slice(stop_first);
+ }
+ ss = ss.slice(use_last * -1);
+ s = s.concat(ss);
}
+ subunits = s;
}
return subunits;
};
diff --git a/lib/citeproc-js/src/util_names_truncate.js b/lib/citeproc-js/src/util_names_truncate.js
index 22ae2e0..0a45d42 100644
--- a/lib/citeproc-js/src/util_names_truncate.js
+++ b/lib/citeproc-js/src/util_names_truncate.js
@@ -27,8 +27,8 @@ CSL.NameOutput.prototype.truncatePersonalNameLists = function () {
}
}
}
- // Could be factored out to a separate function for clarity.
- if (this.etal_min === 1 && this.etal_use_first === 1
+ if (this.state.opt.development_extensions.etal_min_etal_usefirst_hack
+ && this.etal_min === 1 && this.etal_use_first === 1
&& !(this.state.tmp.extension
|| this.state.tmp.just_looking)) {
chopvar = v;
diff --git a/lib/citeproc-js/src/util_number.js b/lib/citeproc-js/src/util_number.js
index d22caaa..1dab0a4 100644
--- a/lib/citeproc-js/src/util_number.js
+++ b/lib/citeproc-js/src/util_number.js
@@ -195,7 +195,7 @@ CSL.Engine.prototype.processNumber = function (node, ItemObject, variable) {
if (localeAnd === localeAmpersand) {
localeAmpersand = "&";
}
-
+
// XXXX shadow_numbers should carry an array of objects with
// XXXX full data for each. The test of a number should be
// XXXX a separate function, possibly supported by a splitter
@@ -302,6 +302,11 @@ CSL.Engine.prototype.processNumber = function (node, ItemObject, variable) {
str = normalizeFieldValue(str, defaultLabel);
var jmrex, jsrex, mystr;
+ if ("page" === variable) {
+ if (str.indexOf("\u2013") > -1) {
+ str = str.replace(/\u2013/g, "-");
+ }
+ }
if (str.indexOf("\\-") > -1) {
jmrex = new RegExp(joinerMatchRex.source.replace("\\-", ""));
jsrex = new RegExp(joinerSplitRex.source.replace("\\-", ""));
@@ -784,6 +789,10 @@ CSL.Engine.prototype.processNumber = function (node, ItemObject, variable) {
val = ItemObject[realVariable];
}
+ if (val && realVariable === "number" && ItemObject.type === "legal_case") {
+ val = val.replace(/[\\]*-/g, "\\-");
+ }
+
// XXX HOLDING THIS
// Apply short form ONLY if first element tests is-numeric=false
if (val && this.sys.getAbbreviation) {
@@ -792,16 +801,23 @@ CSL.Engine.prototype.processNumber = function (node, ItemObject, variable) {
// No need for this.
//val = ("" + val).replace(/^\"/, "").replace(/\"$/, "");
-
- var jurisdiction = this.transform.loadAbbreviation(ItemObject.jurisdiction, "number", val);
+ if (this.sys.normalizeAbbrevsKey) {
+ var normval = this.sys.normalizeAbbrevsKey(realVariable, val);
+ } else {
+ var normval = val;
+ }
+ var jurisdiction = this.transform.loadAbbreviation(ItemObject.jurisdiction, "number", normval, ItemObject.language);
if (this.transform.abbrevs[jurisdiction].number) {
- if (this.transform.abbrevs[jurisdiction].number[val]) {
- val = this.transform.abbrevs[jurisdiction].number[val];
+ if (this.transform.abbrevs[jurisdiction].number[normval]) {
+ val = this.transform.abbrevs[jurisdiction].number[normval];
} else {
+
+ // *** This is terrible ***
+
// Strings rendered via cs:number should not be added to the abbreviations
// UI unless they test non-numeric. The test happens below.
- if ("undefined" !== typeof this.transform.abbrevs[jurisdiction].number[val]) {
- delete this.transform.abbrevs[jurisdiction].number[val];
+ if ("undefined" !== typeof this.transform.abbrevs[jurisdiction].number[normval]) {
+ delete this.transform.abbrevs[jurisdiction].number[normval];
}
}
}
@@ -971,9 +987,9 @@ CSL.Util.outputNumericField = function(state, varname, itemID) {
if (num.collapsible) {
var blob;
if (num.value.match(/^[1-9][0-9]*$/)) {
- blob = new CSL.NumericBlob(num.particle, parseInt(num.value, 10), numStyling, itemID);
+ blob = new CSL.NumericBlob(state, num.particle, parseInt(num.value, 10), numStyling, itemID);
} else {
- blob = new CSL.NumericBlob(num.particle, num.value, numStyling, itemID);
+ blob = new CSL.NumericBlob(state, num.particle, num.value, numStyling, itemID);
}
if ("undefined" === typeof blob.gender) {
blob.gender = state.locale[state.opt.lang]["noun-genders"][varname];
diff --git a/lib/citeproc-js/src/util_parallel.js b/lib/citeproc-js/src/util_parallel.js
index 987a79e..9d5f21b 100644
--- a/lib/citeproc-js/src/util_parallel.js
+++ b/lib/citeproc-js/src/util_parallel.js
@@ -20,7 +20,7 @@ CSL.Parallel.prototype.StartCitation = function (sortedItems, out) {
var nextItem = sortedItems[i+1][0];
var freshMatchList = false;
var info = {};
- if (sortedItems[i][0].seeAlso && !parallelMatchList) {
+ if (sortedItems[i][0].seeAlso && sortedItems[i][0].seeAlso.length > 0 && !parallelMatchList) {
freshMatchList = true;
parallelMatchList = [sortedItems[i][0].id].concat(sortedItems[i][0].seeAlso);
var tempMatchList = parallelMatchList.slice();
diff --git a/lib/citeproc-js/src/util_transform.js b/lib/citeproc-js/src/util_transform.js
index 5f8c636..2b5913e 100644
--- a/lib/citeproc-js/src/util_transform.js
+++ b/lib/citeproc-js/src/util_transform.js
@@ -111,7 +111,7 @@ CSL.Transform = function (state) {
} else {
preferredJurisdiction = "default";
}
- var jurisdiction = state.transform.loadAbbreviation(preferredJurisdiction, myabbrev_family, normalizedKey, Item.type);
+ var jurisdiction = state.transform.loadAbbreviation(preferredJurisdiction, myabbrev_family, normalizedKey, Item.language);
// Some rules:
// # variable === "country"
@@ -329,10 +329,15 @@ CSL.Transform = function (state) {
// Setter for abbreviation lists
// This initializes a single abbreviation based on known
// data.
- function loadAbbreviation(jurisdiction, category, orig, itemType) {
+ function loadAbbreviation(jurisdiction, category, orig, lang) {
if (!jurisdiction) {
jurisdiction = "default";
}
+ var country = jurisdiction.split(":")[0];
+ var domain = CSL.getAbbrevsDomain(state, country, lang);
+ if (domain) {
+ jurisdiction += ("@" + domain);
+ }
if (!orig) {
if (!state.transform.abbrevs[jurisdiction]) {
state.transform.abbrevs[jurisdiction] = new state.sys.AbbreviationSegments();
@@ -350,9 +355,12 @@ CSL.Transform = function (state) {
//
// See testrunner_stdrhino.js for an example.
if (state.sys.getAbbreviation) {
- jurisdiction = state.sys.getAbbreviation(state.opt.styleID, state.transform.abbrevs, jurisdiction, category, orig, itemType, true);
+ jurisdiction = state.sys.getAbbreviation(state.opt.styleID, state.transform.abbrevs, jurisdiction, category, orig);
if (!jurisdiction) {
jurisdiction = "default";
+ if (domain) {
+ jurisdiction += ("@" + domain);
+ }
}
}
return jurisdiction;
@@ -384,36 +392,44 @@ CSL.Transform = function (state) {
return false;
}
-
+ function citeFormCheck(Item, value) {
+ var m = value.match(/^#([0-9]+).*>>>/);
+ if (m && m[1]) {
+ Item["cite-form"] = m[1];
+ }
+ }
+
// The name transform code is placed here to keep similar things
// in one place. Obviously this module could do with a little
// tidying up.
function quashCheck(jurisdiction, value) {
- var m = value.match(/^!((?:[-_a-z]+(?:(?:.*)))(?:,(?:[-_a-z]+(?:(?:.*))))*)>>>/);
+ var m = value.match(/^(?:#[0-9]+)*(?:!((?:[-_a-z]+(?:(?:.*)))(?:,(?:[-_a-z]+(?:(?:.*))))*))*>>>/);
if (m) {
- var fields = m[1].split(",");
value = value.slice(m[0].length);
- for (var i = 0, ilen = fields.length; i < ilen; i += 1) {
- var rawField = fields[i];
- var mm = rawField.match(/^([-_a-z]+)(?:\:(.*))*$/);
- var field = mm[1];
- // trimmer is not available in getAmbiguousCite
- var trimmer = state.tmp.abbrev_trimmer;
- if (mm[2]) {
- if (trimmer && jurisdiction) {
- if (!trimmer[jurisdiction]) {
- trimmer[jurisdiction] = {};
+ if (m[1]) {
+ var fields = m[1].split(",");
+ for (var i = 0, ilen = fields.length; i < ilen; i += 1) {
+ var rawField = fields[i];
+ var mm = rawField.match(/^([-_a-z]+)(?:\:(.*))*$/);
+ var field = mm[1];
+ // trimmer is not available in getAmbiguousCite
+ var trimmer = state.tmp.abbrev_trimmer;
+ if (mm[2]) {
+ if (trimmer && jurisdiction) {
+ if (!trimmer[jurisdiction]) {
+ trimmer[jurisdiction] = {};
+ }
+ trimmer[jurisdiction][field] = mm[2];
}
- trimmer[jurisdiction][field] = mm[2];
- }
- } else if (state.tmp.done_vars.indexOf(field) === -1) {
- if (trimmer && jurisdiction) {
- if (!trimmer.QUASHES[jurisdiction]) {
- trimmer.QUASHES[jurisdiction] = {};
+ } else if (state.tmp.done_vars.indexOf(field) === -1) {
+ if (trimmer && jurisdiction) {
+ if (!trimmer.QUASHES[jurisdiction]) {
+ trimmer.QUASHES[jurisdiction] = {};
+ }
+ trimmer.QUASHES[jurisdiction][field] = true;
}
- trimmer.QUASHES[jurisdiction][field] = true;
+ state.tmp.done_vars.push(field);
}
- state.tmp.done_vars.push(field);
}
}
}
@@ -516,7 +532,8 @@ CSL.Transform = function (state) {
// Suppress subsequent use of another variable if requested by
// hack syntax in this abbreviation short form.
if (primary) {
- // The abbreviate() function could use a cleanup, after Zotero correct to use title-short
+ // We run quash-check in getAmbiguousCite, to possibly pick up a cite-form value.
+ citeFormCheck(Item, primary);
if (!state.tmp.just_looking) {
primary = quashCheck(Item.jurisdiction, primary);
}
diff --git a/lib/citeproc-js/src/xmljson.js b/lib/citeproc-js/src/xmljson.js
index d13a83d..09c9b06 100644
--- a/lib/citeproc-js/src/xmljson.js
+++ b/lib/citeproc-js/src/xmljson.js
@@ -27,8 +27,7 @@ CSL.XmlJSON = function (dataObj) {
name:"institution",
attrs:{
"institution-parts":"long",
- "substitute-use-first":"1",
- "use-last":"1"
+ "delimiter":", "
},
children:[
{