Page changelog: Source version: Markbridge 0.4.2. These docs are built from the repository and may include unreleased changes. Source page: https://markbridge.dev/changelog/
# Changelog
> Release notes for Markbridge, sourced from GitHub Releases.
### v0.4.2 — 2026-09-18
Caution
This release contains breaking changes — see [UPGRADING.md](https://github.com/discourse/markbridge/blob/v0.4.2/UPGRADING.md) before updating.
#### Bug Fixes
* Render aligned blocks as Markdown islands and indent nested lists relatively ([#86](https://github.com/discourse/markbridge/pull/86))
**Full Changelog**:
***
### v0.4.1 — 2026-09-03
Caution
This release contains breaking changes — see [UPGRADING.md](https://github.com/discourse/markbridge/blob/v0.4.1/UPGRADING.md) before updating.
#### Bug Fixes
* Always escape setext heading underlines ([#82](https://github.com/discourse/markbridge/pull/82))
**Full Changelog**:
***
### v0.4.0 — 2026-07-28
Caution
This release contains breaking changes — see [UPGRADING.md](https://github.com/discourse/markbridge/blob/v0.4.0/UPGRADING.md) before updating.
#### Features
* Add a block flag to AST::Code ([#72](https://github.com/discourse/markbridge/pull/72))
* Match AST subclasses by ancestry in rules and tag dispatch ([#72](https://github.com/discourse/markbridge/pull/72))
* Add HTML heading parsing and the shared html\_mode example ([#70](https://github.com/discourse/markbridge/pull/70))
#### Bug Fixes
* Improve code language detection and drop empty element output ([#70](https://github.com/discourse/markbridge/pull/70))
**Full Changelog**:
***
### v0.3.1 — 2026-07-20
#### Features
* Add an AST normalization pass for target-format nesting rules ([#67](https://github.com/discourse/markbridge/pull/67))
**Full Changelog**:
***
### v0.3.0 — 2026-07-09
Caution
This release contains breaking changes — see [UPGRADING.md](https://github.com/discourse/markbridge/blob/v0.3.0/UPGRADING.md) before updating.
#### Features
* Expose the bare-link judgment as AST::Url#bare? ([#62](https://github.com/discourse/markbridge/pull/62))
* Let tag overrides fall back to the stock rendering ([#62](https://github.com/discourse/markbridge/pull/62))
* Keep bare and relative URLs intact in UrlTag ([#62](https://github.com/discourse/markbridge/pull/62))
#### Bug Fixes
* Model quote attributions with honest names and types ([#62](https://github.com/discourse/markbridge/pull/62))
#### Performance
BBCode and MediaWiki now convert roughly twice as fast, HTML about 1.5×, with allocations down 3–9.5× depending on the format. Multibyte text no longer carries a penalty — scanning non-ASCII BBCode was up to 5× slower than ASCII and is now at parity.
* Trim TextFormatter per-parse and per-element overhead ([#61](https://github.com/discourse/markbridge/pull/61))
* Cut the HTML tree walk’s per-node overhead ([#61](https://github.com/discourse/markbridge/pull/61))
* Build the MediaWiki inline tag registry only once ([#60](https://github.com/discourse/markbridge/pull/60))
* Convert the MediaWiki inline parser to byte-offset jump scanning ([#60](https://github.com/discourse/markbridge/pull/60))
* Skip the line split for single-line text in MarkdownEscaper ([#59](https://github.com/discourse/markbridge/pull/59))
* Turn RenderContext into a linked parent chain ([#59](https://github.com/discourse/markbridge/pull/59))
* Cut small allocations in the parse and render hot paths ([#58](https://github.com/discourse/markbridge/pull/58))
* Convert the BBCode scanner to byte offsets ([#58](https://github.com/discourse/markbridge/pull/58))
* Build the default handler registry and tag library only once ([#58](https://github.com/discourse/markbridge/pull/58))
**Full Changelog**:
***
### v0.2.1 — 2026-07-06
#### Removed
* Removed the `Markbridge::Processors::DiscourseMarkdown` module — the scanner and the mention/poll/event/upload detectors. This code is moving into the Discourse migrations tooling. ([#56](https://github.com/discourse/markbridge/pull/56))
**Full Changelog**:
***
### v0.2.0 — 2026-06-11
#### Breaking Changes
The migration API was redesigned around structured result types ([#30](https://github.com/discourse/markbridge/pull/30)). [UPGRADING.md](https://github.com/discourse/markbridge/blob/v0.2.0/UPGRADING.md) has before/after examples for every change.
* `parse_*` methods now return a `Parse` and `*_to_markdown` / `convert` return a `Conversion` instead of raw `String`s — use `Conversion#markdown` (or `#to_s`) for the output ([#30](https://github.com/discourse/markbridge/pull/30))
* Global configuration is gone: `Markbridge::Configuration`, `.configure`, `.reset_defaults!`, and all `default_*` accessors were removed — build a reusable renderer with `Markbridge.discourse_renderer(...)` and pass it via `renderer:` ([#30](https://github.com/discourse/markbridge/pull/30))
* `tags:`, `tag_library:`, `escaper:`, and `escape_hard_line_breaks:` were removed from the per-call signatures; `*_to_markdown` / `convert` accept only `handlers:`, `renderer:`, and `raise_on_error:` ([#30](https://github.com/discourse/markbridge/pull/30))
* Proc/lambda handlers are no longer supported — handlers must be objects responding to `#process(...)` ([#30](https://github.com/discourse/markbridge/pull/30))
* MediaWiki parser kwarg renamed: `inline_tag_registry:` → `handlers:` ([#30](https://github.com/discourse/markbridge/pull/30))
* TextFormatter handlers must accept a `processor:` keyword ([#30](https://github.com/discourse/markbridge/pull/30))
#### Features
* `Markbridge.discourse_renderer(...)` factory builds reusable `Renderer` instances — accepts `tags:`, `tag_library:`, `unregister:`, `escaper:`, `escape:`, `escape_hard_line_breaks:`, `allow:`, `postprocessor:`, `strip_trailing_invisibles:` ([#30](https://github.com/discourse/markbridge/pull/30))
* `Markbridge.convert(format:)` dispatcher and polymorphic `Markbridge.render(Parse | AST::Node)` ([#30](https://github.com/discourse/markbridge/pull/30))
* AST mutation between parse and render: block form on every `*_to_markdown` / `convert`, plus `AST::Element#each_descendant`, `#descendants(klass = nil)`, and `#replace_child(old, new)` ([#30](https://github.com/discourse/markbridge/pull/30))
* `raise_on_error: false` collects render errors on `Conversion#errors` for per-row failure isolation in batch migrations ([#30](https://github.com/discourse/markbridge/pull/30))
* Selective Markdown escaping via `MarkdownEscaper#allow:` (`:bullet_list`, `:ordered_list`, `:atx_heading`, `:block_quote`, alias `:lists`), and `IdentityEscaper` / `discourse_renderer(escape: false)` for already-trusted Markdown ([#30](https://github.com/discourse/markbridge/pull/30))
* Handler registries gain `#overlay(name) { |previous| ... }` for wrapping default handlers (BBCode, HTML, TextFormatter) ([#30](https://github.com/discourse/markbridge/pull/30))
* `TagLibrary#unregister` — unregistered AST classes auto-pass-through to their rendered children ([#30](https://github.com/discourse/markbridge/pull/30))
* HTML and TextFormatter parsers accept pre-parsed Nokogiri input (`DocumentFragment`, `Document`, `Element`) in addition to Strings ([#30](https://github.com/discourse/markbridge/pull/30))
* `AST::Details` + `DetailsTag` for Discourse `[details=…]…[/details]` collapsible sections ([#30](https://github.com/discourse/markbridge/pull/30))
* Optional strip\_trailing\_invisibles config flag ([#39](https://github.com/discourse/markbridge/pull/39))
* Collapse whitespace in HTML per spec ([#36](https://github.com/discourse/markbridge/pull/36))
* Map inline span styles to AST formatting nodes ([#34](https://github.com/discourse/markbridge/pull/34))
#### Bug Fixes
* Make RenderContext parent-queries answer is\_a? semantics ([#42](https://github.com/discourse/markbridge/pull/42))
* Move ] label-escape into MarkdownEscaper so image-in-link works ([#41](https://github.com/discourse/markbridge/pull/41))
* Escape ] in link labels to prevent early link termination ([#40](https://github.com/discourse/markbridge/pull/40))
* Insert blank line between raw text and following block elements ([#37](https://github.com/discourse/markbridge/pull/37))
* Skip \[u] wrapper inside \[url] and \[email] ([#36](https://github.com/discourse/markbridge/pull/36))
* Skip \[u] wrapper when underline content is whitespace-only ([#35](https://github.com/discourse/markbridge/pull/35))
* Treat Unicode whitespace as whitespace in RenderingInterface#wrap\_inline ([#33](https://github.com/discourse/markbridge/pull/33))
**Full Changelog**:
***
### v0.1.3 — 2026-05-07
#### Bug Fixes
* Treat \r as part of CRLF terminator in MarkdownEscaper ([#32](https://github.com/discourse/markbridge/pull/32))
**Full Changelog**:
***
### v0.1.2 — 2026-05-05
#### Features
* Make BBCode HandlerRegistry and Discourse TagLibrary enumerable ([#28](https://github.com/discourse/markbridge/pull/28))
#### Bug Fixes
* Name receiver class in AST::Element#<< type error ([#28](https://github.com/discourse/markbridge/pull/28))
* Copy text into a fresh buffer in AST::Text ([#28](https://github.com/discourse/markbridge/pull/28))
* Render Markdown as HTML inside the table fallback (html\_mode) ([#26](https://github.com/discourse/markbridge/pull/26))
**Full Changelog**:
***
### v0.1.1 — 2026-04-24
#### Features
* Add Markdown table support with HTML fallback ([#13](https://github.com/discourse/markbridge/pull/13))
#### Bug Fixes
* Drop raw-text and metadata HTML elements entirely ([#16](https://github.com/discourse/markbridge/pull/16))
* Emit trailing blank line after quotes ([#21](https://github.com/discourse/markbridge/pull/21))
* Emit trailing blank line after more block-level tags ([#22](https://github.com/discourse/markbridge/pull/22))
**Full Changelog**:
***
### v0.1.0 — 2026-03-31
**Full Changelog**: