DEV Community

Alexandr Zahatski
Alexandr Zahatski

Posted on

Coming in Podlite 2.0

The spec branch for Podlite 2.0 has landed in a pull request. The final tag goes up once the review window closes. If you build parsers or ship documents in Podlite, this is the time to read the diff and push back.

Why a major bump? A few real breaking changes (mostly legacy string-attribute syntax that nobody should have been writing anyway), plus four big new features. Bundling them means one parser-side update instead of four spread over time.

Two new directives

=boundary — section dividers with semantics

A divider with semantics. It renders as a horizontal rule, but the parser sees a typed block. A tool building a table of contents, page-splitter, or chapter-navigator knows exactly where one section ends and the next begins. The optional :caption attribute describes the transition (=boundary :caption('Part Two')).

=set — per-block attribute assignment

Pre-configure attributes for the next block. Multiline values via continuation lines, inline markup inside attribute values, and lexical scope per file. The mechanism is useful when an attribute value is too long to sit on the directive line, or when you want to factor common attributes out of repeated blocks.

Content masking

Accept the terms to read G<the full case study>.
Enter fullscreen mode Exit fullscreen mode
=begin para :masked
Premium analysis. Hidden until the reader signs in.
=end para
Enter fullscreen mode Exit fullscreen mode

G<> masks inline content, :masked masks whole blocks. The renderer hides the content by default and shows it once a condition is met — terms accepted, sign-in done, draft mode on. Use it for content released after agreement (T&C, paywall, age gate). Use it for credentials in code samples, PII in case studies, or unreleased details that should live in the source file but stay out of the rendered output.

This hides content at render time. It is one layer of defense-in-depth, not a replacement for source-file access controls or secret-management tools.

Smarter attributes

Markdown fenced code blocks accept attributes

javascript :line-numbers :caption('Example')
const x = 1;

Enter fullscreen mode Exit fullscreen mode

The string after the language tag is now parsed as Podlite attributes. Previous behavior (raw meta string) is preserved when no attribute syntax is present.

L<> takes per-link attributes

L<docs|https://example.com :rel<external> :class<button>>
Enter fullscreen mode Exit fullscreen mode

Settings stay with the link, not scattered through surrounding prose. Existing plain L<text|url> works unchanged.

:mime-type accepts MIME parameters

=begin data :key<planets> :mime-type<'text/csv; header=present'>
  name,radius_km,moons
  Mercury,2440,0
  Venus,6052,0
  Earth,6371,1
  Mars,3390,2
=end data

=for table :caption('Inner planets')
data:planets
Enter fullscreen mode Exit fullscreen mode

The header=present|absent parameter (per RFC 4180 §3) tells the renderer to treat the first row as column labels in =table data:X. The MIME parameter syntax follows RFC 6838.

Reclassifications and fixes

=include is now formally a directive, consistent with =config and =alias. :folded got a tighter definition. =table has explicit error recovery rules. Malformed rows (wrong cell count, mixed separators) now emit a warning and continue, instead of dropping the parser into silent fallback.

Removed: a few outdated string attribute formats. If you write the current syntax, nothing changes.

Read the diff before the tag lands

If something looks off — a broken example, ambiguous wording, an edge case the spec doesn't cover — this is the window. Feedback after the tag is much harder to act on.

Top comments (0)