Skip to content

feat: improve citation formatting with publication object - #51

Open
maxulysse wants to merge 25 commits into
mainfrom
feat/citation-formatting-improvements
Open

maxulysse wants to merge 25 commits into
mainfrom
feat/citation-formatting-improvements

Conversation

@maxulysse

@maxulysse maxulysse commented Jun 18, 2026

Copy link
Copy Markdown
Member

Summary

Updates citation utilities to read from a nested publication object in meta.yml tool entries, aligning with the new meta-schema.json structure being added in nf-core/modules#12129 and used in nf-core/seqinspector#241

New meta.yml structure

tools:
  - samtools:
      doi: "10.1093/bioinformatics/btp352"
      homepage: "https://www.htslib.org/"
      publication:
        author: "Li H, et al."
        year: 2009
        title: "The Sequence Alignment/Map format and SAMtools"
        source: "Bioinformatics"

Changes

  • formatBibliographyFromData() — reads author, year, title, source from citationData.publication
  • shortReference() — reads author, year from info.publication
  • Renamed journal field to source (covers journals, conferences, workshops, preprints)
  • Updated all tests, validation meta.yml files, and documentation

Related PRs

- Always use 'Surname et al.' format for author names
- Link short citations to DOI when available
Revert shortAuthor to original behavior (only add 'et al.' for multiple
authors). Keep the DOI linking improvement in formatShortCitation.
- Add comma before year: 'Andrews, 2010' instead of 'Andrews 2010'
- Wrap 'et al.' in <em> tag for italics: 'Danecek <em>et al.</em>, 2021'
- Link short citations to DOI when available
- Year in parentheses: '(2021)' instead of '2021'
- DOI as link: doi: <a href='https://doi.org/...'>DOI</a>
- Remove tool name fallback when no citation data
- Use shared formatBibliographyFromData in generateModuleToolCitation
For tools without DOI, bibliography now shows: tool name. title. url
Version bump to 0.6.0 will be done in a separate release PR.
Comment thread src/main/groovy/nfcore/plugin/nfcore/NfcoreCitationUtils.groovy Outdated
Comment thread src/main/groovy/nfcore/plugin/nfcore/NfcoreCitationUtils.groovy Outdated
@maxulysse

Copy link
Copy Markdown
Member Author

Happy enough with current state, I need to talk back to team infrastructure about the structure of the meta.yml file before going forward.

@maxulysse

Copy link
Copy Markdown
Member Author

It gives me this in seqinspector, with some addition in the meta.yml files:

Screenshot from 2026-06-22 10-42-28

@nvnieuwk nvnieuwk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

Update NfcoreCitationUtils to read citation fields from a nested
publication object in meta.yml tool entries instead of flat fields.

Changes:
- formatBibliographyFromData reads author/year/title/source from publication
- shortReference reads author/year from publication
- Renamed journal field to source
- Updated tests, validation meta.yml files, and documentation
@maxulysse maxulysse changed the title feat: improve citation formatting feat: improve citation formatting with publication object Jun 22, 2026
Comment thread build.gradle Outdated

@edmundmiller edmundmiller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs changes — a couple of correctness issues worth addressing before merge.

Blocking

1. formatBibliographyFromData() drops the tool name fallback — bibliography entries become unidentifiable

Old code (removed in this diff):

def title = citationData.title ?: toolName   // toolName fallback

New code:

def title = pub.title ?: ""                   // no fallback

For any tool that carries only doi + homepage and no publication block (every module that hasn't been migrated yet), the bibliography entry becomes:

<li>doi: <a href='https://doi.org/…'></a>.</li>

There is no indication of which tool this refers to. The topic-channel-citations snapshot confirms the regression — the old snapshot had <li>samtools. doi: …</li>, the new one drops samtools entirely. A minimal fix is to restore the toolName fallback in the no-publication branch:

def title = pub.title ?: (doi ? toolName : "")

so DOI-only entries still read samtools. doi: ….

2. Silent backward-incompatibility with existing flat-field meta.yml files

shortReference() and formatBibliographyFromData() now read exclusively from citationData.publication. Modules still using the old flat fields (author, year, title, journal) — the current state of nearly all nf-core modules until nf-core/modules#12129 lands and propagates — will silently produce author-less, year-less citations with no warning. The topic-channel-citations validation modules aren't migrated in this PR and their snapshot shows degraded output is now the accepted baseline.

This is fine if the intent is that this plugin version only ships once all upstream module meta.yml files are updated, but that coupling isn't documented anywhere. A pipeline author who bumps the plugin without updating their modules will get silently wrong citations. Options:

  • Add a log.warn when publication is absent but top-level author/year fields are present.
  • Or add a compatibility shim that reads flat fields as a fallback:
    def pub = citationData.publication instanceof Map
        ? citationData.publication
        : [author: citationData.author, year: citationData.year,
           title:  citationData.title,  source: citationData.journal]

Suggestion

<em>et al.</em> embeds HTML in toolCitationText() output — if that string ever reaches log.info or a plain-text file, the tags appear literally. The snapshots accept this. Worth noting explicitly (e.g. in the Javadoc) that the return type is now HTML, not plain text.


Generated by Claude Code

@edmundmiller edmundmiller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice migration to the nested publication object — the schema alignment, Harvard-style short refs, and DOI/homepage linking all read cleanly, and the test/fixture/snapshot updates are thorough.

Two things to look at before merge (inline):

  1. Bibliography entries can lose their tool name in the DOI branch of formatBibliographyFromData() — the old title ?: toolName fallback is gone, so meta.yml files with a DOI but no publication.title produce anonymous <li>doi: …</li> entries (already baked into the updated snapshots). This is the one I'd treat as blocking.
  2. Short citations now contain HTML but are still documented as plain-text copy-paste and written to auto_citations.txt — worth confirming the intended consumer.

The trailing-period trim and DOI-link selection logic both check out. Thanks @maxulysse!


Generated by Claude Code

Comment on lines +260 to +267
if (doi) {
def parts = []
if (author) parts << author
if (year) parts << year
if (title) parts << title
if (source) parts << source
parts << doi
return "<li>${parts.join('. ')}.</li>"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: the DOI branch never falls back to the tool name. The old code set title = toolInfo.title ?: toolName, so every bibliography entry carried at least the tool name. Here title is only appended when pub.title is present, and there's no toolName fallback.

For the common case of a meta.yml with a doi and a publication that has author/year but no title (exactly the validation fixtures in this PR), the entry loses its tool identifier. When there's no publication at all it collapses to a fully anonymous entry — visible in the updated snapshots:

<li>doi: <a href='https://doi.org/10.1093/bioinformatics/btp352'>10.1093/bioinformatics/btp352</a>.</li>

A reader can no longer tell which tool the line refers to. Suggest appending toolName when title is empty so the entry is never anonymous.


Generated by Claude Code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call on the all-or-nothing schema — that reframes the fix. Rather than a title ?: toolName fallback (which would have injected the tool name as a pseudo-title even when an author was present), I keyed the formatter on publication presence:

  • publication present → author-led reference: Author. (year). title. source. doi: link
  • no publication → identified by the tool name: toolName. doi: link

So the only entries that gain a tool name are the bare-DOI ones (your Zenodo case); anything with a publication stays author-led and never carries the tool name. I kept lightweight per-field guards inside the publication branch because a few modules (and the validation fixtures in this PR) still carry a partial publication (author/year, no source) mid-migration — without them those render Author. (year). . .. Once the modules in nf-core/modules#12142–12151 land, those guards just become belt-and-braces.

Pushed to claude/beautiful-fermi-silds0 (red-green tested; citations-on-the-fly and topic-channel-citations snapshots updated — only the bare-DOI multiqc/topic entries change). Happy to open it as a PR against this branch, or you can cherry-pick a94bd85.


Generated by Claude Code

Comment on lines +545 to +552
if (ref) {
// Link to DOI if available, else link to homepage
if (info?.doi) {
ref = "<a href='https://doi.org/${info.doi}'>${ref}</a>"
} else if (info?.homepage) {
ref = "<a href='${info.homepage}'>${ref}</a>"
}
parts << ref

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design check: the short citation now embeds HTML (<a href=...> and <em>et al.</em>) into a string that docs/utilities/NfcoreCitationUtils.md still describes as "formatted for direct copy-paste into a methods paragraph," and that gets written to auto_citations.txt. A user pasting that file into a manuscript would get raw HTML tags.

If the markup is intentional for the MultiQC/HTML methods section, could we reconcile the plain-text artifact + docs (e.g. keep a plain-text variant for auto_citations.txt)? Otherwise the HTML leaks into a context that expects text.


Generated by Claude Code

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't a paste without formatting deals with that?

edmundmiller pushed a commit that referenced this pull request Jun 23, 2026
Capture the architectural question raised on PR #51: rather than the
Nextflow plugin assembling AND formatting citations (HTML links, italics)
that get reused as plain text, emit structured citation data (CSL-JSON /
.bib) and let MultiQC own the rendering, consistent with how MultiQC owns
reporting everywhere else.

Status: Proposed. Lays out context (assembly vs presentation split,
current consumers, MultiQC plugin entry points), a proposed decision,
consequences, open questions, and alternatives. Linked from the ADR index.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015EvrftaVNPDUPvdubjHepF
edmundmiller pushed a commit that referenced this pull request Jun 23, 2026
Record the decisions: CSL-JSON canonical (+ optional .bib), a dedicated
new MultiQC citations plugin repo, structured file as the sole
nf-core-utils deliverable (no in-plugin renderer), clean cutover. Add a
sequencing plan (land #51 fix, bootstrap the plugin repo, then a
nf-core-utils refactor PR) and the remaining design questions for the
new repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015EvrftaVNPDUPvdubjHepF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants