# 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

AVAILABLE

  Indicate whether SsKaTeX may be available.

  This test is incomplete; it cannot test the existence of katex_js nor the availability of a specific js_run because those depend on configuration not given here. This test mainly indicates whether static dependencies such as the `sskatex` and `execjs` gems are available.

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.

### 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 82
    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 70
    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 51
    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