Keep dashes and ellipses with the words they cling to - #56
Merged
Conversation
An em dash written as "---" joins two words into a single token, since the
wrapper breaks only on whitespace. That was safe but crude: the pair moved
as a unit, and the dash never got a break of its own. Sweeping the cursor
across the margin against a fragment that opens with a dash -- the shape the
navigation panel uses -- turned up something sharper. Such a line could run
past the margin, to column 83 in an 80 column terminal. A fragment starting
with punctuation is granted SafetyMargin columns so that a lone period is
not stranded by itself; a hyphen is punctuation, so fifty characters of
prose beginning with a dash collected a concession meant for one character.
The terminal hides this behind the five columns PagedOutput holds back.
--width and the web driver do not.
Three rules now, and an ellipsis wants all of them as much as a dash does:
- A break may fall on the far side of a run of two or more hyphens or
periods, which is the one place inside a word where a line may end.
The far side must be a word: to break "am I..." from "?" would strand
the question mark, which is the fault being repaired rather than a
second instance of it.
- No break is chosen that would leave such a run at the head of a line.
The mark belongs to the word behind it and travels with it.
- The punctuation concession is for a stub of no more than SafetyMargin
characters, not for any clause that merely opens with a mark.
A single hyphen is left alone. It belongs to the word it joins, and
"lead-lined" is not a place to break a line.
The second rule governs the break the wrapper chooses. It does not reach
the case where there is no room to choose anything -- a fragment opening
with a dash, arriving when the line is already full. That one goes down to
the next line and starts it with the mark, which is the same answer the
wrapper has always given a word too long to fit: hold the margin, and let
the line begin with whatever had to be moved. Overrunning the margin is
the fault that shows in a narrow window.
Starship and Gorreven produce byte-identical output across the change.
Neither uses the unspaced forms yet, which is the point: this is inert on
everything already written.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ui8UMgev1U8LW5iyQdSsJ
gitosaurus
force-pushed
the
fix/wrap-em-dash
branch
from
August 13, 2026 02:28
04b3dad to
3aa2bfd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An em dash written as
---joins two words into a single token, because thewrapper breaks only on whitespace. That was safe but crude: the pair moved as
a unit and the dash never got a break of its own. Sweeping the cursor across
the margin against a fragment that opens with a dash turned up something
sharper — such a line could run to column 83 in an 80-column terminal.
A fragment starting with punctuation is granted
SafetyMargincolumns so thata lone period is not stranded by itself. A hyphen is punctuation, so fifty
characters of prose beginning with a dash collected a concession meant for one
character. The terminal hides this behind the five columns
PagedOutputholdsback;
--widthand the web driver do not.Three rules, and an ellipsis wants all of them as much as a dash does
periods — the one place inside a word where a line may end. The far side
must be a word: breaking
am I...from?would strand the question mark,which is the fault being repaired rather than a second instance of it.
The mark belongs to the word behind it and travels with it.
SafetyMargincharacters, not for any clause that merely opens with a mark.
A single hyphen is left alone. It belongs to the word it joins, and
lead-linedis not a place to break a line.Where the second rule stops
It governs the break the wrapper chooses. It does not reach the case where
there is no room to choose anything — a fragment opening with a dash arriving
when the line is already full. That one goes down to the next line and starts
it with the mark, which is the same answer the wrapper has always given a word
too long to fit: hold the margin, and let the line begin with whatever had to
be moved.
Honouring the no-leading-dash rule in that case was written first, and it cost
fifteen lines of special handling and a soft margin. Relaxing the rule deleted
the special case and made the margin hard again. Overrunning the margin is the
fault that shows in a narrow window; a line that opens with a dash is not.
Verification
testClingingMarks_at 20columns, covering both sides of a mark, the stranded
?,lead-lined, theforced case, and the lone period that the safety margin still rescues.
Neither uses the unspaced forms yet, which is the point: this is inert on
everything already written, and only changes what happens once
---startsappearing in game text.
🤖 Generated with Claude Code
https://claude.ai/code/session_013Ui8UMgev1U8LW5iyQdSsJ