Repository navigation
Add in-text and margin citations - #256
Conversation
A "Cite" rich-text format (bibliography-builder/citation) links a short
citation in any paragraph, including a theme's margin-note style, to an
entry in a Borges bibliography on the same post. The popover lists every
entry of every bibliography block in the post, searchable, with an
optional locator. The short form follows the style family: a Chicago
short note, (Family Year, locator), or [n].
The saved link is a plain fragment link to save()'s <li id="ref-{id}">,
with the h-cite class and data-bibliography-ref, which survive kses for
every role. The bibliography block's save() is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS
verify-metrics.sh checks docs/current-metrics.md against the tree; the new format and its helpers add 1,084 lines of source (13608 -> 14692). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #256 +/- ##
============================================
- Coverage 89.32% 88.64% -0.68%
Complexity 67 67
============================================
Files 96 102 +6
Lines 10550 10968 +418
Branches 846 962 +116
============================================
+ Hits 9424 9723 +299
- Misses 417 447 +30
- Partials 709 798 +89 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@codex review Generated by Claude Code |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e35816f769
ℹ️ 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".
| const has = ( index ) => | ||
| Array.isArray( formats[ index ] ) && | ||
| formats[ index ].some( | ||
| ( format ) => format.type === CITATION_FORMAT_NAME | ||
| ); |
There was a problem hiding this comment.
Stop citation ranges at a change of reference
When two different citations are adjacent, such as [1][2], this predicate treats them as one citation because it checks only the format type, not the reference attributes. A caret inside [1] consequently produces a range covering both links: updating with the default replacement deletes [2], updating without replacement retargets both citations, and removing unlinks both. Compare each neighboring citation's reference with the active citation before expanding the range.
Useful? React with 👍 / 👎.
Save each citation's locator as data-locator, prefill it when the Cite
popover reopens, and add an "Update citations" action: a "Citations in
this post" sidebar panel on the bibliography block, and a notice after a
style change. The update rewrites the citations the editor generated
(in any block, nested ones included) in the current style and
numbering, keeps locators, recovers them from the text of older
citations, leaves reworded ones alone unless asked, and counts
citations whose entry is gone. It is one undoable edit.
Also fix getCitationRange() treating adjacent citations to different
entries ("[1][2]") as one: the range now grows only over characters
citing the same ref, using the active citation's ref at a boundary.
Rename the locator field to "Page, chapter or section (optional)" with
help text.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS
|
@codex review Generated by Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9582206eaa
ℹ️ 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".
| if ( hasText && ! replaceText ) { | ||
| return applyFormat( | ||
| value, | ||
| getCitationFormat( entry.id, locator ), |
There was a problem hiding this comment.
Remove existing link formats before applying a citation
When the selected text already contains a normal hyperlink, inserting a citation with the default “keep text” behavior adds the citation format without removing core/link. Both formats serialize as <a> elements, producing invalid nested links rather than replacing the existing destination. On HTML reload, the browser repairs those nested anchors, which can leave the visible citation text linked to the original URL instead of its bibliography entry. Remove the existing link format over the citation range before applying the citation format.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d271328: applyCitation() now removes core/link over the cited range before applying the citation format, so the text carries one link, the citation. A test covers citing part of an existing link: the cited part becomes the citation, and the rest keeps its URL as a separate, non-nested link.
Generated by Claude Code
Applying a citation to text that already carried core/link nested one <a> inside another, which browsers split apart on reload, leaving the text linked to the old URL. Remove core/link over the cited range first. Found by Codex. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS
|
@codex review Generated by Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d271328ddb
ℹ️ 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".
| return start === end ? null : { start, end }; | ||
| } | ||
|
|
||
| const isSame = ( index ) => refAt( index ) === anchorRef; |
There was a problem hiding this comment.
Stop citation ranges when the locator changes
When adjacent citations refer to the same entry but different pages, such as [1, 12][1, 20], comparing only ref still merges them into one editable range. A caret inside the first citation therefore causes the default Update action to replace both citations with one, losing the second page reference; Remove also unlinks both. The different-reference case from the earlier review is fixed, but a direct check with identical references and different locator attributes still returns the combined range. Include the locator in the boundary comparison so these distinct citations remain independently editable.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 147a2e8: the range now grows only over characters with the same ref and the same locator, so [1, 12][1, 20] are two citations. A test checks both ranges and that removing the second leaves the first linked.
Generated by Claude Code
Adjacent citations of one entry at different pages ("[1, 12][1, 20]")
merged into one range, so updating or removing one changed both. A citation
range now grows only over characters with the same ref and locator. Found by
Codex.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS
|
@codex review Generated by Claude Code |
|
Generated by Claude Code |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
# Conflicts: # CHANGELOG.md # SPEC.md # docs/current-metrics.md
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>
This adds a Cite control to the rich-text toolbar. It links a short citation in any paragraph to an entry in a Borges bibliography on the same post. It works in running text and in a theme's margin-note paragraph style, such as Marginalia's Gloss, with no new block. This is the "margin citations" item from
SPEC.md(#255).<a class="bibliography-builder-citation h-cite" href="#ref-{id}" data-bibliography-ref="{id}">. It works with no JavaScript, and it surviveswp_kses_postfor authors withoutunfiltered_html(checked).SPEC.md§ "In-Text and Margin Citations" documents this.@wordpress/rich-textto devDependencies (already in the lockfile at 7.48.1). Lint needs it as a declared dependency.How it was checked
build, ESLint, Stylelint,typecheck:js,lint:i18nand Prettier also pass.:targetoutline. It also works with JavaScript off.npm cineeds--legacy-peer-depswith npm 10.9.9 because of an eslint peer-range conflict that is already onmain, not caused by this branch.Follow-ups
Updating citations after a style change
Each citation now saves its page, chapter, or section as
data-locator.wp_kses_postkeeps it, which was checked in Playground as an Author. The Cite popover's field is now labelled "Page, chapter or section (optional)", and it fills in again when reopened on a citation.The bibliography's sidebar has a "Citations in this post" panel. It counts the citations that point at the bibliography and offers Update citations. Changing the style offers the same action in a notice.
The update rewrites every citation the editor generated, in any block, nested ones and table cells included. It uses the current style and numbering, keeps each citation's locator, and makes all the changes as one undoable edit.
data-locatorexisted have their locator read back from text that matches a short form, and then saved.This also fixes Codex's finding: two citations side by side ("[1][2]") are now two ranges, so updating or removing one no longer changes the other.
https://claude.ai/code/session_01WPtgA1cnwP9mYKwaWniaFS
Generated by Claude Code