typst / typst

A new markup-based typesetting system that is powerful and easy to learn.
https://typst.app
Apache License 2.0
34.9k stars 928 forks source link

Allow `cite` to collect multiple entries to a range. #1713

Closed ModProg closed 1 year ago

ModProg commented 1 year ago

Description

If there are multiple references for some topic, it could make sense instead of listing them all to specify a range in the citation, when using the numeric style.

The links in such a joined citation [1 - 4, 7 – 10, 22] should go to the numbers shown, i.e. to 1, 4, 7,10, and22` respectively.

Use Case

Given a bib:

a: #...
b: #...
#...
f: #...

when a user specifies #cite("a", "b", "c", "f") this could expand to [1-3, 6], assuming all entries were referenced in order prior.

bluebear94 commented 1 year ago

Would this also apply if the entries were referenced in a different order such as #cite("a", "f", "c", "b")?

ModProg commented 1 year ago

Would this also apply if the entries were referenced in a different order such as #cite("a", "f", "c", "b")?

that is a good question, it mainly depends on their order in the bibliography, as that needs to match in order to even have consecutive numbers. Not sure if the order in the cite should be enforced or if resorting could be applied when useful.

bluebear94 commented 1 year ago

I don’t want to have to sort the cite entries manually by the order in which they would appear in the bibliography. I’d rather have the entries sorted by reference number by default in styles that use them.

bluebear94 commented 1 year ago

hayagriva is capable of formatting citations for multiple entries at a time, but Typst only passes one entry cited to each call of Database::citation. I’ll have to look more into it.

NuraliMedeu commented 1 year ago

Is it possible to define custom rules or functions to show 3 or more consecutive citations in a range with an en-dash? For instance, #cite("two", "three", "four") would be rendered as [2]–[4].

Edit: I created a janky temporary solution:

#let cite_multi(first, ..middle, last) = {
  cite(first)
  box(
    width: 0pt,
    text(fill: white, cite(..middle))
  )
  "\u{2013}"
  cite(last)
}

The main problem with this is that the middle citations are still clickable and highlightable when copying the text despite being invisible. Please let me know how to improve this.

reknih commented 1 year ago

Typst 0.9.0 now merges adjacent cites if the CSL style requests it.