citation-style-language / schema

Citation Style Language schema
https://citationstyles.org/
MIT License
185 stars 61 forks source link

Collapse multiple child items into one parent item #436

Open Quintus opened 8 months ago

Quintus commented 8 months ago

I open this ticket mostly to elevate the issue described at https://github.com/andras-simonyi/citeproc-el/issues/96 to CSL proper.

Is your feature request related to a problem? Please describe.

I sometimes deal with books containing contributions from multiple authors. I want to write a CSL style which creates only one single bibliography entry for the book, while being able to cite individual entries seperately. For example, let us say there is a liber amicorum for John Doe, edited by William Shakespeare, which contains contributions in form of articles devoted to topics John Doe has concerned himself with over his expansive academic life. These contributions are written by different authors. If I now want to cite two of those articles in a footnote-based style, I want to be able to achieve this:

1. Someone Else, in: William Shakespeare (ed.), liber amicorum for John Doe, 1999, pp. 208-215 (211).
2. Peter Smith, in: Shakespeare (see N. 1), pp. 100-115 (104).

If there is a real bibliography at the end of the article, it should be possible to have only one single bibliographic entry for the liber amicorum:

Shakespeare, William (ed.). liber amicorum for John Doe, 1999. Cited as: Name, in: Shakespeare.

This is currently not possible with CSL, because it requires citations tracking one another.

Describe the solution you'd like

I would like to have a conditional expression in CSL that allows me to check whether the current item is part of a larger work which is only meant to be cited in full once. For instance, my first example might be written like this:

<choose>
    <if collection="parent">
        <choose>
            <!-- First appearance of the parent being cited inline -->
            <if position="first">
                <names variable="editor">
                    <name delimiter="/" form="long"/>
                    <label form="short" prefix=" (" suffix=")"/>
                </names>
                <text variable="title" form="long" prefix=", "/>
                <date variable="issued" date-parts="year" form="text" prefix=", "/>
            </if>
            <else>
              <!-- Subsequent appearance of the parent being cited inline -->
              <names variable="editor">
                  <name delimiter="/" form="short"/>
              </names>
              <text variable="first-reference-note-number" prefix=" (see N." suffix=")"/>
            </else>
        </choose>
    </if>
    <else-if collection="child">
        <!-- Child item cited in footnote -->
        <names variable="author" suffix=", in: ">
            <name delimiter="/" form="short"/>
        </names>
        <text variable="collection-parent" suffix=", "/><!-- ← Renders content from above branch collection='parent' -->
        <label variable="locator" form="short" suffix=" "/>
        <text variable="page" prefix=" "/>
        <text variable="locator" prefix=" (" suffix=")"/>
    </else-if>
</choose>

New here is:

  1. New conditional collection, which either holds parent when the parent is being referenced from within another citation, or child if this is the referencing entry. If it is a standalone item, i.e., neither parent or child, it holds "standalone".
  2. first-reference-note-number notices that it is in a nested citation and refers to the first mention of the nested citation, i.e., the parent.
  3. New variable collection-parent, which triggers the nested rendering of the parent item, i.e. sets the collection conditional to parent-reference.

My second example is more complicated. Writing it could look like this:

<citation>
    <layout delimiter="; " suffix=".">
        <choose>
            <if type="chapter">
                <choose>
                    <if collection="parent">
                        <text term="cited-as" prefix=". " suffix=": " font-style="italic"/>
                        <text term="cited-as-name" suffix=", in: "/>
                        <names variable="editor">
                            <name delimiter="/" form="short"/>
                        </names>
                    </if>
                    <else-if collection="child">
                        <names variable="author" suffix=", in: ">
                            <name delimiter="/" form="short"/>
                        </names>
                        <text variable="collection-parent" suffix=", "/><!-- ← Renders content from above branch collection='parent' -->
                        <label variable="locator" form="short" suffix=" "/>
                        <text variable="page" prefix=" "/>
                        <text variable="locator" prefix=" (" suffix=")"/>
                    </else-if>
                </choose>
            </if>
        </choose>
    </layout>
</citation>
<bibliography>
    <layout>
        <choose>
            <if collection="child">
                <!-- Skip and do not render at all -->
            </if>
            <else>
                <choose>
                    <if type="chapter">
                        <names variable="editor">
                            <name delimiter="/" form="long"/>
                            <label form="short" prefix=" (" suffix=")"/>
                        </names>
                        <text variable="title" form="long" prefix=", "/>
                        <date variable="issued" date-parts="year" form="text" prefix=", "/>

                        <!-- The below should of course match what is formatted
                             in the footnotes... -->
                        <choose>
                            <if collection="parent">
                                <text term="cited-as" prefix=". " suffix=": " font-style="italic"/>
                                <text term="cited-as-name" suffix=", in: "/>
                                <names variable="editor">
                                    <name delimiter="/" form="short"/>
                                </names>
                            </if>
                        </choose>
                    </if>
                </choose>
            </else>
        </choose>
    </layout>
</bibliography>

New here is:

  1. Again, the collection conditional. As shown, it should also be available in the bibliography section.
  2. Again, the collection-parent variable. It has the same function as in the earlier example.
  3. Two new terms are introduced, cited-as (English default: “Cited as“) and cited-as-name (English default: “Name”). The latter is a placeholder to be printed so the reader knows he has to insert an author name here. It might be useful to instead introduce a completely new element <cited-as/> instead of directly requiring term formatting as shown.

Finally, it should be mentioned that implementing this proposal requires changes to CSL-JSON as well, because there needs to be a way to denote which entries are parents and which are children. Biblatex has a simple crossref key that comes quite close to this, even if it is only actually meant for shortcutting. It might be possible to add a key parent to CSL-JSON, which would take a target key and would automatically designate the target as a parent and the source as a child.

Describe alternatives you've considered

There is a container tracking feature in CSL-M using new constructs track-containers, consolidate-containers, first-container-reference-note-number, position="container-subsequent", container-multiple, container-subsequent. I find the CSL-M spec on how they work highly unclear; please refer to the discussion in https://github.com/andras-simonyi/citeproc-el/issues/96 for details.

Even if it somehow was clear, there’s a simple reason for me not to use it. citeproc-el does not implement CSL-M. Additionally, I think this collapsing mechanism is something other styles may find useful as well; I do not think this is something inherently tied to legal citing.

Additional context

This is used for example in the citation styles of:

denismaier commented 7 months ago

As much as I'd love to have a feature like this, we currently don't have the concept of "parent" and "child" items in CSL. Currently, the datamodel is entirely flat. Do you think the proposed solution would work even in that case?

Quintus commented 7 months ago

As much as I'd love to have a feature like this, we currently don't have the concept of "parent" and "child" items in CSL. Currently, the datamodel is entirely flat. Do you think the proposed solution would work even in that case?

With a completely flat data model, it is difficult. One would have to guess which items could be children, which might work or might not work that well. A possible way out would be to construct a virtual parent entry automatically by looking at all items and noticing those which have identical editor/collection-title/date/etc. fields (better have the fields configurable for the user). If a certain global option is set – let’s call it collapse-collections, a CSL processor would honour that and act as outlined in the OP.

That’s off the top of my head. Guessing will always lead to false positives and negatives, but I cannot really judge how grave these deviations will be. There might me tolerably few. On the positive side, the guessing approach would free the user from creating a parent entry in his database and setting relationship fields manually.

bdarcus commented 7 months ago

I'm experimenting with a rewrite of CSL. That does have a more relational input model, so there the container could be represented unambiguously.

The actual configuration would likely just be a simple parameter (since that's the approach in that experiment).

Correct that this kind of pattern would likely only be seen in note-based styles?

denismaier commented 7 months ago

Correct that this kind of pattern would likely only be seen in note-based styles?

It's probably the most common case, but I think I've seen something similar in author date styles already.

bdarcus commented 7 months ago

It's probably the most common case, but I think I've seen something similar in author date styles already.

I can see that.

It doesn't really matter in terms of implementation; just wondering.

Quintus commented 2 months ago

Today I had an idea on this question. Currently I am working around the limitation this issue is supposed to address by simply having the <bibliography> format for the entries in question to be exactly the same, and sorted by editor rather than author. On exporting to the dreaded DOCX, this generates, say, 3 identical bibliography entries if I cited 3 “child” entries of the “parent“ entry. I then manually delete 2 of these identical entries and add manually the statement “cited as: author, in: Doe (ed.)” in the exported DOCX.

I wonder, could CSL not simply automate this rather straightforward process? Thus, could it be extended with an optional identity checker for <biblography> formats? That is, an option, that will a) remove 1:1 identical <bibliography> outputs and instead add a cited as: author, in... statement to the last remaining output? This cited as text should probably be configurable by means of a macro (the styles I work with usually require the word author to be formatted in italic), but I think, such a functionality would cover my need completely without the need to introduce hierarchical entries in CSL.

Quintus commented 2 months ago

Here’s an example from a CSL style I recently wrote for my personal needs: https://redmine.guelker.eu/projects/emacs-jura-tooling/repository/14/revisions/89fcbba3039736278e40d98e31e9274c7c5f9558/entry/csl/dsri.csl#L383

The type legal_commentary (taken from CSL-M and thankfully supported by citeproc-el, which I use a citation processor) is a chapter-alike, that is, refers to a clearly defined section within a larger book. Each of these legal_commentary entries in the literature database contains its own author and chapter entries, as well as further fields (namely editor and title) which are identical across all legal_commentary entries sourcing from the same book. The <bibliography> formatter I linked to ignores all fields which are different and only focuses on the common fields. As a consequence, all legal_commentary entries come out in the bibliography exactly identical so I can manually then process them as outlined in the previous post.

For chapters in a liber amicorum this would work exactly the same, just using the ordinary chapter instead of legal_commentary, hence I do not think this is in any way specific to CSL-M’s extensions.

Quintus commented 2 months ago

Ah, actually there seems to be a tradeoff. The approach only works if the <citation> format, that is, the actual footnotes, do not need to refer to the first occurence of the first “child” entry, that is, if there actually is a bibliography which serves as the main reference point for the “parent” entry. But it gets things 90% there – it does only not work for styles without a <bibliography> that rely on cross-references in footnotes only. Maybe one can imagine some kind of hack to find out where the first citation happened to get first-reference-note-number-alike functionality?

georgd commented 2 months ago

@Quintus I can’t really contribute to your question. But just in case you missed it, you don’t even have to resort to the legal_commentary type. If you use a processor that does CSL-M you can also use consolidate-containers with chapters.

Quintus commented 2 months ago

If you use a processor that does CSL-M you can also use consolidate-containers with chapters.

I use https://github.com/andras-simonyi/citeproc-el, which only partially implements CSL-M; consolidate-containers is not implemented. As far as I understand, the developer of citeproc-el watches this ticket and waits for it to come to a conclusion before he implements something that will be superseded anyway.

denismaier commented 2 months ago

Well, given the speed of CSL development @andras-simonyi could probably implement consolidate-containers for the time being without having to fear that he'll need to reimplement a different solution in the super-near future.

bwiernik commented 2 months ago

If I recall correctly, Jurism/CSLm has a similar container consolidation feature