diff --git a/src/csl/mod.rs b/src/csl/mod.rs index 362afa9..dba7403 100644 --- a/src/csl/mod.rs +++ b/src/csl/mod.rs @@ -83,12 +83,9 @@ impl<'a, T: EntryLike> BibliographyDriver<'a, T> { /// Create a new citation with the given items. pub fn citation(&mut self, mut req: CitationRequest<'a, T>) { - let style = req.style(); - for (i, item) in req.items.iter_mut().enumerate() { item.initial_idx = i; } - style.sort(&mut req.items, style.csl.citation.sort.as_ref(), req.locale.as_ref()); self.citations.push(req); } } @@ -96,7 +93,7 @@ impl<'a, T: EntryLike> BibliographyDriver<'a, T> { /// Implementations for finishing the bibliography. impl<'a, T: EntryLike + Hash + PartialEq + Eq + Debug> BibliographyDriver<'a, T> { /// Render the bibliography. - pub fn finish(self, request: BibliographyRequest<'_>) -> Rendered { + pub fn finish(mut self, request: BibliographyRequest<'_>) -> Rendered { // 1. Assign citation numbers by bibliography ordering or by citation // order and render them a first time without their locators. let bib_style = request.style(); @@ -115,6 +112,7 @@ impl<'a, T: EntryLike + Hash + PartialEq + Eq + Debug> BibliographyDriver<'a, T> &mut entries, bib_style.csl.bibliography.as_ref().and_then(|b| b.sort.as_ref()), request.locale.as_ref(), + |_| 0, ); let citation_number = |item: &T| { entries.iter().position(|e| e.entry == item).expect("entry not found") @@ -124,10 +122,17 @@ impl<'a, T: EntryLike + Hash + PartialEq + Eq + Debug> BibliographyDriver<'a, T> let mut res: Vec> = Vec::new(); let mut last_cite: Option<&CitationItem> = None; - for citation in &self.citations { - let items = &citation.items; + for citation in &mut self.citations { let style = citation.style(); + style.sort( + &mut citation.items, + style.csl.citation.sort.as_ref(), + citation.locale.as_ref(), + &citation_number, + ); + + let items = &citation.items; let mut renders: Vec> = Vec::new(); for item in items.iter() { @@ -516,7 +521,12 @@ pub fn standalone_citation( mut req: CitationRequest<'_, T>, ) -> ElemChildren { let style = req.style(); - style.sort(&mut req.items, style.csl.citation.sort.as_ref(), req.locale.as_ref()); + style.sort( + &mut req.items, + style.csl.citation.sort.as_ref(), + req.locale.as_ref(), + |_| 0, + ); let mut res = vec![]; let mut all_hidden = true; for item in req.items { diff --git a/src/csl/sort.rs b/src/csl/sort.rs index 16826fc..1c8ab83 100644 --- a/src/csl/sort.rs +++ b/src/csl/sort.rs @@ -137,12 +137,20 @@ impl<'a> StyleContext<'a> { cites: &mut [CitationItem], sort: Option<&Sort>, term_locale: Option<&LocaleCode>, + citation_number: impl Fn(&T) -> usize, ) { if let Some(sort) = sort { cites.sort_by(|a, b| { let mut ordering = Ordering::Equal; for key in &sort.keys { - ordering = self.cmp_entries(a, 0, b, 0, key, term_locale); + ordering = self.cmp_entries( + a, + citation_number(a.entry), + b, + citation_number(b.entry), + key, + term_locale, + ); if ordering != Ordering::Equal { break; } diff --git a/tests/citeproc.rs b/tests/citeproc.rs index 1f22642..9395d13 100644 --- a/tests/citeproc.rs +++ b/tests/citeproc.rs @@ -439,6 +439,18 @@ fn test_single_file() { assert!(test_file(case, &locales, || path.display())); } +#[test] +fn test_local_files() { + let locales = locales(); + let test_path = PathBuf::from("tests/local"); + + for path in iter_files_with_name(&test_path, "txt", |_| true) { + let case = build_case(&std::fs::read_to_string(&path).unwrap()); + assert!(can_test(&case, || path.display(), true)); + assert!(test_file(case, &locales, || path.display())); + } +} + fn build_case(s: &str) -> TestCase { let mut s = Scanner::new(s); let mut builder = TestCaseBuilder::new(); diff --git a/tests/local/collapse_CitationNumberRangesSort.txt b/tests/local/collapse_CitationNumberRangesSort.txt new file mode 100644 index 0000000..88b42c4 --- /dev/null +++ b/tests/local/collapse_CitationNumberRangesSort.txt @@ -0,0 +1,98 @@ +>>===== MODE =====>> +citation +<<===== MODE =====<< + +Simplified from collapse_CitationNumberRangesInsert.txt + + +>>===== RESULT =====>> +[1]–[4] +[1]–[4] +<<===== RESULT =====<< + +>>===== CITATION-ITEMS =====>> +[ + [ + { + "id": "ITEM-1" + }, + { + "id": "ITEM-2" + }, + { + "id": "ITEM-3" + }, + { + "id": "ITEM-4" + } + ], + [ + { + "id": "ITEM-2" + }, + { + "id": "ITEM-1" + }, + { + "id": "ITEM-4" + }, + { + "id": "ITEM-3" + } + ] +] +<<===== CITATION-ITEMS =====<< + + +>>===== CSL =====>> + +<<===== CSL =====<< + + +>>===== INPUT =====>> +[ + { + "id": "ITEM-1", + "title": "Paper 1", + "type": "book" + }, + { + "id": "ITEM-2", + "title": "Paper 2", + "type": "book" + }, + { + "id": "ITEM-3", + "title": "Paper 3", + "type": "book" + }, + { + "id": "ITEM-4", + "title": "Paper 4", + "type": "book" + } +] +<<===== INPUT =====<< + + +>>===== VERSION =====>> +1.0 +<<===== VERSION =====<<