How can I configure linking and color in my bibliography?

Dear everyone,

I’d like to render my bibilography in such a way that the text describing an article in a journal is rendered as an hyperlink to its DOI and the text is in blue.
As far as I understand (with my limited knowledge), this is not possible to encode in a CSL file (no hyperlink, no color), so maybe we can tune that from typst ?

Hello,
If you have an example of what you wish to achieve, I think it would be clearer what you have in mind!
Do you want the whole bibliography entry to be a hyperlink?

Hello
Thanks for the answer ! Here’s a screenshot of what I mean :

I’d like the bibliogrphy to be as above, with the journal name & ref in blue being an hyperlink to its DOI (in this case https://doi.org/10.1088/1126-6708/2007/09/126) . Additionnaly the arxiv ID, if present, is also displayed as a link (but I guess this would not be more difficult than displaying a link for the journal name)

2 Likes

I’d be interested in this too

If you only want the URL highlighted, you can do following:

#show bibliography: it => {
  show link: set text(blue)
  show link: underline
  it
}

I’m not sure if there is a better solution, but this one does the job pretty well :)


If the respective elements are linked (which I think is configured in the citation style language files), the links are automatically highlighted and underlined!

1 Like

The arXiv link is easier, since all the information are already there and it has a known format, so a simple regex show-rule is sufficient:

#show bibliography: it => {
  let arxiv-magic = regex("arXiv: ((\d+\.\d+) \[.*\])")
  show arxiv-magic: it => {
    show link: set text(fill: blue)
    let (text, arxiv-id) = it.text.matches(arxiv-magic).first().captures
    "arXiv: " + link("https://arxiv.org/abs/" + arxiv-id, text)
  }
}

grafik


The journal link is trickier. It’s a bit hacky, but you can adjust the CSL style to add some “magic” prefixes and suffixes, which you can find and transform into the desired link with a regex show-rule.

For example this modified CSL snipped

<group delimiter=" " prefix="<<<" suffix=">>>">
    <text variable="URL" suffix="|||"/>
    <text variable="container-title-short"/>
    <text variable="issue" />
    <text variable="volume" prefix="(" suffix=")"/>
    <text variable="page"/>
</group>

would produce something like this:
grafik

Then using this show rule

#show bibliography: it => {
  // first show rule transforms the original link
  // into plain text, so we can match it with a regex
  show link: it => {
    if it.body.text == it.dest { // apply only to original link
      it.body
    } else {
      it
    }
  }
  // second show rule matches the magic prefixes and suffixes ...
  let link-magic = regex("<<<(.*)\|\|\|\s*(.*)>>>")
  show link-magic: it => {
    // ... and renders it as a custom link
    set text(fill: blue)
    link(..it.text.matches(link-magic).first().captures)
  }
  it
}

You get:
grafik


Here is the full reproducible example:

main.typ

#show bibliography: it => {
  // this show rule transforms the original link
  // into plain text, so we can match it with a regex
  show link: it => {
    if it.body.text == it.dest { // link before processing
      it.body
    } else {
      it
    }
  }
  // this show rule matches the magic prefixes and suffixes ...
  let link-magic = regex("<<<(.*)\|\|\|\s*(.*)>>>")
  show link-magic: it => {
    // ... and renders it as a custom link
    set text(fill: blue)
    link(..it.text.matches(link-magic).first().captures)
  }
  it
}


#bibliography("literature.bib", style: "style_mod.csl", full: true)

style_mod.csl

<?xml version="1.0" encoding="utf-8"?>
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0">
  <info>
    <title>Example Style</title>
    <id>http://www.zotero.org/styles/example</id>
  </info>
  
  <citation>
    <sort>
      <key variable="citation-number"/>
    </sort>
    <layout delimiter=", ">
      <group prefix="[" suffix="]" delimiter=", ">
        <text variable="citation-number"/>
        <text macro="citation-locator"/>
      </group>
    </layout>
  </citation>
  
  <bibliography second-field-align="flush">
    <layout suffix=".">
      <text variable="citation-number" prefix="[" suffix="]"/>
      <group delimiter=", &#10;">
        <names variable="author">
          <name initialize-with="."/>
        </names>
        <text variable="title" font-style="italic"/>
        <group delimiter=" " prefix="<<<" suffix=">>>">
          <text variable="URL" suffix="|||"/>
          <text variable="container-title-short"/>
          <text variable="issue" />
          <text variable="volume" prefix="(" suffix=")"/>
          <text variable="page"/>
        </group>
      </group>
    </layout>
  </bibliography>
</style>

literature.bib

@article{Frixione_2007,
  doi = {10.1088/1126-6708/2007/09/126},
  url = {https://dx.doi.org/10.1088/1126-6708/2007/09/126},
  year = {2007},
  month = {sep},
  publisher = {},
  volume = {2007},
  number = {09},
  pages = {126},
  author = {Stefano Frixione and Giovanni Ridolfi and Paolo Nason},
  title = {A positive-weight next-to-leading-order Monte Carlo for heavy flavour hadroproduction},
  journal = {Journal of High Energy Physics},
  archivePrefix = {arXiv},
  eprint = {0707.3088},
  primaryClass = {hep-ph},
}

The first show rule is required, because normally regex show rules don’t match across different element types, so we need to remove the link typst automatically adds to the URL first by turning it into plain text.

1 Like

Thanks ! I’ll give it a try !

Hi @Philipp, thanks a lot for this! I just asked about something very similar in another thread, and your solution is very useful for me.

However, it doesn’t seem to work if the content to the right of the ||| has formatting (e.g. add font-style="italic" to the container-title-short field in your CSL). The regex does not match in this case. Do you have thoughts on how one might fix this?

Well, just remove the font-style from the CSL? You can easily add it back in the show rule.

Cool idea, but the CSL for my scientific community uses different font styles for different publication types; e.g. titles are set in italics for books, but not in italics for inproceedings.

I suppose I could put more magic markers into the CSL that could be expanded to italics through a regex show rule, but I’m trying to build a solution that works across many CSL files with minimal CSL changes, so that doesn’t seem like an appealing solution. (This is for blinky.)

Are we stuck with not being able to match formatted content against a regex?

I don’t see how an italic title would interfere with the journal/volume/year information this post is about. However, as far as I know it’s indeed not possible to match a regex over differently formatted content using show rules. Vote here if you want this to be supported: Allow regex to match across styled content · Issue #6076 · typst/typst · GitHub

1 Like