Impact: low. Cosmetic, invisible in a terminal.
Filing this for the context, not because it needs fixing soon. A wrapped line
can end with a space. Nothing renders differently: a terminal shows nothing,
HTML collapses it, and gameplay is unaffected. It shows up only in byte-exact
comparison of --width output, or when someone copies text out of a window.
The fix touches the trickiest function in WrappedOutput, so the cost is
plausibly larger than the defect.
Reproduction
room start_room
desc : "probe room"
methods
'INITIAL' : 'START HERE' -> player
'LONGDESC' : {
>>Struggling, I manage to get the guard's uniform off of his fat,
>>sweaty---and increasingly cold---body.
}
end
./build/archetype --silent --source=probe.arch --include=games --create=probe.acx
./build/archetype --silent --update=probe.acx --input="look" --width=36 | grep -n ' $'
2:guard's uniform off of his fat, <EOL>
Mechanism
Not the paragraph's fault. ParagraphOutputStatement::execute
(src/Statement.cc:528) already has exactly the right semantics -- it is
' '.join(pieces), emitting a separator between lines and nothing after the
last, with two spaces after . : ! ? and none at all when the previous
line already ended in whitespace. There is no paragraph-final space to trim.
The separator goes out as its own small put. At that moment the cursor is at
31 of 36, so the space fits and is committed to the line. Then the next
fragment arrives, its first word is 12 characters, 4 columns remain, and the
cut_p == s.begin() branch (src/WrappedOutput.cc:67) ends the line and moves
the word down. The space was already spent.
Nothing is wrong at either site. The space was emitted before the information
needed to judge it existed.
TestWrappedOutput::testWrapAcrossPuts_ (src/TestWrappedOutput.cc:128)
already covers the neighbouring case, where the space arrives with the cursor
exactly on the margin and the break correctly spends it. This is the case
where the space fits but the following word does not.
If it is ever fixed
A pending-whitespace buffer in WrappedOutput: hold whitespace found at the
tail of a put instead of emitting it, flush it only when non-whitespace
follows on the same line, and discard it at endLine. Cursor accounting has to
follow the deferral, which is the part that makes this more than a few lines.
Note that it would change output bytes wherever it fires, so it wants the same
before/after capture over Starship and Gorreven that the em-dash change used.
A new case belongs next to the existing one in testWrapAcrossPuts_.
Impact: low. Cosmetic, invisible in a terminal.
Filing this for the context, not because it needs fixing soon. A wrapped line
can end with a space. Nothing renders differently: a terminal shows nothing,
HTML collapses it, and gameplay is unaffected. It shows up only in byte-exact
comparison of
--widthoutput, or when someone copies text out of a window.The fix touches the trickiest function in
WrappedOutput, so the cost isplausibly larger than the defect.
Reproduction
Mechanism
Not the paragraph's fault.
ParagraphOutputStatement::execute(
src/Statement.cc:528) already has exactly the right semantics -- it is' '.join(pieces), emitting a separator between lines and nothing after thelast, with two spaces after
.:!?and none at all when the previousline already ended in whitespace. There is no paragraph-final space to trim.
The separator goes out as its own small
put. At that moment the cursor is at31 of 36, so the space fits and is committed to the line. Then the next
fragment arrives, its first word is 12 characters, 4 columns remain, and the
cut_p == s.begin()branch (src/WrappedOutput.cc:67) ends the line and movesthe word down. The space was already spent.
Nothing is wrong at either site. The space was emitted before the information
needed to judge it existed.
TestWrappedOutput::testWrapAcrossPuts_(src/TestWrappedOutput.cc:128)already covers the neighbouring case, where the space arrives with the cursor
exactly on the margin and the break correctly spends it. This is the case
where the space fits but the following word does not.
If it is ever fixed
A pending-whitespace buffer in
WrappedOutput: hold whitespace found at thetail of a
putinstead of emitting it, flush it only when non-whitespacefollows on the same line, and discard it at
endLine. Cursor accounting has tofollow the deferral, which is the part that makes this more than a few lines.
Note that it would change output bytes wherever it fires, so it wants the same
before/after capture over Starship and Gorreven that the em-dash change used.
A new case belongs next to the existing one in
testWrapAcrossPuts_.