Releases: php-collective/djot-php
Release list
0.1.31
Fixes
- Extension-generated ids (tabs, code groups) are now deduplicated against the document id namespace: an explicit id attribute or a colliding heading auto-slug bumps the generated id instead of emitting a duplicate DOM id, and ARIA tab/panel pairs stay aligned.
- Hardened URL schemes in the non-HTML renderers.
- Heading ids derive from source text rather than smart-punctuation glyphs.
Full Changelog: 0.1.30...0.1.31
0.1.30
Fixes
- Security: always-on neutralization of dangerous URL schemes, event-handler / injection-sink attributes (
on*,srcdoc,formaction) and CSSexpression()in the default renderer (previously gated behind safe mode), plus a cap on inline-nesting depth to bound a parse-time DoS. (#253) - Security:
HtmlToDjotignores thedata-djot-src/data-djot-rawround-trip attributes when importing untrusted HTML, preventing a crafted attribute from injecting a raw-HTML block; round-trip honoring is opt-in vianew HtmlToDjot(trustedRoundTrip: true). (#254) - Security: bound abbreviation expansion with a per-render byte budget to prevent an output-amplification memory DoS from a huge definition reused across many occurrences. (#254)
- Non-HTML renderers (Markdown, plain-text, ANSI) no longer lose content. In particular, escaped spaces (
\) no longer leak the internal non-breaking-space placeholder: they now render as a real non-breaking space (U+00A0) in Markdown and an ordinary space in plain-text and ANSI. (#246) - Block content no longer leaks out of marker-line nested-list items. (#251)
- Unreferenced footnotes no longer emit an empty endnotes section. (#236)
- Comments in the profile to-text path are dropped instead of leaking their content. (#235)
- An invalid inline-span attribute block now stays literal instead of being consumed. (#237)
- Over-indented list-item paragraph continuations no longer leak surplus indentation into the output. (#239)
- CLI stdin detection uses
stream_isatty, so piped input is handled reliably. (#240) - Tables: a leading span marker with nothing to merge now renders as an empty cell. (#245)
- Tables: trailing whitespace on rows is tolerated, and empty delimiter cells are rejected. (#247)
- NUL bytes are normalized to
U+FFFDat parse entry. (#248)
Improvements
- New
LineBlockDivExtension: a fenced::: |line block for verse, addresses, lyrics, and signature blocks. Soft line breaks become hard breaks, and indentation is preserved ( in HTML,U+00A0in Markdown) - including medial alignment gaps (runs of two or more spaces, e.g. the caesura of Old English verse), while a single inner space stays collapsible so a long line can still wrap. Opt-in viaaddExtension(new LineBlockDivExtension()). (#243, #244) - New
convertCLI inbin/djot, matching the documented behavior. (#238) - List-item attributes: a
{...}block immediately following a list marker (no space) now attaches to the<li>, e.g.+{.blue} A blue item.(#241) - Keep large table parsing linear (O(n^2) to O(n)). (#234)
- Match single quotes in one O(n) pass instead of an O(n^2) scan. (#249)
Full Changelog: 0.1.29...0.1.30
0.1.29
Fixes
- Empty list items: a bare list marker (such as
-on its own line) is now a valid empty list item, matching the reference djot implementation (#229) - Recognize a list whose marker carries leading indentation, instead of treating an indented
- itemas a paragraph (#232) - Strip residual indentation from a list item's wrapped text continuation, so an over-indented continuation line no longer leaks spaces or tabs into the output (#233)
- Block quotes accept a tab after
>as the marker delimiter, like a space (#231) - Cap block nesting depth to prevent stack and memory exhaustion on deeply nested input (#218)
- Fix unterminated empty backtick code fence being rendered as an inline span (#215)
- Fix blockquote lazy continuation swallowing non-marker lines into an open fence or div (#212)
- Fix empty list marker interrupting a paragraph under
blocksInterruptParagraphs(#221) - HtmlToDjot: reverse smart punctuation for a source-stable round-trip (#214)
- HtmlToDjot round-trip fidelity: an image or nested link inside a link is no longer corrupted, and footnote references, loose lists, and explicit heading/section ids now survive the round-trip (#208)
- HtmlToDjot: separate adjacent same-delimiter inline runs so junctions like
_a__b_no longer merge into a malformed token (#205, #206) - HtmlToDjot: escape leading colon markers and other Djot-significant characters in text output so imported prose is not reparsed as markup (#202, #204)
- HtmlToDjot: pad code-span content symmetrically (#203)
- Reject reference-definition URLs that contain internal whitespace (#200)
- Tighten whitespace handling for reference, footnote, and abbreviation definitions (#199)
- Preserve code-group source in round-trip mode (#198)
Improvements
- Tabs in code blocks and inline code are now preserved literally by default, which is spec-conformant. Enable the new
TabNormalizationExtension(or callsetCodeBlockTabWidth()) to convert them to a fixed number of spaces for display. Note: this changes the default output for code containing tabs (#230) - Align heading-id slugs with the reference Djot implementation and add a pluggable ASCII-folding extension for heading ids (#224)
blocksInterruptParagraphs: in this opt-in mode a line-leading block marker now interrupts a paragraph again, so genuine single-line, short, and lazily-wrapped quotes and lists are preserved. A|interrupts only when the line is a real table row. Standard (non-blocksInterruptParagraphs) parsing is unchanged (#210)blocksInterruptParagraphsnow nests a sublist inside a list item, consistent with top-level interruption across nesting levels (#209)- New
nestedListsWithoutBlankLinelever for compact sublist nesting, the smaller subset ofblocksInterruptParagraphs; paragraph interruption made consistent inside lists (#207) - Support a div attribute opener (#199)
Full Changelog: 0.1.28...0.1.29
0.1.28
Fixes
- Fix sequential list item attributes so consecutive
{...}lines merge onto the same<li>instead of being dropped (#197) - Fix numeric reference-label warnings (#195)
- Parse nested list blocks with deeper indentation and tabs (#192)
Improvements
- Add
blocksInterruptParagraphsparser lever and deprecatesignificantNewlinesin favor of the granular parser options (#194) - Add experimental citations extension (#193)
- Add
nestedBlocksInListsparser option to nest blocks inside list items without a blank line (#191) - Convert
kbd,samp,var,abbr, anddfnHTML tags in MarkdownToDjot (#190)
Full Changelog: 0.1.27...0.1.28
0.1.27
Fixes
- Fix list-item
{.x}attribute line wrongly terminating the list when more indented content follows; the rule is now "attaches to<li>only when last content line of the item" (#186). - Strip
<ol>-only HTML attributes (start,type,reversed) from rendered<li>and<dd>output to avoid emitting invalid HTML when authored on a list item (#187). - Fix lone marker line wrongly starting a block in significantNewlines mode (#180).
- Fix auto-generated heading IDs colliding with explicit ones by reserving explicit IDs first and rewriting refs post-parse (#184).
- Exclude symbols from auto-generated heading identifiers (#181).
Improvements
- Make auto-generated heading IDs ASCII-safe via transliteration (#183).
- Add
bin/djot-watchlive-preview CLI (#178).
Full Changelog: 0.1.26...0.1.27
0.1.26
Fixes
- Fix unindented paragraph being absorbed as list item continuation when a list item contains a nested block followed by a blank line (#177).
Full Changelog: 0.1.25...0.1.26
0.1.25
Fixes
- Fix O(n²) performance issue with single quote smart quote matching (#172)
- Fix HtmlToDjot container and list block serialization (#173)
- Preserve unsupported figures as raw HTML blocks (#171)
- Fix SemanticSpanExtension samp and var rendering (#170)
- Fix HtmlToDjot inline quote escaping (#169)
- Fix HtmlToDjot multiline attribution and captions (#167)
- Fix HtmlToDjot MathML extraction edge cases (#166)
- Fix HtmlToDjot block structure edge cases (#164)
- Fix HtmlToDjot edge cases for divs, titles, and nested tables (#163)
- Normalize configured schemes and fix XHTML footnotes (#162)
- Fix protocol-relative link policy handling and heading ID deduplication (#161)
Improvements
- Add semantic HTML element support to HtmlToDjot (kbd, dfn, abbr, samp, var, q) (#168)
- Add HTML→Djot enhancements: attribution, wrapper unwrap, MathML (#165)
- Add extended round-trip support for reference links, autolinks, custom heading IDs, mentions, tables, and inline code (#157)
- Add footnote and admonition round-trip support with data attributes (#157)
- Add line block and raw inline round-trip support (#158)
- Add abbreviation and escaped character round-trip support (#159)
Full Changelog: 0.1.24...0.1.25
0.1.24
New Features
-
Add
data-djot-srcattribute for visual editor round-trip support - #154- Standalone code blocks now include the attribute in round-trip mode
- CodeGroupExtension preserves
::: code-groupsyntax - TabsExtension preserves
:::: tabssyntax with content - MermaidExtension preserves ``` mermaid blocks
This enables WYSIWYG editors to accurately reconstruct Djot source when users switch between visual and text modes.
Fixes
- Fix MermaidExtension XSS vulnerability - escape
<and&while preserving>for arrow syntax - Fix code fence selection to use
findSafeCodeFence()throughout, preventing conflicts with backticks in content - Fix TabsExtension to preserve wrapper and tab attributes during round-trip
- Fix TabsExtension to handle inline formatting (Strong, Emphasis, Link, Image, BlockQuote) in tab content
Full Changelog: 0.1.23...0.1.24
0.1.23
Breaking Changes
SoftBreakModeis now independent ofsignificantNewlines- #141- Users relying on
withSignificantNewlines()to render soft breaks as<br>need to explicitly set the mode:// Before (implicit) $converter = DjotConverter::withSignificantNewlines(); // After (explicit) $converter = DjotConverter::withSignificantNewlines( softBreakMode: SoftBreakMode::Break, );
- Users relying on
Since this are not DJOT default, but compatibility, no direct major just yet.
There is also a clear upgrade guide, and the BC restore is trivial.
New Features
- Add explicit AST transforms - #149:
HeadingShiftTransformfor shifting heading levelsInlineFootnotesToParenthesesTransformfor non-HTML renderers
- Add
roundTripModefor perfect Djot→HTML→Djot round-tripsThis is needed for WYSIWYG editors and "text mode fallback"$converter = new DjotConverter(roundTripMode: true);
- Extension syntax preserved in round-trip mode - #150
Fixes
- Fix alphabetic list continuation with ambiguous markers
- Fix display math round-trip in MarkdownToDjot converter
- Fix task list checkbox handling in HtmlToDjot converter
- Fix tabs rendering state leaks and heading refs - #144
- Fix TabsExtension breaking TableOfContentsExtension - #140
Improvements
- Default code block tab width changed to 4 spaces - #142
- Refactor HtmlRenderer state into explicit render context - #145
- Add composition API for clean parser/renderer separation - #143
Full Changelog: 0.1.22...0.1.23
0.1.22
New Extensions
InlineFootnotesExtension
Converts [content]{.fn} spans to inline footnotes, allowing footnote content to be written inline with the text.
$converter = new DjotConverter();
$converter->addExtension(new InlineFootnotesExtension());
$html = $converter->convert('Text[An inline footnote]{.fn} here.');- Integrates seamlessly with regular footnotes (shared numbering)
- Supports full inline formatting in footnote content
- Uses span-with-class syntax to avoid conflicts with djot's superscript syntax
HeadingReferenceExtension
Resolves [[Heading Text]] references to headings in the current document.
$converter = new DjotConverter();
$converter->addExtension(new HeadingReferenceExtension());
$html = $converter->convert(<<<'DJOT'
See [[Getting Started]] for details.
# Getting Started
DJOT);
// Links to #Getting-StartedFeatures:
- Custom display text:
[[Heading Text|click here]] - Uses explicit heading IDs when available
- Smart quote normalization for reliable matching
- Falls back to literal
[[...]]text for missing/duplicate headings
Note: Cannot be used together with WikilinksExtension (both parse [[...]] syntax).
Fixes
- Fixed div fence class merging with attribute block classes - #137
- Fixed TabsExtension breaking TableOfContentsExtension - #140
Improvements
- Added
registerInlineFootnote()method toHtmlRendererfor extension use
Full Changelog: 0.1.21...0.1.22