Skip to content

TextFormatter

The TextFormatter parser reads the XML format produced by s9e/TextFormatter, the library phpBB 3.2+ uses to store parsed BBCode. Converting the stored XML directly is faster and more faithful than re-parsing the original BBCode.

Add nokogiri to your Gemfile. It’s a runtime dependency for the TextFormatter parser:

gem "nokogiri"
require "markbridge/textformatter"
xml = "<r><B><s>[b]</s>Hello<e>[/b]</e></B> world!</r>"
result = Markbridge.text_formatter_xml_to_markdown(xml)
result.markdown
# => "**Hello** world!"

TextFormatter wraps content in one of two roots:

  • <t> — plain text (no BBCode was used).
  • <r> — rich text (contains formatted elements).

Inside <r>, formatted children use uppercase element names by convention (<B>, <URL>, <CODE>). Each formatted element may wrap its original BBCode markup in <s> (start) and <e> (end) tags — Markbridge ignores these during parsing.

Element Renders as AST node
<B> **bold** AST::Bold
<I> *italic* AST::Italic
<S> ~~strike~~ AST::Strikethrough
<U> <u>underline</u> AST::Underline
<CODE> Fenced code block, including single-line content AST::Code
<URL> [text](href) AST::Url
<EMAIL> [text](mailto:addr) AST::Url
<IMG> ![](src) AST::Image
<ATTACHMENT> Discourse upload syntax AST::Attachment
<QUOTE> [quote]…[/quote] AST::Quote
<LIST> - item / 1. item AST::List
<LI> List item AST::ListItem
<TABLE>, <TR>, <TD> GFM table AST::Table
<HR> --- AST::HorizontalRule
<br/> Hard line break AST::LineBreak

Several elements carry attributes Markbridge reads: <CODE> (lang), <URL> (url), <EMAIL> (email), <IMG> (src), <LIST> (typebullet or decimal), and <QUOTE> (attribution).

For the exact list, see HandlerRegistry.default.

parser = Markbridge::Parsers::TextFormatter::Parser.new
ast = parser.parse(xml)
renderer = Markbridge::Renderers::Discourse::Renderer.new
renderer.render(ast)
  • Invalid XML falls back to treating the input as plain text instead of raising.
  • Unknown elements are skipped — their children are still processed.
  • Stateless handler API: like the HTML parser, handlers are callables receiving (element:, parent:, processor:). The processor: argument is the parser instance and exposes process_children(xml_element, ast_node) for handlers that want to recurse manually. Lambdas are accepted.

If you’re migrating from phpBB 3.2+ and already have the stored XML, use this parser — it’s both faster and closer to the source of truth than re-parsing the BBCode. For plain BBCode from other forums, use the BBCode parser.