Skip to content

Commit

Permalink
Fix formatting of collapsed numeric citations
Browse files Browse the repository at this point in the history
Fixes typst#154.
  • Loading branch information
bluebear94 committed Aug 7, 2024
1 parent 1df9fe4 commit 0587f71
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 57 deletions.
102 changes: 47 additions & 55 deletions src/csl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -863,25 +863,39 @@ fn collapse_items<'a, T: EntryLike>(cite: &mut SpeculativeCiteRender<'a, '_, T>)
match style.citation.collapse {
Some(Collapse::CitationNumber) => {
// Option with the start and end of the range.
let after_collapse_delim =
after_collapse_delim.or(style.citation.layout.delimiter.as_deref());
let mut range_start: Option<(usize, usize)> = None;
let mut ended_range = false;

let end_range = |items: &mut [SpeculativeItemRender<'a, T>],
range_start: &mut Option<(usize, usize)>,
ended_range: &mut bool| {
let use_after_collapse_delim = *ended_range;
*ended_range = false;

if let &mut Some((start, end)) = range_start {
// If the previous citation range was collapsed,
// then use the after-collapse delimiter
// before the next item.
if use_after_collapse_delim {
items[start].delim_override = after_collapse_delim;
}

let end_range =
|items: &mut [SpeculativeItemRender<'a, T>],
range_start: &mut Option<(usize, usize)>| {
if let &mut Some((start, end)) = range_start {
// There should be at least three items in the range.
if start + 1 < end {
items[end].delim_override =
after_collapse_delim.or(Some("–"));

for item in &mut items[start + 1..end] {
item.hidden = true;
}
// There should be at least three items in the range.
if start + 1 < end {
items[end].delim_override = Some("–");

for item in &mut items[start + 1..end] {
item.hidden = true;
}

*ended_range = true;
}
}

*range_start = None;
};
*range_start = None;
};

for i in 0..cite.items.len() {
let citation_number = {
Expand All @@ -891,7 +905,7 @@ fn collapse_items<'a, T: EntryLike>(cite: &mut SpeculativeCiteRender<'a, '_, T>)
if item.hidden
|| item.rendered.get_meta(ElemMeta::CitationNumber).is_none()
{
end_range(&mut cite.items, &mut range_start);
end_range(&mut cite.items, &mut range_start, &mut ended_range);
continue;
}

Expand All @@ -914,13 +928,13 @@ fn collapse_items<'a, T: EntryLike>(cite: &mut SpeculativeCiteRender<'a, '_, T>)
range_start = Some((start, i));
}
_ => {
end_range(&mut cite.items, &mut range_start);
end_range(&mut cite.items, &mut range_start, &mut ended_range);
range_start = Some((i, i));
}
}
}

end_range(&mut cite.items, &mut range_start);
end_range(&mut cite.items, &mut range_start, &mut ended_range);
}
Some(Collapse::Year | Collapse::YearSuffix | Collapse::YearSuffixRanged) => {
let after_collapse_delim =
Expand Down Expand Up @@ -2883,31 +2897,20 @@ mod tests {
let style = IndependentStyle::from_xml(&style).unwrap();
let mut driver = BibliographyDriver::new();

driver.citation(CitationRequest::new(
vec![
CitationItem::with_entry(bib.get("foia").unwrap()),
CitationItem::with_entry(bib.get("terminator-2").unwrap()),
CitationItem::with_entry(bib.get("oiseau").unwrap()),
CitationItem::with_entry(bib.get("renaissance").unwrap()),
],
&style,
Some(LocaleCode::en_us()),
&en_locale,
None,
));

driver.citation(CitationRequest::new(
vec![
CitationItem::with_entry(bib.get("kinetics").unwrap()),
CitationItem::with_entry(bib.get("house").unwrap()),
CitationItem::with_entry(bib.get("gedanken").unwrap()),
CitationItem::with_entry(bib.get("zygos").unwrap()),
],
&style,
Some(LocaleCode::en_us()),
&en_locale,
None,
));
let mut cite = |keys: &[&str]| {
driver.citation(CitationRequest::new(
keys.iter()
.map(|key| CitationItem::with_entry(bib.get(key).unwrap()))
.collect(),
&style,
Some(LocaleCode::en_us()),
&en_locale,
None,
));
};
cite(&["foia", "terminator-2", "oiseau", "renaissance"]);
cite(&["kinetics", "house", "gedanken", "zygos"]);
cite(&["terminator-2", "oiseau", "house"]);

let rendered = driver.finish(BibliographyRequest::new(
&style,
Expand Down Expand Up @@ -2938,18 +2941,7 @@ mod tests {

println!("{}", rendered.citations[0].citation);
assert_eq!(format!("{:#}", rendered.citations[0].citation), "[1–3; 5]");
assert_eq!(format!("{:#}", rendered.citations[1].citation), "[4; 6–8]");

for cite in rendered.citations {
println!("{}", cite.citation);
}

if let Some(bib) = rendered.bibliography {
for item in bib.items {
println!("{}: {}", item.key, item.content);
}
} else {
println!("no bibliography?");
}
assert_eq!(format!("{:#}", rendered.citations[1].citation), "[4, 6–8]");
assert_eq!(format!("{:#}", rendered.citations[2].citation), "[2, 3, 6]");
}
}
4 changes: 2 additions & 2 deletions styles/numeric.csl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0">
<info>
<title>Numeric</title>
<id>http://typst.org/csl/alphanumeric</id>
<id>http://typst.org/csl/numeric</id>
<author>
<name>Martin Haug</name>
<email>[email protected]</email>
Expand All @@ -13,7 +13,7 @@
</author>
<category citation-format="label" />
<rights>MIT OR Apache-2.0</rights>
<summary>Alphanumeric citations</summary>
<summary>Numeric citations</summary>
</info>
<citation collapse="citation-number" after-collapse-delimiter="; ">
<sort>
Expand Down

0 comments on commit 0587f71

Please sign in to comment.