asciidoctor-katex 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f22339f6723c08a19cc767595dcc38721506b4a36a637181213c4a123a37908
4
- data.tar.gz: 934ea7f37bb904c1e5a437f5e576f673bd68e69a1d9cdac581683aea98b7c270
3
+ metadata.gz: 563feb091e023db762437c7dd7375a8238079780de324428e250da7844bb6b2f
4
+ data.tar.gz: 1567edd17da494abccc2a87832ef032ff9a63e35c9a07de4f53bd4a7584dde01
5
5
  SHA512:
6
- metadata.gz: d433256d16093e1b1c723765deab5e87c242bf469916a8202073dff267152c4332a77fccf89700b13c68a12bf132cc7a02812cc468df7d74ba3ac5c8c62063c9
7
- data.tar.gz: 7ff93fd5d24e49a29b414fa64ececcbc455f9f315959e04c0ddf1d1c0910e70727dca9580238fb0d2c1bb8eea63a1ee7035b22c3834880863f56040c66136e27
6
+ metadata.gz: 638dca239825461b452b6fabadfc2d80685daa02031aec634d5a80198bc9acbdfda4a357df188987f4b3c5ae4aa0425c75d868e90410c820ea834bc9e0eeb891
7
+ data.tar.gz: 3044648be03e130d47ae1deb4bc2fd402dab87334def8e11fe83714bbd5307ac2a8155f541b6ae796e7b2cf5e57b975075ed4d6079efd7ef0d4a8f678e17cf71
@@ -2,6 +2,7 @@
2
2
  require 'asciidoctor' unless RUBY_PLATFORM == 'opal'
3
3
  require 'asciidoctor/extensions' unless RUBY_PLATFORM == 'opal'
4
4
  require 'asciidoctor/katex/version'
5
+ require 'asciidoctor/katex/errors'
5
6
  require 'asciidoctor/katex/treeprocessor'
6
7
 
7
8
  unless RUBY_PLATFORM == 'opal'
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ require 'asciidoctor/katex/version'
3
+
4
+ module Asciidoctor::Katex
5
+
6
+ # Exception raised when KaTeX throw any error except `ParseError`.
7
+ class KatexError < ::RuntimeError
8
+ attr_reader :expression
9
+
10
+ # @param msg [#to_s] the message.
11
+ # @param expression [String] the LaTeX expression that caused the error.
12
+ def initialize(msg, expression)
13
+ @expression = expression
14
+ super(msg.to_s)
15
+ end
16
+ end
17
+
18
+ # Exception raised when KaTeX throw `ParseError` which is the main error
19
+ # thrown by KaTeX functions when something has gone wrong.
20
+ class ParseError < KatexError; end
21
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ require 'asciidoctor/katex/version'
3
+ require 'asciidoctor/katex/errors'
4
+ require 'asciidoctor/katex/utils'
5
+
6
+ module Asciidoctor::Katex
7
+ # Adapter for the KaTeX library for Opal/JS environment.
8
+ class OpalKatexAdapter
9
+ include Utils
10
+
11
+ # @param default_options [Hash] the default options for the KaTeX renderer.
12
+ # @param katex_object the katex object to use under Opal (defaults to
13
+ # global variable `katex`).
14
+ def initialize(default_options = {}, katex_object = nil)
15
+ @default_options = hash_camelize(default_options)
16
+ @katex_object = katex_object || `katex`
17
+ end
18
+
19
+ # Renders the given math expression to HTML using KaTeX.
20
+ #
21
+ # @param math [String] the math (LaTeX) expression.
22
+ # @param opts [Hash] options for `katex.renderToString`.
23
+ # Keys in under_score notation will be converted to camelCase.
24
+ # See <https://github.com/Khan/KaTeX#rendering-options>.
25
+ # @return [String] a rendered HTML fragment.
26
+ def render(math, opts = {})
27
+ opts = @default_options.merge(hash_camelize(opts))
28
+
29
+ begin
30
+ `#{@katex_object}.renderToString(#{math}, #{opts}.$$smap)`
31
+ rescue ::JS::Error => err
32
+ # "#{err}" is really needed for Opal/JS, #to_s returns a different string.
33
+ # rubocop:disable UnneededInterpolation
34
+ raise ParseError.new(err, math) if "#{err}".start_with?('ParseError:')
35
+ raise KatexError.new(err, math)
36
+ end
37
+ end
38
+
39
+ alias call render
40
+ end
41
+
42
+ # The default KaTeX adapter.
43
+ KatexAdapter = OpalKatexAdapter unless defined? KatexAdapter
44
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ require 'asciidoctor/katex/version'
3
+ require 'asciidoctor/katex/errors'
4
+ require 'asciidoctor/katex/utils'
5
+ require 'katex'
6
+
7
+ module Asciidoctor::Katex
8
+ # Adapter for the KaTeX library for Ruby environment.
9
+ class RubyKatexAdapter
10
+ include Utils
11
+
12
+ # @param default_options [Hash] the default options for the KaTeX renderer.
13
+ def initialize(default_options = {})
14
+ @default_options = hash_camelize(default_options)
15
+ end
16
+
17
+ # Renders the given math expression to HTML using KaTeX.
18
+ #
19
+ # @param math [String] the math (LaTeX) expression.
20
+ # @param opts [Hash] options for `katex.renderToString`.
21
+ # Keys in under_score notation will be converted to camelCase.
22
+ # See <https://github.com/Khan/KaTeX#rendering-options>.
23
+ # @return [String] a rendered HTML fragment.
24
+ def render(math, opts = {})
25
+ opts = @default_options.merge(hash_camelize(opts))
26
+
27
+ opts[:throw_on_error] = opts[:throwOnError]
28
+ opts[:error_color] = opts[:errorColor] || '#cc0000'
29
+
30
+ begin
31
+ ::Katex.render(math, opts)
32
+ rescue ::ExecJS::ProgramError => err
33
+ raise ParseError.new(err, math) if err.to_s.start_with?('ParseError:')
34
+ raise KatexError.new(err, math)
35
+ end
36
+ end
37
+
38
+ alias call render
39
+ end
40
+
41
+ # The default KaTeX adapter.
42
+ KatexAdapter = RubyKatexAdapter unless defined? KatexAdapter
43
+ end
@@ -43,9 +43,8 @@ module Asciidoctor::Katex
43
43
  isblock = node.block?
44
44
 
45
45
  output.sub(isblock ? @block_re : @inline_re) do
46
- @math_renderer.call(::Regexp.last_match[1].strip,
47
- display_mode: isblock,
48
- throw_on_error: @throw_on_error)
46
+ math = decode_html_entities(::Regexp.last_match[1].strip)
47
+ @math_renderer.call(math, display_mode: isblock, throw_on_error: @throw_on_error)
49
48
  end
50
49
  end
51
50
 
@@ -68,7 +67,23 @@ module Asciidoctor::Katex
68
67
  # @return [Regexp]
69
68
  def regexp_from_delimiters(delimiters)
70
69
  open, close = delimiters.map { |s| ::Regexp.escape(s) }
71
- /#{open}(.+)#{close}/m
70
+
71
+ # XXX: Opal 0.11.x does not properly escape interpolated regexps and
72
+ # Regexp.new does not work at all. Thus we have to escape \s\S in
73
+ # advance when running on Opal and this faulty behaviour is detected.
74
+ if ::RUBY_PLATFORM == 'opal' && /#{''}\\s/ == /\s/
75
+ /#{open}([\\s\\S]+)#{close}/m
76
+ else
77
+ /#{open}([\s\S]+)#{close}/m
78
+ end
79
+ end
80
+
81
+ # @param str [String]
82
+ # @return [String]
83
+ def decode_html_entities(str)
84
+ str.gsub('&lt;', '<')
85
+ .gsub('&gt;', '>')
86
+ .gsub('&amp;', '&')
72
87
  end
73
88
  end
74
89
  end
@@ -2,25 +2,30 @@
2
2
  require 'asciidoctor' unless RUBY_PLATFORM == 'opal'
3
3
  require 'asciidoctor/extensions' unless RUBY_PLATFORM == 'opal'
4
4
  require 'asciidoctor/katex/version'
5
- require 'asciidoctor/katex/katex_adapter'
6
5
  require 'asciidoctor/katex/stem_converter_decorator'
7
6
 
7
+ if RUBY_PLATFORM == 'opal'
8
+ require 'asciidoctor/katex/opal_katex_adapter'
9
+ else
10
+ require 'asciidoctor/katex/ruby_katex_adapter'
11
+ end
12
+
8
13
  module Asciidoctor::Katex
9
14
  # Asciidoctor processor that renders delimited latexmath expressions using
10
15
  # the KaTeX library.
11
16
  class Treeprocessor < ::Asciidoctor::Extensions::Treeprocessor
12
17
 
13
- # @param katex_renderer [#call] callable that accepts a math expression
18
+ # @param katex_options [Hash] default options for the KaTeX renderer.
19
+ # This parameter has no effect when *katex_renderer* is provided.
20
+ # @param katex_renderer [#call, nil] callable that accepts a math expression
14
21
  # [String] and options [Hash], and returns a rendered expression [String].
15
- # Default is an instance of KatexAdapter.
22
+ # Defaults to {KatexAdapter} initialized with the *katex_options*.
16
23
  # @param require_stem_attr [Boolean] `true` to skip when `stem` attribute
17
24
  # is not declared, `false` to process anyway.
18
- def initialize(katex_renderer: KatexAdapter.new,
19
- require_stem_attr: true,
20
- **)
21
- super
22
- @katex_renderer = katex_renderer
25
+ def initialize(katex_options: {}, katex_renderer: nil, require_stem_attr: true, **)
26
+ @katex_renderer = katex_renderer || KatexAdapter.new(katex_options)
23
27
  @require_stem_attr = require_stem_attr
28
+ super
24
29
  end
25
30
 
26
31
  # @param document [Asciidoctor::Document] the document to process.
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ require 'asciidoctor/katex/version'
3
+
4
+ module Asciidoctor::Katex
5
+ # @private
6
+ module Utils
7
+ module_function
8
+
9
+ # @param hash [Hash] the hash to transform.
10
+ # @return [Hash] a copy of the *hash* with under_score keys transformed to camelCase.
11
+ def hash_camelize(hash)
12
+ hash.map { |key, val|
13
+ key = key.to_s.gsub(/_\w/) { |s| s[1].upcase }.to_sym
14
+ [key, val]
15
+ }.to_h
16
+ end
17
+ end
18
+ end
@@ -3,6 +3,6 @@
3
3
  module Asciidoctor
4
4
  module Katex
5
5
  # Version of the asciidoctor-katex gem.
6
- VERSION = '0.1.2'
6
+ VERSION = '0.2.0'
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-katex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub Jirutka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-30 00:00:00.000000000 Z
11
+ date: 2018-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -147,9 +147,12 @@ files:
147
147
  - asciidoctor-katex.gemspec
148
148
  - lib/asciidoctor-katex.rb
149
149
  - lib/asciidoctor/katex.rb
150
- - lib/asciidoctor/katex/katex_adapter.rb
150
+ - lib/asciidoctor/katex/errors.rb
151
+ - lib/asciidoctor/katex/opal_katex_adapter.rb
152
+ - lib/asciidoctor/katex/ruby_katex_adapter.rb
151
153
  - lib/asciidoctor/katex/stem_converter_decorator.rb
152
154
  - lib/asciidoctor/katex/treeprocessor.rb
155
+ - lib/asciidoctor/katex/utils.rb
153
156
  - lib/asciidoctor/katex/version.rb
154
157
  homepage: https://github.com/jirutka/asciidoctor-katex/
155
158
  licenses:
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'asciidoctor/katex/version'
3
- require 'katex' unless RUBY_PLATFORM == 'opal'
4
-
5
- module Asciidoctor::Katex
6
- # Adapter for KaTeX library supporting both Ruby and Opal environment.
7
- class KatexAdapter
8
-
9
- # @param default_options [Hash] the default options for the KaTeX renderer.
10
- # @param katex_object the katex object to use under Opal (defaults to
11
- # global variable `katex`).
12
- def initialize(default_options = {}, katex_object = nil)
13
- @default_options = default_options
14
- @katex_object = katex_object || `katex` if RUBY_PLATFORM == 'opal'
15
- end
16
-
17
- # @return [Boolean] whether is KaTeX library installed and loaded.
18
- # This is useful only under Opal.
19
- def available?
20
- if RUBY_PLATFORM == 'opal'
21
- `#{@katex_object} != 'undefined' && #{@katex_object}.renderToString != undefined`
22
- else
23
- defined? ::Katex
24
- end
25
- end
26
-
27
- # Renders the given math expression to HTML using KaTeX.
28
- #
29
- # @param math [String] the math (LaTeX) expression.
30
- # @param options [Hash] options for `katex.renderToString`.
31
- # Keys in under_score notation will be converted to camelCase.
32
- # See <https://github.com/Khan/KaTeX#rendering-options>.
33
- # @return [String] a rendered HTML fragment.
34
- def render(math, options = {})
35
- options = hash_camelize(options || {})
36
-
37
- if RUBY_PLATFORM == 'opal'
38
- `#{@katex_object}.renderToString(#{math}, #{options}.$$smap)`
39
- else
40
- ::Katex.render(math, options)
41
- end
42
- end
43
-
44
- alias call render
45
-
46
- # @return [String] version of the KaTeX library.
47
- def version
48
- if RUBY_PLATFORM == 'opal'
49
- '0.9.0' # TODO: replace with `katex.version` after update to 0.10+.
50
- else
51
- ::Katex::KATEX_VERSION.sub(/^v/, '')
52
- end
53
- end
54
-
55
- private
56
-
57
- # @param hash [Hash] the hash to transform.
58
- # @return [Hash] a copy of the *hash* with under_score keys transformed to camelCase.
59
- def hash_camelize(hash)
60
- hash.map { |k, v|
61
- [k.to_s.gsub(/_\w/) { |s| s[1].upcase }.to_sym, v]
62
- }.to_h
63
- end
64
- end
65
- end