Conversation
|
Curvenote Preview
|
fwkoch
left a comment
There was a problem hiding this comment.
Overall, the approach to citations defined in this RFC is great.
Regarding your open questions, I already addressed the Reference node naming.
For CiTO vocabulary, there are ~100 existing intents - this is so many but also narrowing to a subset feels a little arbitrary. I'm inclined to allow all CiTO intents; they are just descriptive strings that help readers understand and follow citations. I don't see big differences in behavior between different intents.
For ORCID, I agree inclusion is useful, and there isn't an exceptionally slick solution. My immediate thought is to allow oxa metadata on the Reference, alongside csl. This would be structured identically to article metadata, so we are not adding a new schema for OXA renderers. Ideally a citation would include full csl and full oxa representation, but it could also have only one or the other or partial versions of each... (I think this is close to your "separate mapping" suggestion.)
| prefix?: [Inline]; | ||
| suffix?: [Inline]; | ||
| display?: 'author' | 'date' | 'full'; | ||
| locator?: string; |
There was a problem hiding this comment.
| locator?: string; | |
| locator?:[Inline]; |
locator is for human-readable display text. This feels equivalent to prefix/suffix (as opposed to fields like xref/intent/url which only work as strings).
There was a problem hiding this comment.
I'm not sure I agree with this. If locator is [Inline] then I'm not sure if provides much value over prefix and suffix. For example, if I want to cite the second chapter of Jones, 1980 should I put "chap. 2" in the locator or in suffix.
locator only feels useful if it is explicitly not presentational and points to specific place in the cited work.
I'd err towards not adding it at this stage and use the "promote from data" principle if necessary.
| children?: [Inline]; | ||
| prefix?: [Inline]; | ||
| suffix?: [Inline]; | ||
| display?: 'author' | 'date' | 'full'; |
There was a problem hiding this comment.
Two concerns with display field.
First, the description of this field states default (i.e. no display) behavior falls back to default rendering, either author-date or number. I propose implicit behavior should have an explicit counterpart, i.e. leaving display off is the same as using display: 'author-date', as suggested above.
| display?: 'author' | 'date' | 'full'; | |
| display?: 'author' | 'date' | 'full' | 'author-date'; |
| - `'author'` — abbreviated author only, e.g. "Jones et al." (equivalent to natbib `\citeauthor`, CSL `author-only`) | ||
| - `'date'` — date only, e.g. "1990" (equivalent to natbib `\citeyear`, CSL `suppress-author`) | ||
| - `'full'` — display the full bibliographic reference inline, as it would appear in a reference list; useful for first-mention expansions or in-body reference rendering without requiring the reader to navigate to the bibliography | ||
| - If omitted, the default citation rendering applies — `author-date` (e.g. "Jones et al., 1990" or "Jones et al. (2022)" depending on narrative/parenthetical context), or numeric (e.g. "[1]") depending on the citation style of the renderer. |
There was a problem hiding this comment.
Second, maybe less of a concern, but a point that should be emphasized:
We are relying on the renderer to understand and respect the intricacies of the OXA spec. Now, I would assume most "numeric" citation renderers to just see a cite node and replace it with the number. This doesn't work for author/date citation kinds.
e.g. for something like:
{type: Cite, kind: author} stated one fact in {type: Cite, kind: date}; {type: Cite, kind: undefined} disagreed.
authors would need to rely on their content getting rendered like so:
_Koch_ stated one fact in _2026_; [2] disagreed
rather than the lazier:
[1] stated one fact in [1]; [2] disagreed
Is this our expectation? Setting the bar higher for everyone involved?
(I think the alternative is to put the burden entirely on the authors to understand how their content will be rendered and adjust the wording and citation structure accordingly.)
There was a problem hiding this comment.
This is a good point. Along similar lines, in practice I've found there are plenty of edge cases where authors want to fully customize the text of their inline citations, or perhaps more urgently in the short term, where JATS imports use <mixed-citation> and so the xref contents can't be predictably rendered from the reference without trying to parse it as a string, with all of the attendant issues. I don't love building "custom" escape hatches into standards, as allowing it causes problems with downstream processing and rendering, but we may still want to consider the possibility. CSL partly discusses this limitation here, which offers an okay workaround for most use-cases, but not all. Note, too, the discussion of issues with legal citations, which are not a target for OXA, but I can imagine similar citation styles promulgating in science if we're successful in breaking down the article into more referencable components.
I don't know that there's a particularly good solution here — I've often thought if you want to do weird things with citations, you should build on top of generic links the way epub does, rather than having specific citations. But that's another discussion.
Ah, I see this is covered in children, below!
|
|
||
| Using inline arrays for `children`, `prefix`, and `suffix` (rather than plain strings) allows rich formatting — for example, italicized titles or emphasized author names within citation text. | ||
|
|
||
| `Cite` is an inline node and can appear directly within a `Paragraph` or other inline container. A standalone `Cite` node (not wrapped in a `CiteGroup`) represents a **narrative** citation — one that is grammatically part of the sentence (equivalent to `\citet` in natbib or a bare `@key` in Pandoc). |
There was a problem hiding this comment.
A standalone Cite node is completely equivalent to a narrative CiteGroup with a single Cite child. It feels a little bad to have two different ways to do the same thing, but I think the only way to avoid that is to require Cite nodes to only exist inside CiteGroups. This gives us consistency but extra boilerplate for the simplest case.
My personal preference is consistency, i.e. always require a CiteGroup. This also makes narrative vs. parenthetical always explicit (since those are only defined on CiteGroup).
|
|
||
| #### Why `kind` Over Boolean Flags | ||
|
|
||
| Using `kind: 'narrative' | 'parenthetical'` rather than `parenthetical: boolean` allows for future extension. Additional citation styles may be introduced (e.g. `'numeric'`, `'note'`) without breaking the existing schema. The nomenclature follows established citation-studies terminology. |
There was a problem hiding this comment.
Regarding note - it's probably worth a small peek ahead to how OXA may handle footnotes.
In JATS, citations use xref -> ref structures, where xref has a specific @xref-type and ref is differentiated by the content it holds (e.g. mixed-citation). There is also note which is an element for non-citation content in a bibliographic ref (JATS best practice is to avoid using this element - https://jats.nlm.nih.gov/archiving/tag-library/1.4/element/note.html). Finally, there are fn footnotes. These use the same xref node in the text, but have a different @xref-type and point to fn nodes in a fn-group.
I like the proposal that Cite will extend a more-generic, not-yet-defined CrossReference node. I think Footnote will be defined similarly, as another extension of CrossReference? Then, there will also be the node type these xref fields point to (FootnoteDefinition or something).
|
|
||
| ```typescript | ||
| interface Reference extends Parent { | ||
| type: 'Reference'; |
There was a problem hiding this comment.
Naming for this node is challenging. In isolation, "Reference" makes sense - these are the article's references.
However, in the context of other nodes, it gets muddy: CrossReferences "reference" other nodes, but CiteGroup "references" a "Reference" ...
When things get hairy like this, I'm always inclined to introduce patterns that make node types more verbose but make relationships clearer. For example, if we extend the thinking to generic xrefs, citations, and footnotes, we could have:
In-line reference -> block-level target
---------------------------------------
CrossReference -> <any node>
CiteReference -> CiteDefinition
FootnoteReference -> FootnoteDefinition
Or maybe just Cite and Footnote for the in-line nodes.
All that said, I'm also perfectly fine declaring that "Reference" (capitalized noun) is this specific node type, regardless of how much we use the verb "reference" elsewhere. However - if we do leave this as Reference, we need to consider the footnote case... is it just FootnoteDefinition and we don't worry about similar naming conventions for these similar nodes?
There was a problem hiding this comment.
Right on. These conventions confuse me to this day, and I agree that it's worth paying some attention to them and deciding if we want to break convention to make it easier for, in particular, developers from outside of academia, to onboard onto these standards and work with folks with academic backgrounds.
My understanding is in vernacular language used by most researchers, the inline node for a citation (e.g. [1] or (Koch, 2026)) is referred to as a "citation." The block node it points to (e.g. Koch, F.W. "Naming for this node is challenging." OXA RFC 5. March 26, 2026. https://github.com/oxa-dev/rfc/pull/5/.) is referred to as a "reference." At the same time, "citation" is also used to describe the effect of having referenced another work, independent of how many times it appears as an inline node in a document. Meanwhile, the inline node for a footnote, almost always rendered as superscript, does not seem to have a formal name! And, of course, the block node it references is simply called a "footnote."
Given the vernacular use of "reference," I don't know that CiteReference or FootnoteReference is appropriate, which is why most tools I'm aware of use simply Cite and Footnote as the node names, as you suggest. But I agree this is also confusing, because "footnote" is the vernacular word for the referenced block element, not the inline element!
I don't have a good proposal for solving this, and agree we could just go with convention. Another stray thought is to use abbreviations to completely disambiguate from the vernacular (although CrossRef breaks this bc ugggggh, but ignore that for now), so, e.g.:
In-line reference -> block-level target
---------------------------------------
CrossRef -> <any node>
CiteRef -> CiteDef
FootnoteRef -> FootnoteDef
¯_(ツ)_/¯
| **Fields:** | ||
|
|
||
| - `identifier` — the unique key used by `Cite` nodes via `xref` to reference this entry (e.g. `"jones2022"`). The node's `identifier` MUST match the `citation-key` field in the `csl` object. | ||
| - `children` — optional inline content for the rendered display of this reference (e.g. `[{ type: 'Text', value: '1' }]` for numeric styles, or formatted author-year text); if omitted, renderers generate display text from `csl` |
There was a problem hiding this comment.
I'm a little confused by children: There's the rendered representation of the entire Reference (i.e. text in the reference list) and there's the short representation when it is referenced by Cite.
Here, "inline content" implies we are talking about the latter case? However, don't Cite nodes themselves define inline rendering? Is Reference.children just another fallback if Cite.display and Cite.children are both undefined and the renderer is unopinionated? I feel like the Reference should not concern itself with inline rendering.
However, maybe my understanding is wrong and children refers to the representation of the full reference. In that case, I understand and agree; we just need to change the wording here.
There was a problem hiding this comment.
Agreed — a little confused if the intent here is, like Cite children, to replace rendered representations, or to add to them to add e.g. notes to the reference.
| - `children` — optional inline content for the rendered display of this reference (e.g. `[{ type: 'Text', value: '1' }]` for numeric styles, or formatted author-year text); if omitted, renderers generate display text from `csl` | ||
| - `csl` — a single CSL-JSON item object conforming to the [CSL-JSON schema](https://resource.citationstyles.org/schema/v1.0/input/json/csl-data.json). This is a well-established, widely-supported standard for representing bibliographic data, used by Zotero, Mendeley, Pandoc, Typst, CrossRef, and most citation-processing tools. | ||
|
|
||
| #### CSL-JSON |
|
|
||
| The node's `identifier` and the CSL item's `citation-key` MUST be kept in sync; they are the shared key that connects `Cite` nodes (via `xref`) to their bibliographic data. | ||
|
|
||
| `Reference` nodes are typically collected in a reference list at the end of a document, analogous to the `<ref-list>` in JATS or a bibliography section in LaTeX. This RFC does not describe where these are collected or placed in a document similar to JATS `<back>` section; that may be introduced in a future RFC. |
There was a problem hiding this comment.
👍 I agree we need not prescribe a collection where References are listed. They are simply block-level content that can be handled at render time, in whatever manner is appropriate for the context.
| kind: 'parenthetical', | ||
| children: | ||
| [ | ||
| { type: 'Cite', xref: 'jones2022', prefix: [{ type: 'Text', value: 'see ' }] }, |
There was a problem hiding this comment.
I wonder if there's any benefit to prefix/suffix at the CiteGroup level... The prefix in this example "see" refers to both citations in the group. I think this is probably overcomplexity, and prefix/suffix on Cite only is fine.
There was a problem hiding this comment.
Similarly, do we need the ability to specify the separator for a CiteGroup, or is a semicolon always sufficient?
There was a problem hiding this comment.
I treat the separator as an aspect of the citation style, not a property of the CiteGroup. For instance a group can be rendered by one style as "A, Y, Z" and another style numerically as "1-3".
|
|
||
| **Fields:** | ||
|
|
||
| - `xref` — reference to the `identifier` of a `Reference` node (e.g. `"jones2022"`). A `Reference` node with a matching `identifier` MUST be present in the containing document. |
There was a problem hiding this comment.
This may be out of scope for OXA, but requiring the identifier to be in the containing document may preclude supporting endnotes in the way they're often used in books and other multi-document works. E.g., in epub3 you can use the <a> tag to cite an element in another document, such as citing a work in chapter-1.html for which the reference only appears in a global references.html. Granted, this is not a full citation/reference specification, it's just extending the HTML a tag. But it is quite useful in practice. The proposed locator property seems to point to this possibility, but this rule would preclude actually allowing it.
https://help.apple.com/itc/booksassetguide/en.lproj/itccf8ecf5c8.html
This also allows an author to cite a work multiple times throughout a multi-document work while only needing to reference it once in a bibliography or endnote.
This also brings to mind the inverse case, somewhat more common in humanities, where a work is only cited in the reference list as a general reference (often with additional commentary), but is not specifically cited in the text. Do we think OXA should support that case?
|
|
||
| ## Relationship to Cross-References | ||
|
|
||
| OXA nodes can carry an `identifier`, and any node that points to another node uses `xref` to do so. `Cite` uses `xref` just like any other referencing node would — the mechanism is intended to be shared, but citations carry additional semantics that justify a distinct node type: |
There was a problem hiding this comment.
This is probably right, and yet I think it's worth at least asking whether we should consider instead extending a generic reference tag with a role or type attribute, similar to epub3's epub:type="noteref".
The philosophical thought here is that in a world where we want to be considering allowing researchers to cite and annotate content far more granularly than traditional citations, do we want to continue to privilege citations with their own tag? And for that matter, do we want to differentiate between internal and external references given our desire to build OXA for remixing of content and, in some sense, break the distinction between "internal" and "external" in the first place?
Again, I think this is probably the right approach for all the reasons mentioned below, as well as making implementations easier by avoiding polymorphism, improving human readability, and, well, the fact that HTML has never been able to develop a standardized approach to citations/references/footnotes despite or perhaps due to the flexibility of the a tag.
But I think it's worth at least examining this assumption while we have the opportunity to.
gabestein
left a comment
There was a problem hiding this comment.
This is a really solid approach! As noted in inline comments, I think it's worth taking a little time to make sure we want to follow some existing conventions given the behavioral changes we're looking to make, but the justifications for doing so do make sense.
On open questions:
- Reference node names: I added some thoughts about reference nodes as an extension of @fwkoch's comment in https://github.com/oxa-dev/rfc/pull/5/changes#r2993194496
- CiTO vocabulary: keeping it open makes the most sense to me. My guess is conventions will arise fairly naturally in specific communities that will (mostly) resolve interop concerns.
- ORCID and extended author metadata: I like the idea of extending csl-json rather than adding additional complexity. Per the docs, arbitrary fields simply won't be passed to the processor, so we'll have no issues with validation for folks using CSL toolkits downstream, but oxa renderers can choose to parse those fields. One thought: we could do as citation.js does and prepend non-conforming fields with an underscore to signal that they're extensions. (e.g. _orcid:
https://orcid.org/1234-1234-1234-1234X).
nokome
left a comment
There was a problem hiding this comment.
Good work Rowan and Franklin. I appreciated the detail, including things like the "Natbib Command Coverage" section.
My main concern is around the Cite.display and CiteGroup.kind properties and their defaults. In Stencila, we have taken a different approach, largely inspired by Pandoc: a Citation (Cite equivalent) defaults to a citationMode: Parenthetical and citationMode is ignored when a part of a CitationGroup. This makes it easy to represent a single parenthetical citation (where parenthetical includes bracketed and superscripted numbers depending on the style), one of the most common cases, whilst still allowing for the other cases here.
I think it is probably worth doing an analysis of the pros and cons of the alternative data models for different use cases. e.g. in the "Natbib Command Coverage" table adding another column and expanding both to full JSON
| Defines three OXA node types for scholarly citations: `Cite` (an inline reference to a bibliographic entry), `CiteGroup` (a container that groups multiple Cite nodes with shared display semantics), and `Reference` (a block-level bibliographic record). | ||
| --- | ||
|
|
||
| This RFC introduces three node types (`Cite`, `CiteGroup`, and `Reference`) for representing citations and bibliographic references in OXA documents. Citations are fundamental to scientific and technical writing and require careful structural treatment; they are not simple cross-references and can carry rich metadata about _how_ and _why_ a source is being cited. |
There was a problem hiding this comment.
Regarding naming, in case it helps, I'll share what we ended up with in Stencila Schema:
-
Citation: was namedCitealso, but that became increasingly confusing, particularly when we started using graph database queries andcitesbecame a relation. Pandoc also uses the nameCitation. -
CitationGroup: was namedCiteGroupalso, but changed when we changed toCitation. -
Reference: same as here.
I'm still happy with these names. I feel it is better to stick with nouns for node types where possible - it reduces confusion.
| prefix?: [Inline]; | ||
| suffix?: [Inline]; | ||
| display?: 'author' | 'date' | 'full'; | ||
| locator?: string; |
There was a problem hiding this comment.
I'm not sure I agree with this. If locator is [Inline] then I'm not sure if provides much value over prefix and suffix. For example, if I want to cite the second chapter of Jones, 1980 should I put "chap. 2" in the locator or in suffix.
locator only feels useful if it is explicitly not presentational and points to specific place in the cited work.
I'd err towards not adding it at this stage and use the "promote from data" principle if necessary.
| display?: 'author' | 'date' | 'full'; | ||
| locator?: string; | ||
| url?: string; | ||
| intent?: string; |
There was a problem hiding this comment.
I suggest we make intent and enum, currently the CiTO vocabulary.
| ```typescript | ||
| interface CiteGroup extends Parent { | ||
| type: 'CiteGroup'; | ||
| kind: 'narrative' | 'parenthetical'; |
There was a problem hiding this comment.
I found having this here a little surprising because i can't think of a use case for a CiteGroup with kind: narrative. This relates to Franklin's comment above I think (having to use a CiteGroup with a single Cite to get a citation with parentheses).
In Stencila Schema, we follow Pandoc and define a CitationMode enum with:
Parenthetical(default)NarrativeNarrativeAuthorNarrativeYear
So this enum is combining CiteGroup.kind and Cite.display in one enumeration on the equivalent of Cite, not CiteGroup. I have found that this has worked fine for both parsing and rendering purposes across a number of citation styles and avoids having to wrap a Cite in a CiteGroup to have in parenthesized.
| - `'parenthetical'` — the entire citation appears in parentheses (equivalent to `\citep` in natbib) | ||
| - `children` — one or more `Cite` nodes | ||
|
|
||
| `CiteGroup` is never directly authored in markup — it is the structural result of parsing grouped citation syntax (e.g. `[@key1; @key2]` in Pandoc or `` \citep{key1,key2}` `` in LaTeX). The group holds the shared context (parenthetical vs. narrative) while each child `Cite` retains its own prefix, suffix, and identifier. |
There was a problem hiding this comment.
I am not sure "never directly authored in markup" is true, or at least, needs to be true. Certainly, Pandoc and JATS, don't have the notion of a CiteGroup but then you get the awkward situation of the brackets and semicolon in [@key1; @key2] becoming part of the content which then makes it hard to say render citations using a different citation style e.g. superscripted number ranges.
I have been transforming adjacent Cite nodes into a CiteGroup and discarding those brackets and separators. But that is just a workaround for the ingested markup not having a syntactic representation of a group of citations.
|
|
||
| `CiteGroup` is never directly authored in markup — it is the structural result of parsing grouped citation syntax (e.g. `[@key1; @key2]` in Pandoc or `` \citep{key1,key2}` `` in LaTeX). The group holds the shared context (parenthetical vs. narrative) while each child `Cite` retains its own prefix, suffix, and identifier. | ||
|
|
||
| This separation is important for UIs: a parenthetical group like `(Jones, 2020; Smith, 2021)` can be rendered as a single parenthesized string _or_ expanded into an interactive list showing each reference with its metadata (such as a hover reference). The display of these can also be shortened by the renderer, for example, `(Jones et al., 1990, 1991)` or `(Jones et al., 1990a,b)`, at the discretion of the rendering engine. |
There was a problem hiding this comment.
| This separation is important for UIs: a parenthetical group like `(Jones, 2020; Smith, 2021)` can be rendered as a single parenthesized string _or_ expanded into an interactive list showing each reference with its metadata (such as a hover reference). The display of these can also be shortened by the renderer, for example, `(Jones et al., 1990, 1991)` or `(Jones et al., 1990a,b)`, at the discretion of the rendering engine. | |
| This separation is important for UIs: a parenthetical group like `(Jones, 2020; Smith, 2021)` can be rendered as a single parenthesized string _or_ expanded into an interactive list showing each reference with its metadata (such as a hover reference). The display of these can also be shortened by the renderer, for example, `(Jones et al., 1990a, 1990b)` or `(Jones et al., 1990a,b)`, at the discretion of the rendering engine. |
| **Fields:** | ||
|
|
||
| - `identifier` — the unique key used by `Cite` nodes via `xref` to reference this entry (e.g. `"jones2022"`). The node's `identifier` MUST match the `citation-key` field in the `csl` object. | ||
| - `children` — optional inline content for the rendered display of this reference (e.g. `[{ type: 'Text', value: '1' }]` for numeric styles, or formatted author-year text); if omitted, renderers generate display text from `csl` |
There was a problem hiding this comment.
| - `children` — optional inline content for the rendered display of this reference (e.g. `[{ type: 'Text', value: '1' }]` for numeric styles, or formatted author-year text); if omitted, renderers generate display text from `csl` | |
| - `children` — optional inline content for the rendered display of this reference (e.g. "Jones (1980). An analysis of.."; if omitted, renderers generate display text from `csl` |
| kind: 'parenthetical', | ||
| children: | ||
| [ | ||
| { type: 'Cite', xref: 'jones2022', prefix: [{ type: 'Text', value: 'see ' }] }, |
There was a problem hiding this comment.
I treat the separator as an aspect of the citation style, not a property of the CiteGroup. For instance a group can be rendered by one style as "A, Y, Z" and another style numerically as "1-3".
Introduces citation node types.
Some open questions on this:
Referencethe best name, or should it beBibliographicEntry,CitationRecord, or something closer to schema.org'sCreativeWork?Referenceis concise and maps naturally to JATS<ref>, but could be confused with general cross-references in some contexts.xrefas a initial conventionorcid. Should ORCIDs and similar identifiers be stored in a separate mapping outside thecslobject, or should they be added to the CSL name objects as extensions?