Module: Markbridge

Defined in:
lib/markbridge.rb,
lib/markbridge/ast.rb,
lib/markbridge/parse.rb,
lib/markbridge/ast/url.rb,
lib/markbridge/version.rb,
lib/markbridge/ast/bold.rb,
lib/markbridge/ast/code.rb,
lib/markbridge/ast/list.rb,
lib/markbridge/ast/node.rb,
lib/markbridge/ast/poll.rb,
lib/markbridge/ast/size.rb,
lib/markbridge/ast/text.rb,
lib/markbridge/ast/align.rb,
lib/markbridge/ast/color.rb,
lib/markbridge/ast/email.rb,
lib/markbridge/ast/event.rb,
lib/markbridge/ast/image.rb,
lib/markbridge/ast/quote.rb,
lib/markbridge/ast/table.rb,
lib/markbridge/ast/italic.rb,
lib/markbridge/ast/upload.rb,
lib/markbridge/conversion.rb,
lib/markbridge/gem_loader.rb,
lib/markbridge/processors.rb,
lib/markbridge/ast/details.rb,
lib/markbridge/ast/element.rb,
lib/markbridge/ast/heading.rb,
lib/markbridge/ast/mention.rb,
lib/markbridge/ast/spoiler.rb,
lib/markbridge/ast/document.rb,
lib/markbridge/parsers/html.rb,
lib/markbridge/ast/list_item.rb,
lib/markbridge/ast/paragraph.rb,
lib/markbridge/ast/subscript.rb,
lib/markbridge/ast/underline.rb,
lib/markbridge/ast/attachment.rb,
lib/markbridge/ast/line_break.rb,
lib/markbridge/parsers/bbcode.rb,
lib/markbridge/ast/superscript.rb,
lib/markbridge/ast/markdown_text.rb,
lib/markbridge/ast/strikethrough.rb,
lib/markbridge/parsers/media_wiki.rb,
lib/markbridge/ast/horizontal_rule.rb,
lib/markbridge/parsers/html/parser.rb,
lib/markbridge/renderers/discourse.rb,
lib/markbridge/parsers/bbcode/parser.rb,
lib/markbridge/parsers/bbcode/scanner.rb,
lib/markbridge/parsers/text_formatter.rb,
lib/markbridge/renderers/discourse/tag.rb,
lib/markbridge/parsers/media_wiki/parser.rb,
lib/markbridge/parsers/bbcode/parser_state.rb,
lib/markbridge/parsers/bbcode/tokens/token.rb,
lib/markbridge/renderers/discourse/renderer.rb,
lib/markbridge/parsers/html/handler_registry.rb,
lib/markbridge/parsers/text_formatter/parser.rb,
lib/markbridge/processors/discourse_markdown.rb,
lib/markbridge/parsers/bbcode/handler_registry.rb,
lib/markbridge/renderers/discourse/tag_library.rb,
lib/markbridge/parsers/bbcode/tokens/text_token.rb,
lib/markbridge/parsers/media_wiki/inline_parser.rb,
lib/markbridge/renderers/discourse/html_escaper.rb,
lib/markbridge/renderers/discourse/tags/url_tag.rb,
lib/markbridge/parsers/bbcode/raw_content_result.rb,
lib/markbridge/parsers/html/handlers/raw_handler.rb,
lib/markbridge/parsers/html/handlers/url_handler.rb,
lib/markbridge/renderers/discourse/postprocessor.rb,
lib/markbridge/renderers/discourse/tags/bold_tag.rb,
lib/markbridge/renderers/discourse/tags/code_tag.rb,
lib/markbridge/renderers/discourse/tags/list_tag.rb,
lib/markbridge/renderers/discourse/tags/poll_tag.rb,
lib/markbridge/renderers/discourse/tags/size_tag.rb,
lib/markbridge/parsers/bbcode/peekable_enumerator.rb,
lib/markbridge/parsers/html/handlers/base_handler.rb,
lib/markbridge/parsers/html/handlers/list_handler.rb,
lib/markbridge/parsers/html/handlers/span_handler.rb,
lib/markbridge/renderers/discourse/render_context.rb,
lib/markbridge/renderers/discourse/tags/align_tag.rb,
lib/markbridge/renderers/discourse/tags/color_tag.rb,
lib/markbridge/renderers/discourse/tags/email_tag.rb,
lib/markbridge/renderers/discourse/tags/event_tag.rb,
lib/markbridge/renderers/discourse/tags/image_tag.rb,
lib/markbridge/renderers/discourse/tags/quote_tag.rb,
lib/markbridge/renderers/discourse/tags/table_tag.rb,
lib/markbridge/parsers/bbcode/handlers/raw_handler.rb,
lib/markbridge/parsers/bbcode/handlers/url_handler.rb,
lib/markbridge/parsers/bbcode/tokens/tag_end_token.rb,
lib/markbridge/parsers/html/handlers/image_handler.rb,
lib/markbridge/parsers/html/handlers/quote_handler.rb,
lib/markbridge/parsers/html/handlers/table_handler.rb,
lib/markbridge/renderers/discourse/tags/italic_tag.rb,
lib/markbridge/renderers/discourse/tags/upload_tag.rb,
lib/markbridge/parsers/bbcode/handlers/base_handler.rb,
lib/markbridge/parsers/bbcode/handlers/code_handler.rb,
lib/markbridge/parsers/bbcode/handlers/list_handler.rb,
lib/markbridge/parsers/bbcode/handlers/size_handler.rb,
lib/markbridge/parsers/bbcode/raw_content_collector.rb,
lib/markbridge/parsers/html/handlers/simple_handler.rb,
lib/markbridge/renderers/discourse/identity_escaper.rb,
lib/markbridge/renderers/discourse/markdown_escaper.rb,
lib/markbridge/renderers/discourse/tags/details_tag.rb,
lib/markbridge/renderers/discourse/tags/heading_tag.rb,
lib/markbridge/renderers/discourse/tags/mention_tag.rb,
lib/markbridge/renderers/discourse/tags/spoiler_tag.rb,
lib/markbridge/parsers/bbcode/handlers/align_handler.rb,
lib/markbridge/parsers/bbcode/handlers/color_handler.rb,
lib/markbridge/parsers/bbcode/handlers/email_handler.rb,
lib/markbridge/parsers/bbcode/handlers/image_handler.rb,
lib/markbridge/parsers/bbcode/handlers/quote_handler.rb,
lib/markbridge/parsers/bbcode/handlers/table_handler.rb,
lib/markbridge/parsers/bbcode/tokens/tag_start_token.rb,
lib/markbridge/processors/discourse_markdown/scanner.rb,
lib/markbridge/parsers/bbcode/closing_strategies/base.rb,
lib/markbridge/parsers/bbcode/handlers/simple_handler.rb,
lib/markbridge/parsers/media_wiki/inline_tag_registry.rb,
lib/markbridge/renderers/discourse/tags/list_item_tag.rb,
lib/markbridge/renderers/discourse/tags/paragraph_tag.rb,
lib/markbridge/renderers/discourse/tags/subscript_tag.rb,
lib/markbridge/renderers/discourse/tags/table_row_tag.rb,
lib/markbridge/renderers/discourse/tags/underline_tag.rb,
lib/markbridge/parsers/bbcode/handlers/spoiler_handler.rb,
lib/markbridge/parsers/html/handlers/list_item_handler.rb,
lib/markbridge/parsers/html/handlers/paragraph_handler.rb,
lib/markbridge/parsers/html/handlers/table_row_handler.rb,
lib/markbridge/parsers/text_formatter/handler_registry.rb,
lib/markbridge/renderers/discourse/rendering_interface.rb,
lib/markbridge/renderers/discourse/tags/attachment_tag.rb,
lib/markbridge/renderers/discourse/tags/line_break_tag.rb,
lib/markbridge/renderers/discourse/tags/table_cell_tag.rb,
lib/markbridge/parsers/bbcode/closing_strategies/strict.rb,
lib/markbridge/parsers/html/handlers/table_cell_handler.rb,
lib/markbridge/renderers/discourse/tags/superscript_tag.rb,
lib/markbridge/parsers/bbcode/handlers/list_item_handler.rb,
lib/markbridge/parsers/bbcode/handlers/table_row_handler.rb,
lib/markbridge/parsers/bbcode/handlers/attachment_handler.rb,
lib/markbridge/parsers/bbcode/handlers/table_cell_handler.rb,
lib/markbridge/parsers/html/handlers/self_closing_handler.rb,
lib/markbridge/renderers/discourse/tags/strikethrough_tag.rb,
lib/markbridge/parsers/text_formatter/handlers/url_handler.rb,
lib/markbridge/parsers/bbcode/closing_strategies/reordering.rb,
lib/markbridge/parsers/bbcode/handlers/self_closing_handler.rb,
lib/markbridge/parsers/text_formatter/handlers/base_handler.rb,
lib/markbridge/parsers/text_formatter/handlers/code_handler.rb,
lib/markbridge/parsers/text_formatter/handlers/list_handler.rb,
lib/markbridge/processors/discourse_markdown/detectors/base.rb,
lib/markbridge/processors/discourse_markdown/detectors/poll.rb,
lib/markbridge/renderers/discourse/tags/horizontal_rule_tag.rb,
lib/markbridge/parsers/text_formatter/handlers/email_handler.rb,
lib/markbridge/parsers/text_formatter/handlers/image_handler.rb,
lib/markbridge/parsers/text_formatter/handlers/quote_handler.rb,
lib/markbridge/processors/discourse_markdown/detectors/event.rb,
lib/markbridge/parsers/bbcode/errors/max_depth_exceeded_error.rb,
lib/markbridge/parsers/text_formatter/handlers/simple_handler.rb,
lib/markbridge/processors/discourse_markdown/detectors/upload.rb,
lib/markbridge/renderers/discourse/builders/list_item_builder.rb,
lib/markbridge/processors/discourse_markdown/detectors/mention.rb,
lib/markbridge/parsers/bbcode/closing_strategies/tag_reconciler.rb,
lib/markbridge/processors/discourse_markdown/code_block_tracker.rb,
lib/markbridge/parsers/text_formatter/handlers/attribute_handler.rb,
lib/markbridge/parsers/text_formatter/handlers/attachment_handler.rb,
lib/markbridge/parsers/text_formatter/handlers/table_cell_handler.rb

Defined Under Namespace

Modules: AST, GemLoader, Parsers, Processors, Renderers Classes: Conversion, Parse

Constant Summary collapse

VERSION =
"0.2.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#astAST::Document (readonly)

Returns delegated to Markbridge::Parse#ast.

Returns:



19
# File 'lib/markbridge/parse.rb', line 19

Parse = Data.define(:ast, :format, :unknown_tags, :diagnostics)

#diagnosticsHash{Symbol => Object} (readonly)

Returns delegated to Markbridge::Parse#diagnostics.

Returns:



19
# File 'lib/markbridge/parse.rb', line 19

Parse = Data.define(:ast, :format, :unknown_tags, :diagnostics)

#errorsArray<StandardError> (readonly)

Returns render-time errors collected when raise_on_error: false was passed; empty otherwise.

Returns:

  • (Array<StandardError>)

    render-time errors collected when raise_on_error: false was passed; empty otherwise.



30
31
32
33
34
35
36
37
38
39
# File 'lib/markbridge/conversion.rb', line 30

Conversion =
Data.define(:parsed, :markdown, :errors) do
  def ast = parsed.ast
  def format = parsed.format
  def unknown_tags = parsed.unknown_tags
  def diagnostics = parsed.diagnostics

  # Allows +puts result+ and +"text: #{result}"+ to work seamlessly.
  def to_s = markdown
end

#formatSymbol? (readonly)

Returns delegated to Markbridge::Parse#format.

Returns:



19
# File 'lib/markbridge/parse.rb', line 19

Parse = Data.define(:ast, :format, :unknown_tags, :diagnostics)

#markdownString (readonly)

Returns the rendered Discourse-flavored Markdown.

Returns:

  • (String)

    the rendered Discourse-flavored Markdown



30
31
32
33
34
35
36
37
38
39
# File 'lib/markbridge/conversion.rb', line 30

Conversion =
Data.define(:parsed, :markdown, :errors) do
  def ast = parsed.ast
  def format = parsed.format
  def unknown_tags = parsed.unknown_tags
  def diagnostics = parsed.diagnostics

  # Allows +puts result+ and +"text: #{result}"+ to work seamlessly.
  def to_s = markdown
end

#parsedParse (readonly)

Returns the parsed input — also reusable for a direct re-render via Markbridge.render(conversion.parsed, …).

Returns:

  • (Parse)

    the parsed input — also reusable for a direct re-render via Markbridge.render(conversion.parsed, …).



30
31
32
33
34
35
36
37
38
39
# File 'lib/markbridge/conversion.rb', line 30

Conversion =
Data.define(:parsed, :markdown, :errors) do
  def ast = parsed.ast
  def format = parsed.format
  def unknown_tags = parsed.unknown_tags
  def diagnostics = parsed.diagnostics

  # Allows +puts result+ and +"text: #{result}"+ to work seamlessly.
  def to_s = markdown
end

#unknown_tagsHash{String => Integer} (readonly)

Returns delegated to Markbridge::Parse#unknown_tags.

Returns:



19
# File 'lib/markbridge/parse.rb', line 19

Parse = Data.define(:ast, :format, :unknown_tags, :diagnostics)

Class Method Details

.bbcode_to_markdown(input, handlers: nil, renderer: nil, raise_on_error: true) {|ast| ... } ⇒ Conversion

Convert BBCode to Discourse Markdown.

If a block is given, it is called with the parsed AST between parse and render — the caller can append/remove/replace nodes before rendering. Mutations to the yielded AST persist in Markbridge::Conversion#ast.

Parameters:

Yield Parameters:

Returns:



49
50
51
52
53
# File 'lib/markbridge.rb', line 49

def bbcode_to_markdown(input, handlers: nil, renderer: nil, raise_on_error: true)
  parse = parse_bbcode(input, handlers:)
  yield(parse.ast) if block_given?
  build_conversion(parse, renderer:, raise_on_error:)
end

.convert(input, format:, **kwargs) {|ast| ... } ⇒ Conversion

Convert input in the given format. Thin dispatcher over the four *_to_markdown methods; useful when the format is data- driven (e.g. iterating posts whose :format column varies). An optional block is forwarded to the dispatched method.

Parameters:

  • input (String, Nokogiri::XML::Node)

    source content; the HTML and TextFormatter dispatch targets also accept pre-parsed Nokogiri trees.

  • format (Symbol)

    one of :bbcode, :html, :text_formatter_xml, :mediawiki

  • kwargs (Hash)

    forwarded to the underlying convenience method (e.g. handlers:, renderer:, raise_on_error:).

Yield Parameters:

Returns:



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/markbridge.rb', line 180

def convert(input, format:, **kwargs, &block)
  case format
  when :bbcode
    bbcode_to_markdown(input, **kwargs, &block)
  when :html
    html_to_markdown(input, **kwargs, &block)
  when :text_formatter_xml
    text_formatter_xml_to_markdown(input, **kwargs, &block)
  when :mediawiki
    mediawiki_to_markdown(input, **kwargs, &block)
  else
    raise ArgumentError,
          "unknown format #{format.inspect} " \
            "(expected :bbcode, :html, :text_formatter_xml, or :mediawiki)"
  end
end

.discourse_renderer(tags: nil, tag_library: nil, unregister: nil, escaper: nil, escape: true, escape_hard_line_breaks: false, allow: nil, postprocessor: nil, strip_trailing_invisibles: false) ⇒ Renderers::Discourse::Renderer

Build a configured Discourse Markbridge::Renderers::Discourse::Renderer for use with the renderer: kwarg on the *_to_markdown convenience methods.

Parameters:

  • tags (Hash{Class => Tag, nil}, nil) (defaults to: nil)

    mappings to merge on top of the default library; nil values unregister the class.

  • tag_library (Renderers::Discourse::TagLibrary, nil) (defaults to: nil)

    base library to start from. Defaults to a fresh TagLibrary.default. When supplied, it is dup‘d before any tags: / unregister: mutation, so the caller’s library is left untouched.

  • unregister (Array<Class>, nil) (defaults to: nil)

    AST classes to drop from the library so they fall through to render_children.

  • escaper (#escape, nil) (defaults to: nil)

    when given, used as-is; escape:, escape_hard_line_breaks:, and allow: are then ignored.

  • escape (Boolean) (defaults to: true)

    when false, the renderer is built with Markbridge::Renderers::Discourse::IdentityEscaper (no Markdown escaping). Mutually exclusive with escape_hard_line_breaks: / allow:.

  • escape_hard_line_breaks (Boolean) (defaults to: false)

    forwarded to a fresh MarkdownEscaper when no explicit escaper: is given.

  • allow (Symbol, Array<Symbol>, nil) (defaults to: nil)

    block-level constructs to pass through unescaped (e.g. :lists, :bullet_list, :ordered_list, :atx_heading, :block_quote); forwarded to a fresh MarkdownEscaper.

  • postprocessor (Renderers::Discourse::Postprocessor, nil) (defaults to: nil)

    when given, used as-is; strip_trailing_invisibles: is then ignored.

  • strip_trailing_invisibles (Boolean) (defaults to: false)

    forwarded to a fresh Markbridge::Renderers::Discourse::Postprocessor when no explicit postprocessor: is given. Strips NBSP and zero-width format characters from the end of each line.

Returns:



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/markbridge.rb', line 265

def discourse_renderer(
  tags: nil,
  tag_library: nil,
  unregister: nil,
  escaper: nil,
  escape: true,
  escape_hard_line_breaks: false,
  allow: nil,
  postprocessor: nil,
  strip_trailing_invisibles: false
)
  # Dup the caller's library before mutating so successive
  # +discourse_renderer+ calls against the same +tag_library:+ don't
  # see each other's overrides. +TagLibrary.default+ already returns
  # a fresh instance, so the dup is only needed in the explicit
  # +tag_library:+ branch.
  library = tag_library ? tag_library.dup : Renderers::Discourse::TagLibrary.default
  library.merge!(tags) if tags
  Array(unregister).each { |klass| library.unregister(klass) }

  escaper ||= build_escaper(escape:, escape_hard_line_breaks:, allow:)
  postprocessor ||= Renderers::Discourse::Postprocessor.new(strip_trailing_invisibles:)

  Renderers::Discourse::Renderer.new(tag_library: library, escaper:, postprocessor:)
end

.html_to_markdown(input, handlers: nil, renderer: nil, raise_on_error: true) {|ast| ... } ⇒ Conversion

Convert HTML to Discourse Markdown.

If a block is given, it is called with the parsed AST between parse and render — the caller can append/remove/replace nodes before rendering. Mutations to the yielded AST persist in Markbridge::Conversion#ast.

Parameters:

Yield Parameters:

Returns:



90
91
92
93
94
# File 'lib/markbridge.rb', line 90

def html_to_markdown(input, handlers: nil, renderer: nil, raise_on_error: true)
  parse = parse_html(input, handlers:)
  yield(parse.ast) if block_given?
  build_conversion(parse, renderer:, raise_on_error:)
end

.mediawiki_to_markdown(input, handlers: nil, renderer: nil, raise_on_error: true) {|ast| ... } ⇒ Conversion

Convert MediaWiki wikitext to Discourse Markdown.

If a block is given, it is called with the parsed AST between parse and render — the caller can append/remove/replace nodes before rendering. Mutations to the yielded AST persist in Markbridge::Conversion#ast.

Parameters:

Yield Parameters:

Returns:



160
161
162
163
164
# File 'lib/markbridge.rb', line 160

def mediawiki_to_markdown(input, handlers: nil, renderer: nil, raise_on_error: true)
  parse = parse_mediawiki(input, handlers:)
  yield(parse.ast) if block_given?
  build_conversion(parse, renderer:, raise_on_error:)
end

.parse_bbcode(input, handlers: nil) ⇒ Parse

Parse BBCode to AST.

Parameters:

Returns:

Raises:

  • (ArgumentError)


18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/markbridge.rb', line 18

def parse_bbcode(input, handlers: nil)
  raise ArgumentError, "input cannot be nil" if input.nil?

  parser = Parsers::BBCode::Parser.new(handlers:)
  ast = parser.parse(input.to_s)

  Parse.new(
    ast:,
    format: :bbcode,
    unknown_tags: parser.unknown_tags,
    diagnostics: bbcode_diagnostics(parser),
  )
end

.parse_html(input, handlers: nil) ⇒ Parse

Parse HTML to AST.

Parameters:

  • input (String, Nokogiri::XML::Node)

    HTML source or pre-parsed Nokogiri tree (e.g. the DocumentFragment returned by Nokogiri::HTML.fragment). Passing a pre-parsed tree lets callers run their own Nokogiri-driven pre-processing without forcing Markbridge to re-parse the same bytes.

  • handlers (Parsers::HTML::HandlerRegistry, nil) (defaults to: nil)

    custom handlers

Returns:

Raises:

  • (ArgumentError)


64
65
66
67
68
69
70
71
# File 'lib/markbridge.rb', line 64

def parse_html(input, handlers: nil)
  raise ArgumentError, "input cannot be nil" if input.nil?

  parser = Parsers::HTML::Parser.new(handlers:)
  ast = parser.parse(input)

  Parse.new(ast:, format: :html, unknown_tags: parser.unknown_tags, diagnostics: {})
end

.parse_mediawiki(input, handlers: nil) ⇒ Parse

Parse MediaWiki wikitext to AST.

Parameters:

Returns:

Raises:

  • (ArgumentError)


138
139
140
141
142
143
144
145
# File 'lib/markbridge.rb', line 138

def parse_mediawiki(input, handlers: nil)
  raise ArgumentError, "input cannot be nil" if input.nil?

  parser = Parsers::MediaWiki::Parser.new(handlers:)
  ast = parser.parse(input.to_s)

  Parse.new(ast:, format: :mediawiki, unknown_tags: parser.unknown_tags, diagnostics: {})
end

.parse_text_formatter_xml(input, handlers: nil) ⇒ Parse

Parse s9e/TextFormatter XML to AST.

Parameters:

  • input (String, Nokogiri::XML::Node)

    XML source or pre-parsed Nokogiri tree. A Nokogiri::XML::Document is unwrapped via #root; any other node is treated as the root.

  • handlers (Parsers::TextFormatter::HandlerRegistry, nil) (defaults to: nil)

    custom handlers

Returns:

Raises:

  • (ArgumentError)


103
104
105
106
107
108
109
110
111
# File 'lib/markbridge.rb', line 103

def parse_text_formatter_xml(input, handlers: nil)
  raise ArgumentError, "input cannot be nil" if input.nil?

  parser = Parsers::TextFormatter::Parser.new(handlers:)
  ast = parser.parse(input)
  unknown_tags = parser.unknown_tags

  Parse.new(ast:, format: :text_formatter_xml, unknown_tags:, diagnostics: {})
end

.render(parse_or_ast, format: :discourse, renderer: nil, raise_on_error: true) ⇒ Conversion

Render a Parse or a bare AST node to Discourse Markdown. Useful when the caller has mutated the AST between parse and render (e.g. appending attachments not present in the source), or built an AST programmatically.

When given a Parse, the returned Conversion carries the parser’s unknown_tags, diagnostics, and source format forward. When given an AST node, those fields default to empty and format is nil — there was no source document, so there is no source format to report. A bare node that isn’t already a Markbridge::AST::Document is wrapped in one, so Markbridge::Conversion#ast is always a Document (and tree helpers like each_descendant are always available on it).

Parameters:

  • parse_or_ast (Parse, AST::Node)
  • format (Symbol) (defaults to: :discourse)

    :discourse (only renderer currently shipped)

  • renderer (Renderers::Discourse::Renderer, nil) (defaults to: nil)
  • raise_on_error (Boolean) (defaults to: true)

Returns:

Raises:

  • (ArgumentError)


216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/markbridge.rb', line 216

def render(parse_or_ast, format: :discourse, renderer: nil, raise_on_error: true)
  raise ArgumentError, "unknown render format #{format.inspect}" unless format == :discourse

  parse =
    case parse_or_ast
    when Parse
      parse_or_ast
    when AST::Document
      Parse.new(ast: parse_or_ast, format: nil, unknown_tags: {}, diagnostics: {})
    when AST::Node
      document = AST::Document.new([parse_or_ast])
      Parse.new(ast: document, format: nil, unknown_tags: {}, diagnostics: {})
    else
      raise ArgumentError, "expected Parse or AST::Node, got #{parse_or_ast.class}"
    end

  build_conversion(parse, renderer:, raise_on_error:)
end

.text_formatter_xml_to_markdown(input, handlers: nil, renderer: nil, raise_on_error: true) {|ast| ... } ⇒ Conversion

Convert s9e/TextFormatter XML to Discourse Markdown.

If a block is given, it is called with the parsed AST between parse and render — the caller can append/remove/replace nodes before rendering. Mutations to the yielded AST persist in Markbridge::Conversion#ast.

Parameters:

Yield Parameters:

Returns:



127
128
129
130
131
# File 'lib/markbridge.rb', line 127

def text_formatter_xml_to_markdown(input, handlers: nil, renderer: nil, raise_on_error: true)
  parse = parse_text_formatter_xml(input, handlers:)
  yield(parse.ast) if block_given?
  build_conversion(parse, renderer:, raise_on_error:)
end