Add LineBlockDivExtension (::: | fenced line blocks)#243
Merged
Conversation
A `:::` div whose only class token is a pipe is treated as a line block: soft breaks become hard breaks, leading whitespace is preserved, and a blank line separates stanzas. It produces the same `line-block` div as the `|`-prefixed form, without prefixing every line - convenient for verse, addresses, lyrics, and signature blocks. Pure extension, no core changes: the block pattern runs before the core div parser, so `::: |` is intercepted before it could become a `class="|"` div. Reuses the core LineBlock node and its renderers, and the core FencedBlockParser detectors so code-fence and closer recognition match the built-in div parser. Composes with nesting (blockquotes, list items). Tracks djot#29.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #243 +/- ##
============================================
+ Coverage 91.89% 92.04% +0.14%
- Complexity 3532 3559 +27
============================================
Files 106 107 +1
Lines 9985 10078 +93
============================================
+ Hits 9176 9276 +100
+ Misses 809 802 -7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Leading whitespace in a `::: |` block now survives the browser's whitespace collapsing without any CSS: it is emitted via the internal non-breaking-space placeholder (U+E000, a private-use sentinel that never collides with a literal U+00A0 in the author's text). The HTML escaper already renders it as ` `; the Markdown / plain-text / ANSI renderers now collapse it to an ordinary space as their final output step - which also fixes a pre-existing case where the escaped-space placeholder leaked into non-HTML output. Tabs expand to four-column stops. A `cssIndent` option keeps raw spaces instead for an HTML + CSS (`white-space: pre-wrap`) workflow.
Drop the `cssIndent` option: the default placeholder now preserves indentation faithfully in every format, so the raw-spaces-for-CSS mode only added a caveat (and a non-HTML-only variant would need a fragile render hook). A custom extension can cover that niche if anyone needs it. Markdown now keeps the indent as a real non-breaking space (U+00A0) rather than an ordinary space. Markdown is a re-parseable round-trip format, so the nbsp survives a re-render as ` ` and is never mistaken for an indented code block. Plain-text and ANSI stay on an ordinary space.
Contributor
Author
|
Merging without release for demo in sandbox for us for now. Net-side effect of fixing the NBSP transformation affects all renderers => positive |
This was referenced Jun 12, 2026
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.
Summary
Adds
LineBlockDivExtension: a fenced line block written as a:::div whose only class token is a pipe -::: |. Produces the sameline-blockdiv as the existing|-prefixed form, without prefixing every line.Inside the fence: soft line breaks become hard breaks (
<br>), leading whitespace is preserved, a blank line separates stanzas (each becomes its own paragraph), and inline djot still parses normally.Indentation preserved in every format
Leading whitespace is kept as a non-breaking space, so the indent survives without any CSS - and it composes with nesting. An indented poem inside a list item:
renders (HTML):
Per format:
in HTML, a real non-breaking space (U+00A0) in Markdown - which keeps the indent through a round-trip re-render and never trips the indented-code-block rule - and an ordinary space in plain-text / ANSI. Tabs expand to four-column stops.Why
Per djot#29: a leading
|on every line (Pandoc-style) can be confused with pipe tables and is awkward to edit; an English-keyword div class (::: verse) was undesirable. A language-neutral|marker on the div opener sidesteps both. The pipe is consumed as the marker, so the output is aline-blockdiv, never a literalclass="|"- and because|is not a meaningful class, intercepting it cannot collide with real usage.Design
addBlockPattern, which runs before the core div parser, so::: |is intercepted before it could become aclass="|"div. Reuses the coreLineBlocknode and the coreFencedBlockParserdetectors so code-fence/closer recognition matches the built-in div parser. Composes with blockquotes and list items.U+00A0in the author's text. The HTML escaper already turns it into ; the non-HTML renderers convert it as their final output step (Markdown ->U+00A0, plain/ANSI -> space). This also fixes a pre-existing case where the escaped-space placeholder leaked into non-HTML output.$converter->addExtension(new LineBlockDivExtension());Docs
docs/extensions/index.md: newLineBlockDivExtensionsection + table entry.docs/guide/syntax.md: cross-reference from the Line Blocks section.Notes
Draft - proposal-stage feature tracking djot#29. Class name settled as
line-block; stanza handling (blank line = separate paragraph) open to review.