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 likeSpiderMonkey = 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 likeSpiderMonkey = Spidermonkey
, an unspecified choice is made.- JS_ESCAPE
Dictionary for escape sequences used in Javascript string literals
Public Class Methods
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
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
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