Skip to content

Commit 3b25c0b

Browse files
committed
New CLI script bin/sskatex and new Rakefile targets using it.
The script `bin/sskatex` serves as a simple CLI to the SsKaTeX gem. The new Rakefile targets `dev:test_sskatex_deps`, `dev:update_katex_tests` use `bin/sskatex` for availabiity tests and for test reference updates. The latter may become necessary after KaTeX updates.
1 parent 53ba8a3 commit 3b25c0b

File tree

3 files changed

+148
-6
lines changed

3 files changed

+148
-6
lines changed

Rakefile

+39
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,42 @@ end
66

77
desc "Run tests"
88
task default: [:test]
9+
10+
namespace :dev do
11+
desc "Check for SsKaTeX availability"
12+
task :test_sskatex_deps do
13+
katexjs = 'katex/katex.min.js'
14+
raise (<<TKJ) unless File.exists? katexjs
15+
Cannot find file '#{katexjs}'.
16+
You need to download KaTeX e.g. from https://github.com/Khan/KaTeX/releases/
17+
and extract at least '#{katexjs}'.
18+
Alternatively, if you have a copy of KaTeX unpacked somewhere else,
19+
you can create a symbolic link 'katex' pointing to that KaTeX directory.
20+
TKJ
21+
html = `echo a | #{RbConfig.ruby} -Ilib bin/sskatex -v`
22+
raise (<<KTC) unless $?.success?
23+
Some requirement by SsKaTeX or the employed JS engine has not been satisfied.
24+
Cf. the above error messages.
25+
If you 'gem install sskatex', also make sure that some JS engine is available,
26+
e.g. by installing one of the gems 'duktape', 'therubyracer', or 'therubyrhino'.
27+
KTC
28+
raise (<<XJS) unless / class="katex"/ === html
29+
Hmmm... SsKaTeX produces output which does not seem like KaTeX output.
30+
You are experimenting, huh?
31+
XJS
32+
puts "SsKaTeX is available, and its default configuration works."
33+
end
34+
35+
desc "Update SsKaTeX test reference outputs"
36+
task update_katex_tests: [:test_sskatex_deps] do
37+
# Not framed in terms of rake file tasks to prevent accidental overwrites.
38+
['block', 'span'].each do |display|
39+
Dir['test/tex/*.tex'].each do |texfile|
40+
stem = File.basename(texfile, '.tex')
41+
html = File.join('test', display, stem + '.html')
42+
disp = "--#{'no-' if display != 'block'}display"
43+
ruby "-Ilib bin/sskatex #{disp} #{texfile} #{html}"
44+
end
45+
end
46+
end
47+
end

bin/sskatex

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#! /usr/bin/env ruby
2+
require 'json'
3+
require 'safe_yaml'
4+
require 'optparse'
5+
require 'sskatex'
6+
7+
me = File.basename(__FILE__)
8+
9+
# Useful as Hash.merge argument
10+
merge_dicts = lambda do |key, left_val, right_val|
11+
if left_val.class == Hash and right_val.class == Hash
12+
left_val.merge(right_val, &merge_dicts)
13+
else
14+
right_val
15+
end
16+
end
17+
18+
cmd_opts = {}
19+
cfg_opts = {}
20+
config_file = nil
21+
display_mode = nil
22+
OptionParser.new do |opts|
23+
opts.banner = <<USAGE
24+
Usage: #{me} [options] [INFILE [OUTFILE]]
25+
26+
Processes a TeX math fragment from INFILE (default stdin) and
27+
writes corresponding HTML+MathML to OUTFILE (default stdout).
28+
Needs katex.min.js and a Javascript engine to do that.
29+
30+
Options:
31+
USAGE
32+
opts.on('-C CONFIG_FILE', '--config_file=CONFIG_FILE',
33+
'Specify path to YAML configuration file') do |cf|
34+
config_file = cf
35+
end
36+
opts.on('-D', '--[no-]display',
37+
'format math in display style') do |dm|
38+
display_mode = dm
39+
end
40+
opts.on('-J KATEX_JS', '--katex_js=KATEX_JS',
41+
'Specify path to katex.js') do |katex_js|
42+
cmd_opts[:katex_js] = katex_js
43+
end
44+
opts.on('-K JSON', '--katex_opts=JSON',
45+
'Specify KaTeX options') do |katex_opts|
46+
cmd_opts[:katex_opts] = JSON.parse(katex_opts, symbolize_names: true)
47+
end
48+
opts.on('-L JS_DIR', '--js_dir=JS_DIR',
49+
'Specify dir with JS helper files') do |js_dir|
50+
cmd_opts[:js_dir] = js_dir
51+
end
52+
opts.on('-l JS_LIB,...', '--js_libs=JS_LIB,...', Array,
53+
'Specify JS helper files, relative to JS_DIR') do |js_libs|
54+
cmd_opts[:js_libs] = js_libs
55+
end
56+
opts.on('-R JS_RUN', '--js_run=JS_RUN',
57+
'Specify JS engine to use (-v lists choices)') do |js_run|
58+
cmd_opts[:js_run] = js_run
59+
end
60+
opts.on('-d', '--[no-]debug',
61+
'Log JS engine config and usage to stderr') do |d|
62+
cmd_opts[:debug] = d
63+
end
64+
opts.on('-v', '--[no-]verbose',
65+
'Log JS engine configuration to stderr') do |v|
66+
cmd_opts[:verbose] = v
67+
end
68+
opts.on("-h", "--help", "Prints this help and exits") do |h|
69+
if h
70+
puts opts
71+
exit
72+
end
73+
end
74+
end.parse!
75+
76+
if ARGV.size > 2
77+
warn opts
78+
exit 2
79+
end
80+
81+
cfg_opts = JSON.parse(YAML.load(config_file, safe: true).to_json,
82+
symbolize_names: true) if config_file
83+
options = cfg_opts.merge(cmd_opts, &merge_dicts)
84+
loglevel = options[:debug] ? :debug : options[:verbose] ? :verbose : nil
85+
display_mode = !!display_mode
86+
87+
conv = SsKaTeX.new(options, &SsKaTeX.warn_logger(loglevel))
88+
tex = if ARGV.size == 0
89+
$stdin.set_encoding Encoding::UTF_8
90+
$stdin.read
91+
else
92+
IO.read(ARGV.shift, encoding: Encoding::UTF_8)
93+
end.chomp
94+
html = conv.call(tex, display_mode) + "\n"
95+
if ARGV.size == 0
96+
$stdout.set_encoding Encoding::UTF_8
97+
$stdout.write html
98+
else
99+
IO.write(ARGV.shift, html, encoding: Encoding::UTF_8)
100+
end

sskatex.gemspec

+9-6
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
Gem::Specification.new do |s|
1010
s.name = 'sskatex'
11-
s.version = '0.9.24'
12-
s.date = '2017-11-23'
11+
s.version = '0.9.30'
12+
s.date = '2017-11-30'
1313
s.summary = "Server-side KaTeX for Ruby"
1414
s.description = <<DESC
1515
This is a TeX-to-HTML+MathML+CSS converter class using the Javascript-based
@@ -28,15 +28,18 @@ For that reason, the configuration must not be left to untrusted users.
2828
DESC
2929
s.author = "Christian Cornelssen"
3030
s.email = 'ccorn@1tein.de'
31-
s.files = Dir["COPYING", "README.md", "lib/sskatex.rb",
32-
"test/test_all.rb",
33-
"test/{block,span}/*.html", "test/tex/*.tex",
34-
"data/sskatex/js/*.js"]
3531
s.homepage = 'https://github.com/ccorn/sskatex'
3632
s.license = 'MIT'
3733
s.add_runtime_dependency 'execjs', '~> 2.7'
3834
s.add_development_dependency 'duktape', '~> 1.6', '>= 1.6.1'
3935
s.required_ruby_version = '>= 2.1'
4036
s.requirements << "Javascript engine supported by the ExecJS gem"
4137
s.rdoc_options << '-a'
38+
s.files = Dir["COPYING", "README.md",
39+
"bin/sskatex",
40+
"lib/sskatex.rb",
41+
"test/test_all.rb",
42+
"test/{block,span}/*.html", "test/tex/*.tex",
43+
"data/sskatex/js/*.js"]
44+
s.executables << 'sskatex'
4245
end

0 commit comments

Comments
 (0)