module Kramdown::Converter::MathEngine::SsKaTeX

Consider this a lightweight alternative to MathjaxNode. Uses KaTeX and ExecJS (via ::SsKaTeX) instead of MathJax and Node.js. Javascript execution context initialization is done only once. As a result, the performance is reasonable.

Constants

DEBUG_LOGGER

A logger that routes messages to the debug channel only. No need to create this dynamically.

KTXC

Class-level cache for ::SsKaTeX converter state, queried by configuration. Note: KTXC contents may become stale if the contents of used JS files change while the configuration remains unchanged.

VERSION

Public Class Methods

call(converter, el, opts) click to toggle source

The function used by kramdown for rendering TeX math to HTML

# File lib/kramdown/converter/math_engine/sskatex.rb, line 74
def call(converter, el, opts)
  display_mode = el.options[:category]
  ans = katex_conv(converter).call(el.value, display_mode == :block, &logger(converter))
  attr = el.attr.dup
  attr.delete('xmlns')
  attr.delete('display')
  ans.insert(ans =~ /[[:space:]>]/, converter.html_attributes(attr))
  ans = ' ' * opts[:indent] << ans << "\n" if display_mode == :block
  ans
end

Private Class Methods

katex_conv(converter) click to toggle source

Given a Kramdown::Converter::Base object converter, return a ::SsKaTeX converter sktx that has been configured with converter's math_engine_opts, but not for logging. Cache sktx for reuse, without references to converter.

# File lib/kramdown/converter/math_engine/sskatex.rb, line 62
def katex_conv(converter)
  config = converter.options[:math_engine_opts]
  # Could .reject { |key, _| [:verbose, :debug].include?(key.to_sym) }
  # because the JS engine setup can be reused for different logging settings.
  # But then the +math_engine_opts+ dict would be essentially dup'ed every time,
  # and late activation of logging would miss the initialization if the engine is reused.
  KTXC[config] ||= ::SsKaTeX.new(config)
end
logger(converter) click to toggle source

Given a Kramdown::Converter::Base object converter, retrieves the logging options and builds an object usable for ::SsKaTeX#logger. The result is either nil (no logging) or a Proc object which, when given a level (either :verbose or :debug) and a block, decides whether logging is enabled, and if so, evaluates the given block for the message and routes that message to the appropriate channels. With level == :verbose+, messages are passed to converter.warning if the converter's :verbose option is set. All messages are passed to warn if the converter's :debug option is set.

Note that the returned logger may contain references to the given converter and is not affected by subsequent changes in the converter's logging options.

# File lib/kramdown/converter/math_engine/sskatex.rb, line 43
def logger(converter)
  config = converter.options[:math_engine_opts]
  debug = config[:debug]
  if config[:verbose]
    # Need a closure
    lambda do |level, &expr|
      verbose = (level == :verbose)
      msg = expr.call if debug || verbose
      warn(msg) if debug
      converter.warning(msg) if verbose
    end
  elsif debug
    DEBUG_LOGGER
  end
end