Skip to content

fix(ui): render qs Selah pause on its own right-aligned line (YPE-6405) - #254

Open
Dustin-Kelley wants to merge 15 commits into
dk/native-text-pocfrom
cursor/qs-selah-own-line-6ac6
Open

Dustin-Kelley wants to merge 15 commits into
dk/native-text-pocfrom
cursor/qs-selah-own-line-6ac6

Conversation

@Dustin-Kelley

@Dustin-Kelley Dustin-Kelley commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Why

Readers of the native Bible see a Selah pause (qs) in italic on the left of the poetry line. The pause should sit on its own italic line at the end of the line, which is the right edge in a left-to-right Bible. A pause that is already inside qr stays as it is.

What changed

  • A line that contains qs keeps the poetry before the pause, and puts the pause on its own end-aligned line.
  • That line reads the pause, then an attached footnote marker, then trailing punctuation. With notes on, that is Selah, the marker, then the period. With notes off, it is Selah and the period.
  • Share text and footnote html still come from the verse before that split, so punctuation does not gain a space.

Scope

This covers qs in any poetry line, including q and q4. It leaves qr lines alone. It does not change the web reader.

Tradeoffs

End alignment puts the pause on the right in left-to-right text and on the left in right-to-left text. qr stays on the physical right in both directions, which is the existing rule.

Blast Radius

Native chapter text that contains a qs span. Share text still reads as one sentence, and a mark after the pause does not gain a space in front of it.

Verification

  • Jest on the scripture parser and the native reader. The new pause cases failed before the fix (the period and the exclamation mark were their own lines) and pass after it. 122 tests.
  • No Platform app key, so the HTML is the Bible.com verse API for Habakkuk 3:3 (https://nodejs.bible.com/api/bible/verses/3.3?id={version}&references[]=HAB.3.3). Swift pull request 297 lists these three Habakkuk 3:3 examples and does not list 3:9 or 3:13. Before is dk/native-text-poc. After is this branch.
  • Bible.com calls a footnote note f and a verse number label. Those two class names were renamed to yv-n f and yv-vlbl so this reader draws a marker and a verse number. The poetry classes and the words are the Bible.com markup. Brand fonts returned 401 and fell back.
Example Before After
Orthodox Jewish Bible (130), Habakkuk 3:3. iOS simulator. Before, Orthodox Jewish Bible, Habakkuk 3:3 After, Orthodox Jewish Bible, Habakkuk 3:3
Orthodox Jewish Bible (130), Habakkuk 3:9 and 3:13. iOS simulator. Before, Orthodox Jewish Bible, Habakkuk 3:9 and 3:13 After, Orthodox Jewish Bible, Habakkuk 3:9 and 3:13
Orthodox Jewish Bible (130), Habakkuk 3:9 and 3:13. Android emulator. Before, Orthodox Jewish Bible, Habakkuk 3:9 and 3:13 After, Orthodox Jewish Bible, Habakkuk 3:9 and 3:13
The Passion Translation (1849), Habakkuk 3:3. iOS simulator. Before and after match because the pause line was already right-aligned. Before, The Passion Translation, Habakkuk 3:3 After, The Passion Translation, Habakkuk 3:3

Footnote marker

A footnote marker immediately after a Selah pause stays on the pause line, before any trailing punctuation. That is the expected behavior.

NVI Bible version was not tested — no license available for that version.

Open in Web Open in Cursor 

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge, with one previously reported, non-blocking quote-placement issue remaining.

Fix All in Claude CodeFindings

  1. P2 Opening quote leaves its sentence ▶
Fix with agent prompt
### Issue 1
packages/ui/src/native/scripture/parse-passage.ts:217-224
For `<span class="qs">Selah</span> "Next words"`, the new split moves the opening quote onto the Selah line. `opensFollowingWords` misses it because the following words are inside the same inline, not the next one. The uppercase check then accepts the split. Readers see `Selah"` followed by `Next words"` on another line.

Please check for opening quotes within the shared text before moving its punctuation.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Moves qs pauses onto their own end-aligned lines in the native reader.

  • Selah pauses sit on their own trailing-edge line.

Reviews (12) · Last reviewed commit: "docs(ui): add OJB Habakkuk 3:9–3:13 Andr..." · Reviewed by Greptile

cursoragent and others added 2 commits October 30, 2026 17:04
YPE-6405

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
A qs pause leaves the poetry line and sits on the trailing edge.
A qr line stays as it is. A footnote marker after the pause stays
on the pause line until the team picks the other placement.

YPE-6405

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
@Dustin-Kelley
Dustin-Kelley marked this pull request as ready for review November 2, 2026 14:06
cursoragent and others added 8 commits November 2, 2026 14:12
YPE-6405

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
Share text and footnote html come from the passage before the pause
moves to its own line, so a mark after Selah does not gain a space.

YPE-6405

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
The pause line reads the pause, then its footnote marker, then a
following mark. Share text still comes from the verse before that split.

YPE-6405

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
YPE-6405

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
YPE-6405

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
YPE-6405

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
YPE-6405

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>

@bmanquen bmanquen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue (blocking): The acceptance criteria call for a visual check of Habakkuk 3:3, 3:9 and 3:13 in versions 130, 4360 and 1849. The PR shows only 3:3 in 130 and 1849. The Portuguese NVI (4360) shots were dropped in 67a2efb, and 3:9 and 3:13 are not covered. Please add those captures, or note why they are out of scope, before merging.

Any mark after a pause now stays on the pause line, not only . ! ? and
the ellipsis. Opening marks stay with the words that follow. linkedom
splits a text node at each entity, so the pause line takes every
following punctuation run.

YPE-6405

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A straight quote has no opening or closing form, so spacing decides. A
space before it and a word right after it means it opens the next line.
Any other straight quote stays on the pause line.

YPE-6405

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@bmanquen bmanquen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Three things to fix before merge, inline below. The verification gap has no code line, so here it is:

todo (blocking): YPE-6405 asks for a visual check of Habakkuk 3:3, 3:9 and 3:13 in 130, 4360 and 1849. The PR shows only 3:3, in 130 and 1849, on iOS. NVI (4360) has no license, so that gap is fine. Please add 3:9 and 3:13 in 130 and 1849, and one Android capture. The Android shot matters most, because of the RTL alignment noted inline on passage.tsx.

// Every punctuation category except opening marks (Ps, Pi), which belong to the next line.
const PAUSE_PUNCTUATION = /^[\s\p{Pc}\p{Pd}\p{Pe}\p{Pf}\p{Po}]+$/u

function isPausePunctuation(inline: Inline): boolean {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue (blocking): The trailing punctuation stays on the pause line only when it is a whole text node by itself. Habakkuk 3:3 passes because its period sits alone after the qs span. When the punctuation shares a node with the words after it, the period moves to the start of the next line:

<span class="qs">Selah</span>. God shall send forth his mercy

The lines come out as ["Selah"] and [". God shall send forth his mercy"]. That breaks the ticket rule "the period after Selah [is] unchanged". A Selah in the middle of a verse, followed by more words, is common (Psalm 57:3, for example).

Suggest splitting the leading punctuation off the next text node. Put the punctuation on the pause line and leave the rest as prose. Please add a test for this shape.

text: texts.join(' ').replace(/\s+/g, ' ').trim(),
html: htmls.join(' '),
text: joinVerseParts(texts),
html: joinVerseParts(htmls),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue (blocking): This now collapses and trims every verse's html, not only the Selah verses. It used to be htmls.join(' '). The change affects share and footnote HTML everywhere, and the changeset doesn't mention it.

The split doesn't need this, because collectVerses already reads the blocks before the split. Suggest keeping html: htmls.join(' ') and using joinVerseParts only for text. If the change is intended, give it a line in the changeset.

if (rule.align === 'center') {
textAlign = 'center'
} else if (rule.align === 'end') {
if (look.rtl) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

question (blocking): In RTL, end becomes a physical textAlign: 'left' next to writingDirection: 'rtl'. The comment removed here said iOS keeps an explicit left in RTL. On Android, left and right may be read as start and end under RTL, and the pause could land on the wrong edge. Has this been checked on Android with an RTL Bible? If it hasn't, this needs a capture before merge (see the summary comment).

When closing punctuation starts the text node after a qs run, peel it onto
the pause line when the remainder opens a new sentence; keep joinVerseParts
for share text only and join verse html with spaces.

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
Comment on lines +217 to +224
if (opensFollowingWords(placed, selahStart, index)) {
return false
}
const rest = split.rest.trimStart()
if (rest === '') {
return true
}
return /^\p{Lu}/u.test(rest)

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 Opening quote leaves its sentence

For <span class="qs">Selah</span> "Next words", the new split moves the opening quote onto the Selah line. opensFollowingWords misses it because the following words are inside the same inline, not the next one. The uppercase check then accepts the split. Readers see Selah" followed by Next words" on another line.

Please check for opening quotes within the shared text before moving its punctuation.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/ui/src/native/scripture/parse-passage.ts
Line: 217-224

Comment:
**Opening quote leaves its sentence**

For `<span class="qs">Selah</span> "Next words"`, the new split moves the opening quote onto the Selah line. `opensFollowingWords` misses it because the following words are inside the same inline, not the next one. The uppercase check then accepts the split. Readers see `Selah"` followed by `Next words"` on another line.

Please check for opening quotes within the shared text before moving its punctuation.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Cursor Fix in Codex

cursoragent and others added 2 commits November 4, 2026 19:08
iOS simulator before/after for version 130 (YPE-6405).

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
Emulator before/after for version 130 (YPE-6405).

Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.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.

3 participants