typst / hayagriva

Rusty bibliography management.
Apache License 2.0
289 stars 44 forks source link

Chapters fail to print using custom CSL style #148

Open ashprice opened 3 months ago

ashprice commented 3 months ago

Hello, I am trying to format a bibliography in typst.

Consider the following biblatex reference:

@incollection{c.r2015,
  title = {The cartography of syntactic structures},
  booktitle = {The {{Oxford}} handbook of linguistic analysis},
  author = {Cinque, Guglielmo and Rizzi, Luigi},
  editor = {Heine, Bernd and Narrog, Heiko},
  date = {2015},
  series = {Oxford handbooks in linguistics},
  edition = {Second edition},
  pages = {51--65},
  publisher = {Oxford University Press},
  location = {New York, NY},
  isbn = {978-0-19-967707-8},
  langid = {english},
  language = {English},
  annotation = {OCLC: ocn908566410}
}

And the following CSL:

<?xml version="1.0" encoding="utf-8"?>
<style class="in-text" version="1.0" and="symbol" et-al-min="5" et-al-use-first="1" initialize="false" initialize-with="" name-as-sort-order="first" demote-non-dropping-particle="never" xmlns="http://purl.org/net/xbiblio/csl">
  <info>
    <title>foobar</title>
    <id>http://www.zotero.org/styles/apa</id>
    <author>
      <name>AMPrice</name>
    </author>
    <updated>2024-03-30T23:11:28+00:00</updated>
    <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
  </info>
  <locale xml:lang="en">
    <terms>
      <term name="editor">
        <single>ed.</single>
        <multiple>eds.</multiple>
      </term>
      <term name="translator">
        <single>trans.</single>
        <multiple>trans.</multiple>
      </term>
    </terms>
  </locale>
  <citation et-al-min="3" et-al-use-first="1" disambiguate-add-year-suffix="true" disambiguate-add-names="true" disambiguate-add-givenname="true" collapse="year" givenname-disambiguation-rule="primary-name-with-initials">
    <layout delimiter="; " prefix="(" suffix=")">
      <group>
        <names variable="author" delimiter=", "/>
      </group>
    </layout>
  </citation>
  <bibliography hanging-indent="true" name-as-sort-order="first" et-al-min="21" et-al-use-first="19" entry-spacing="0" line-spacing="1" and="text" initialize-with=" ">
    <layout>
      <group>
        <choose>
        <if type="chapter" match="any">
            <text value="foofoo"/>
            <names variable="author" delimiter=", " suffix=". ">
              <name/>
            </names>
            <text variable="title"/>
          </if>
        </choose>
      </group>
    </layout>
  </bibliography>
</style>

This will print a blank line:

$ ~/.cargo/bin/hayagriva foo.yaml cite --key c.r2015 --csl new.csl

Its type inside hayagriva (after conversion from a .bib file) is given as anthos, and the parent reference has the type anthology (not sure this is what I would call it, but whatever).

I can get it to print using the CSL by eg. within the CSL, calling all reference types, matching for references that have titles, etc. But I cannot call it by type="chapter", while this should be possible, and such works using other tools that use CSL.

Not sure if this is a bug, or if I am making a mistake. Thank you for any help & let me know what further info I can provide.

ashprice commented 3 months ago

OK, I don't know if this is a preferred solution but I tracked down the issue. Anthos isn't given the CSL type for chapter, as I suspected. Still not sure I really understand 'what' is happening there, I don't know rust (although I wish to learn) and I am a relative beginner at all things code.

A fix, whether hacky or not, is to simply use the selector to select anthos and make it into a chapter for CSL. See the commit here: https://github.com/ashprice/hayagriva/commit/49d88b2d37d1e9b72e115bd675ccaaf87bee4101

diff --git a/src/csl/taxonomy.rs b/src/csl/taxonomy.rs
index c691ed3..e3108b7 100644
--- a/src/csl/taxonomy.rs
+++ b/src/csl/taxonomy.rs
@@ -564,7 +564,8 @@ impl EntryLike for Entry {
                 !(is_periodical || is_collection)
             }
             Kind::Chapter => {
-                select!(Chapter > (Book | Anthology | Proceedings)).matches(self)
+                select!((Chapter | Anthos) > (Book | Anthology | Proceedings))
+                    .matches(self)
             }
             Kind::Entry | Kind::EntryDictionary | Kind::EntryEncyclopedia => {
                 if kind == Kind::EntryDictionary {

I can make this into a PR, but I am not sure that this is the preferred way to deal with this. FWIW, we are dealing here with a regular book that contains a series of chapters with different authors, I am not quite sure I would call that an anthology to begin with, but I am guessing that the type exists to differentiate it from chapters with the same authors...