class Asciidoctor::Katex::StemConverterDecorator

The converter decorator that renders delimited math expressions in block and inline latexmath stem nodes after.

Public Class Methods

new(converter, math_renderer) click to toggle source

@param converter [Asciidoctor::Converter] the decorated converter to

delegate all method calls to.

@param math_renderer [#call] callable that accepts a math expression

[String] and options [Hash], and returns a rendered expression [String].
Calls superclass method
# File lib/asciidoctor/katex/stem_converter_decorator.rb, line 14
def initialize(converter, math_renderer)
  super(converter)
  @math_renderer = math_renderer
  @block_re = regexp_from_delimiters(::Asciidoctor::BLOCK_MATH_DELIMITERS[:latexmath])
  @inline_re = regexp_from_delimiters(::Asciidoctor::INLINE_MATH_DELIMITERS[:latexmath])
end

Public Instance Methods

convert(node, transform = node.node_name, opts = {}) click to toggle source

@param node [Asciidoctor::AbstractNode] the node to convert. @param transform [String, nil] the conversion method to call. @param opts [Hash] options to pass to the converter. @return [String] output of the converter.

# File lib/asciidoctor/katex/stem_converter_decorator.rb, line 25
def convert(node, transform = node.node_name, opts = {})
  # Call the underlying converter.
  output = __getobj__.convert(node, transform, opts)

  if latexmath? node
    render_latexmath(output, node)
  else
    output
  end
end

Protected Instance Methods

latexmath?(node) click to toggle source

@param node [Asciidoctor::AbstractNode] the AST node to test. @return [Boolean] `true` if the given node is a block or inline latexmath,

`false` otherwise.
# File lib/asciidoctor/katex/stem_converter_decorator.rb, line 54
def latexmath?(node)
  case node.node_name
  when 'stem'
    return true if node.style == 'latexmath'
  when 'inline_quoted'
    return true if node.type == :latexmath
  end
  false
end
render_latexmath(output, node) click to toggle source

@param output [String] the converted node with delimited math expression. @param node [Asciidoctor::AbstractNode] the AST node. @return [String] a copy of output with math expression rendered.

# File lib/asciidoctor/katex/stem_converter_decorator.rb, line 41
def render_latexmath(output, node)
  @throw_on_error ||= node.document.attr('katex-throw-on-error', false)
  isblock = node.block?

  output.sub(isblock ? @block_re : @inline_re) do
    math = decode_html_entities(::Regexp.last_match[1].strip)
    @math_renderer.call(math, display_mode: isblock, throw_on_error: @throw_on_error)
  end
end

Private Instance Methods

decode_html_entities(str) click to toggle source

@param str [String] @return [String]

# File lib/asciidoctor/katex/stem_converter_decorator.rb, line 76
def decode_html_entities(str)
  str.gsub('&lt;', '<')
    .gsub('&gt;', '>')
    .gsub('&amp;', '&')
end
regexp_from_delimiters(delimiters) click to toggle source

@param delimiters [Array<String>] tuple with open and close delimiter. @return [Regexp]

# File lib/asciidoctor/katex/stem_converter_decorator.rb, line 68
def regexp_from_delimiters(delimiters)
  open, close = delimiters.map { |s| ::Regexp.escape(s) }
  # XXX: `[\s\S]+` is used instead of `.+` for compatibility with Opal.
  /#{open}([\s\S]+)#{close}/m
end