module SsKaTeX::Utils

This is a module with miscellaneous utility functions needed by SsKaTeX.

Constants

JSRUN_FROMSYM

ExecJS uses runtime = Runtimes.const_get(name) without checks. That is fragile and potentially insecure with arbitrary user input. Instead we use a fixed dictionary restricted to valid contents. Note that there are aliases like SpiderMonkey = Spidermonkey.

JSRUN_TOSYM

Subclasses of ExecJS::Runtime provide .name (which is too verbose), but not, say, .symbol. This dictionary associates each JS runtime class with a representative symbol. For aliases like SpiderMonkey = Spidermonkey, an unspecified choice is made.

JS_ESCAPE

Dictionary for escape sequences used in Javascript string literals

Public Class Methods

dedup_keys(conf) click to toggle source

Configuration dicts may contain keys in both string and symbol form. This bloats the output of .to_json with duplicate key-value pairs. While this does not affect the result, it looks strange in logfiles. Therefore here is a function that recursively dedups dict keys, removing symbolic keys if there are corresponding string keys. Nondestructive.

# File lib/sskatex.rb, line 167
def dedup_keys(conf)
  # Lazy solution would be: JSON.parse(conf.to_json)
  case conf
  when Hash
    conf.reject {|key, _| key.is_a?(Symbol) && conf.has_key?(key.to_s)}.
      tap {|dict| dict.each {|key, value| dict[key] = dedup_keys(value)}}
  when Array
    conf.map {|value| dedup_keys(value)}
  else
    conf
  end
end
js_quote(str) click to toggle source

Turn a string into an equivalent Javascript literal, double-quoted. Similar to .to_json, but escape all non-ASCII codes as well.

# File lib/sskatex.rb, line 143
def js_quote(str)
  # No portable way of escaping Unicode points above 0xFFFF
  '"%s"' % str.encode(Encoding::UTF_8).
  gsub(/[\0-\u{001F}\"\\\u{0080}-\u{FFFF}]/u) do |c|
    JS_ESCAPE[c] || "\\u%04x" % c.ord
  end
end
js_runtimes() click to toggle source

This should really be provided by ExecJS::Runtimes: A list of available JS engines, as symbols, in the order of preference.

# File lib/sskatex.rb, line 153
def js_runtimes
  # Ruby 2.3+:
  # ExecJS::Runtimes.runtimes.select(&:available?).map(&JSRUN_TOSYM)
  ExecJS::Runtimes.runtimes.select(&:available?).map do |runtime|
    JSRUN_TOSYM[runtime]
  end
end