Skip to content

fix(renderer): treat single newlines as soft breaks, not line breaks - #19

Merged
b451c merged 1 commit into
b451c:mainfrom
shmuelzon:ignore-single-line-breaks
Aug 15, 2026
Merged

fix(renderer): treat single newlines as soft breaks, not line breaks#19
b451c merged 1 commit into
b451c:mainfrom
shmuelzon:ignore-single-line-breaks

Conversation

@shmuelzon

Copy link
Copy Markdown
Contributor

The renderer appended a hard newline after every source line, so a single newline inside a paragraph rendered as a visible line break. CommonMark treats it as a soft break — rendered as a space.

Add MarkdownRenderer.joinSoftBreaks, a pre-pass that joins consecutive paragraph lines into one logical line before per-line rendering:

  • hard breaks still work: two+ trailing spaces, or a trailing backslash (odd runs only — an even run is escaped literal backslashes)
  • a list/task item starts its own line but absorbs the plain lines that follow it (CommonMark lazy continuation), so wrapped item text stays inside the item under its hanging indent instead of dropping to the left margin as a bogus paragraph
  • headers, rules, and blank lines keep their own line and never absorb or become a continuation
  • a continuation line's leading/trailing whitespace is collapsed into the single joining space

Blockquote and alert bodies did the same per-line joining, so they now run their lines through the same pre-pass.

The renderer appended a hard newline after every source line, so a
single newline inside a paragraph rendered as a visible line break.
CommonMark treats it as a soft break — rendered as a space.

Add MarkdownRenderer.joinSoftBreaks, a pre-pass that joins consecutive
paragraph lines into one logical line before per-line rendering:

- hard breaks still work: two+ trailing spaces, or a trailing backslash
  (odd runs only — an even run is escaped literal backslashes)
- a list/task item starts its own line but absorbs the plain lines that
  follow it (CommonMark lazy continuation), so wrapped item text stays
  inside the item under its hanging indent instead of dropping to the
  left margin as a bogus paragraph
- headers, rules, and blank lines keep their own line and never absorb
  or become a continuation
- a continuation line's leading/trailing whitespace is collapsed into
  the single joining space

Blockquote and alert bodies did the same per-line joining, so they now
run their lines through the same pre-pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@b451c
b451c merged commit 50c279b into b451c:main Aug 15, 2026
3 checks passed
@b451c

b451c commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Merged - thank you, this is exactly the kind of fix I like to receive. The pre-pass approach keeps renderLine untouched, classify mirroring the renderer's dispatch is the right guard against gluing structural lines, and the odd/even trailing-backslash rule plus lazy continuation for list items show you went to the spec rather than the symptom. The 13 tests document the contract better than a comment ever could.

Verified locally: full suite green (108/108), Release build clean, and a running build renders one-sentence-per-line paragraphs as a single flow, two-space and backslash hard breaks still break, escaped backslashes stay literal, wrapped bullet/ordered/task items hang under their text, and blockquotes/alerts keep their paragraph structure. Search highlighting is unaffected since it works on the rendered text.

This is a visible behavior change for anyone who relied on single newlines breaking lines, so it will be called out in the changelog. Ships in the next release (1.8.0).

b451c added a commit that referenced this pull request Aug 15, 2026
…ow-up to #19)

PR #19 made single newlines soft breaks on screen, including in blockquote
and alert bodies, but the printable views used for PDF export and printing
still rendered those bodies line by line — a quote written one sentence per
line came out as one line per sentence in the PDF while reading as a single
paragraph in the window. Run the same `MarkdownRenderer.joinSoftBreaks`
pre-pass in PrintableBlockquoteView and PrintableAlertView so screen and
export agree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
b451c added a commit that referenced this pull request Aug 15, 2026
1.8.0: custom font families for body/code (#18, Settings → Fonts + theme
JSON keys) and CommonMark soft breaks (#19, behavior change, @shmuelzon).
README: fonts in features/structure/roadmap, soft breaks noted, 123 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@b451c

b451c commented Aug 15, 2026

Copy link
Copy Markdown
Owner

v1.8.0 with this change is now live: https://github.com/b451c/quickmd/releases/tag/v1.8.0 - thanks again!

One follow-up landed alongside it: the printable blockquote and alert views used for PDF export and printing now run the same soft-break pre-pass, so screen and PDF agree (6599cf7).

@shmuelzon
shmuelzon deleted the ignore-single-line-breaks branch August 15, 2026 18:03
@shmuelzon

Copy link
Copy Markdown
Contributor Author

Merged - thank you, this is exactly the kind of fix I like to receive

image

:)

v1.8.0 with this change is now live: https://github.com/b451c/quickmd/releases/tag/v1.8.0 - thanks again!

Nice catch, forgot about PDFs, and thanks for the quick release!

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