Skip to content

Releases: php-collective/djot-php

0.1.31

Choose a tag to compare

@dereuromark dereuromark released this 05 Jul 22:49
63e6c1b

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

Choose a tag to compare

@dereuromark dereuromark released this 26 Jun 10:54
ff46886

Fixes

  • Security: always-on neutralization of dangerous URL schemes, event-handler / injection-sink attributes (on*, srcdoc, formaction) and CSS expression() in the default renderer (previously gated behind safe mode), plus a cap on inline-nesting depth to bound a parse-time DoS. (#253)
  • Security: HtmlToDjot ignores the data-djot-src / data-djot-raw round-trip attributes when importing untrusted HTML, preventing a crafted attribute from injecting a raw-HTML block; round-trip honoring is opt-in via new 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+FFFD at 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+00A0 in 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 via addExtension(new LineBlockDivExtension()). (#243, #244)
  • New convert CLI in bin/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

Choose a tag to compare

@dereuromark dereuromark released this 07 Jun 14:58
32c0d50

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 - item as 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 call setCodeBlockTabWidth()) 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)
  • blocksInterruptParagraphs now nests a sublist inside a list item, consistent with top-level interruption across nesting levels (#209)
  • New nestedListsWithoutBlankLine lever for compact sublist nesting, the smaller subset of blocksInterruptParagraphs; paragraph interruption made consistent inside lists (#207)
  • Support a div attribute opener (#199)

Full Changelog: 0.1.28...0.1.29

0.1.28

Choose a tag to compare

@dereuromark dereuromark released this 27 May 14:29
afdfce0

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 blocksInterruptParagraphs parser lever and deprecate significantNewlines in favor of the granular parser options (#194)
  • Add experimental citations extension (#193)
  • Add nestedBlocksInLists parser option to nest blocks inside list items without a blank line (#191)
  • Convert kbd, samp, var, abbr, and dfn HTML tags in MarkdownToDjot (#190)

Full Changelog: 0.1.27...0.1.28

0.1.27

Choose a tag to compare

@dereuromark dereuromark released this 20 May 02:52
5017e30

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-watch live-preview CLI (#178).

Full Changelog: 0.1.26...0.1.27

0.1.26

Choose a tag to compare

@dereuromark dereuromark released this 13 Apr 20:56
d176668

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

Choose a tag to compare

@dereuromark dereuromark released this 02 Apr 02:20
f3f6a70

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

Choose a tag to compare

@dereuromark dereuromark released this 31 Mar 04:41
ad98aff

New Features

  • Add data-djot-src attribute for visual editor round-trip support - #154

    • Standalone code blocks now include the attribute in round-trip mode
    • CodeGroupExtension preserves ::: code-group syntax
    • TabsExtension preserves :::: tabs syntax 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

Choose a tag to compare

@dereuromark dereuromark released this 30 Mar 09:04
375c6ae

Breaking Changes

  • SoftBreakMode is now independent of significantNewlines - #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,
      );

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:
    • HeadingShiftTransform for shifting heading levels
    • InlineFootnotesToParenthesesTransform for non-HTML renderers
  • Add roundTripMode for perfect Djot→HTML→Djot round-trips
    $converter = new DjotConverter(roundTripMode: true);
    This is needed for WYSIWYG editors and "text mode fallback"
  • 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

Choose a tag to compare

@dereuromark dereuromark released this 28 Mar 19:40
5b6b08f

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-Started

Features:

  • 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 to HtmlRenderer for extension use

Full Changelog: 0.1.21...0.1.22