Skip to content

Add annotated bibliographies - #258

Merged
dknauss merged 5 commits into
mainfrom
feat/annotations
Nov 6, 2026
Merged

dknauss merged 5 commits into
mainfrom
feat/annotations

Conversation

@dknauss

@dknauss dknauss commented Nov 6, 2026

Copy link
Copy Markdown
Owner

This adds annotated bibliographies, as planned in SPEC.md (#255). Each entry can carry your own note on a work: what it argues, why it matters, how you used it. A new block setting, Show annotations, prints each note under its entry.

  • Storage: plain text in the entry's CSL annote (CSL 1.0.2: "reader's notes about the item content"), with a blank line between paragraphs. HTML is stripped in both the JS and PHP sanitizers.
  • Editor:
    • An "Annotation" field in "Edit fields" and in manual entry. Changing only the note keeps a hand-edited citation line and skips the duplicate check.
    • A "Show annotations" toggle (showAnnotations, default off) in the sidebar. While it's on, the editor previews the notes.
  • Output: with the setting on, each paragraph is a <p class="bibliography-builder-annotation"> inside the entry, indented under it, in newsletters and feeds too. Notes stay out of copied citations, plain text, COinS and JSON-LD (description is noted as a possible later mapping).
  • Exports and imports:
    • Exports: CSL-JSON keeps annote, BibTeX writes annote, BibLaTeX annotation, and RIS N1. The per-entry Cite / Export RIS adds it only while notes are shown, so old blocks don't change.
    • Imports: BibTeX and BibLaTeX notes come in with their paragraphs. RIS N1 stays mapped to CSL note, and abstracts stay abstracts.
  • Read model and writes: the read model, PATCH …/bibliographies/{ref} and wp borges list --fields gain showAnnotations.

Existing blocks are untouched. With the setting off, or with no notes, save() writes exactly what 1.18.0 did, so no deprecation is needed. New save-parity fixtures for hidden notes were rendered by main's JS save() and PHP port, and the new code matches them byte for byte.

Decision for you: a hidden note is not private. It stays in the entry's data, so the CSL-JSON and BibTeX exports (and the Cite / Export data, when that's on) carry it even with "Show annotations" off. Stripping it would change blocks that already carry annote without a deprecation, so this PR documents it instead, in the field's help text, SPEC (as an open item) and the changelog.

How it was checked

  • Jest: 1,291 tests. PHPUnit: 726 tests. ESLint, Stylelint, Prettier, tsc, PHPCS, Psalm and verify-metrics.sh all pass.
  • In WordPress Playground: old posts open valid, including old markup whose entries already carry annote. A new post with a pasted BibTeX entry, a two-paragraph note and the setting on saves, reloads valid, and shows the note on the front end.
  • Not run locally: the Playwright E2E smoke (the repo pins a different Chromium build). CI runs it.
  • Not checked: how Zotero, Mendeley and EndNote read the exported annote, annotation and N1. It's listed as open in SPEC.

Merge order: this branch, #256 (citations) and the other new Borges PR touch the same docs (CHANGELOG.md, SPEC.md, README.md, readme.txt) and the line counts in docs/current-metrics.md. Whichever merges later needs a rebase and a re-run of verify-metrics.sh. No version is bumped, so merging releases nothing.


Generated by Claude Code

dknauss and others added 3 commits November 6, 2026 03:44
Each entry can carry the compiler's own note in its CSL `annote`
variable, as plain text with blank lines between paragraphs. The field
editor and manual entry gain an "Annotation" textarea, and a new block
setting, showAnnotations (default false), prints each paragraph as a
<p class="bibliography-builder-annotation"> after the entry text.

With the setting off or absent, or with no annotations, save() writes
exactly what 1.18.0 wrote, so existing blocks need no deprecation. The
annotations-hidden and annotations-off save-parity fixtures were
rendered by the 1.18.0 save() (JS and PHP) and still match.

- Sanitizers (JS and PHP) keep annote as clean plain text or drop it.
- The PHP save() port matches; parity fixtures cover shown annotations.
- RIS writes N1 (bulk export always; Cite / Export only when shown).
  BibTeX/BibLaTeX write annote/annotation through citation-js.
- BibTeX annote and BibLaTeX annotation import with paragraphs kept;
  RIS N1 stays a note and abstracts stay abstracts.
- Kept out of copied text, plain text, COinS, and JSON-LD; kept in
  email and feed output with an inline indent.
- Read model, write settings, and wp borges list report showAnnotations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS
Move the SPEC plan into implemented behaviour with the remaining open
items, add the feature to the readmes and the Unreleased changelog,
list showAnnotations in the write-route and WP-CLI docs, and update the
line counts in docs/current-metrics.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS
tools/check-components.py compares components.json with block.json's
attributes; the new attribute was missing there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS
@codecov

codecov Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.43713% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.32%. Comparing base (b3ef682) to head (d83d8fd).

Files with missing lines Patch % Lines
src/lib/bibtex-fields.js 64.70% 5 Missing and 13 partials ⚠️
src/lib/annotation.js 73.33% 0 Missing and 4 partials ⚠️
src/lib/csl-sanitize.js 66.66% 0 Missing and 3 partials ⚠️
src/components/structured-citation-editor.js 50.00% 0 Missing and 2 partials ⚠️
src/hooks/use-citation-editor-state.js 75.00% 0 Missing and 1 partial ⚠️
src/lib/export.js 66.66% 0 Missing and 1 partial ⚠️
src/lib/manual-entry.js 50.00% 0 Missing and 1 partial ⚠️
src/save-markup.js 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main     #258      +/-   ##
============================================
- Coverage     89.47%   89.32%   -0.15%     
  Complexity       67       67              
============================================
  Files            95       96       +1     
  Lines         10409    10550     +141     
  Branches        816      846      +30     
============================================
+ Hits           9313     9424     +111     
- Misses          412      417       +5     
- Partials        684      709      +25     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

dknauss commented Nov 6, 2026

Copy link
Copy Markdown
Owner Author

@codex review


Generated by Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-06T15:11:37.308517Z dae1a3a Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9969ab2298

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/bibtex-fields.js Outdated
Comment on lines +457 to +458
.slice( start, stop )
.replace( /\r?\n[ \t]*\r?\n\s*/gu, ' \\par ' ) +

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restrict paragraph marking to the annotation field value

When a valid BibTeX entry has a blank line after its annotation field, this replacement inserts \par outside the field value. For example, annote = {Note.},\n\n year = {2001} becomes annote = {Note.}, \par year = {2001}, which is invalid BibTeX and breaks importing that entry. Blank lines between = and the value or before the entry's closing brace are affected too. Restrict the replacement to the annotation's actual value, preserving whitespace outside it.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in dae1a3a. markBibtexAnnotationParagraphs() now finds the braced or quoted value (findBibtexFieldValueRange()) and marks paragraphs only inside it. Blank lines between = and the value, after the value, or before the entry's closing brace are left alone, and bare values are skipped. New tests cover each case, plus nested braces inside a quoted value. The full Jest suite passes (1,292 tests).


Generated by Claude Code

markBibtexAnnotationParagraphs() replaced blank lines from the field name
to the next field, so a blank line after the value (or before it, or
before the entry's closing brace) became a \par outside the braces and
the entry no longer parsed. It now finds the braced or quoted value and
changes only its inside; bare values are left alone. Found by Codex
review on #258.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS

dknauss commented Nov 6, 2026

Copy link
Copy Markdown
Owner Author

@codex review


Generated by Claude Code

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: dae1a3a144

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

dknauss commented Nov 6, 2026

Copy link
Copy Markdown
Owner Author

The Playwright (lifecycle) and Package release artifact failures at dae1a3a are infrastructure, not the code: Composer got HTTP 504 from api.github.com downloading myclabs/php-enum, seboettg/collection, and citeproc-php, so both jobs stopped before building or testing anything. They will be re-run once the rest of the run finishes.


Generated by Claude Code

# Conflicts:
#	CHANGELOG.md
#	docs/current-metrics.md
#	includes/email-output.php
@dknauss
dknauss merged commit 887ccfa into main Nov 6, 2026
28 of 32 checks passed
@dknauss
dknauss deleted the feat/annotations branch November 6, 2026 15:55
@dknauss dknauss mentioned this pull request Nov 6, 2026
dknauss added a commit that referenced this pull request Nov 7, 2026
In-text and margin citations with Update citations after a style change
(#256); annotated bibliographies (#258); h-cite microformats (#257); full
citation records in Yoast SEO's graph and Yoast context fix (#252, #254);
RIS journal abbreviations; sentence case in Harvard; the Playground demo
example of citations and annotations (#259).


Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants