kramdown 1.15.0 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of kramdown might be problematic. Click here for more details.

Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTERS +7 -1
  3. data/Rakefile +35 -0
  4. data/VERSION +1 -1
  5. data/bin/kramdown +22 -1
  6. data/doc/default.template +1 -1
  7. data/doc/documentation.template +1 -0
  8. data/doc/index.page +2 -2
  9. data/doc/installation.page +9 -7
  10. data/lib/kramdown/converter.rb +1 -1
  11. data/lib/kramdown/converter/html.rb +15 -4
  12. data/lib/kramdown/converter/kramdown.rb +5 -4
  13. data/lib/kramdown/converter/latex.rb +5 -1
  14. data/lib/kramdown/converter/math_engine/mathjaxnode.rb +9 -9
  15. data/lib/kramdown/converter/math_engine/sskatex.rb +97 -0
  16. data/lib/kramdown/converter/remove_html_tags.rb +3 -1
  17. data/lib/kramdown/converter/syntax_highlighter/rouge.rb +16 -9
  18. data/lib/kramdown/options.rb +54 -0
  19. data/lib/kramdown/parser/gfm.rb +25 -0
  20. data/lib/kramdown/parser/kramdown/paragraph.rb +8 -1
  21. data/lib/kramdown/utils.rb +1 -0
  22. data/lib/kramdown/utils/lru_cache.rb +40 -0
  23. data/lib/kramdown/version.rb +1 -1
  24. data/man/man1/kramdown.1 +46 -0
  25. data/test/test_files.rb +39 -6
  26. data/test/testcases/block/03_paragraph/line_break_last_line.html +9 -0
  27. data/test/testcases/block/03_paragraph/line_break_last_line.text +9 -0
  28. data/test/testcases/block/03_paragraph/with_html_to_native.html +1 -0
  29. data/test/testcases/block/03_paragraph/with_html_to_native.options +1 -0
  30. data/test/testcases/block/03_paragraph/with_html_to_native.text +1 -0
  31. data/test/testcases/block/06_codeblock/rouge/multiple.options +1 -1
  32. data/test/testcases/block/15_math/mathjaxnode.html.19 +1 -1
  33. data/test/testcases/block/15_math/mathjaxnode_notexhints.html.19 +1 -1
  34. data/test/testcases/block/15_math/mathjaxnode_semantics.html.19 +1 -1
  35. data/test/testcases/block/15_math/sskatex.html.19 +2 -0
  36. data/test/testcases/block/15_math/sskatex.options +1 -0
  37. data/test/testcases/block/15_math/sskatex.text +2 -0
  38. data/test/testcases/span/04_footnote/backlink_inline.html +79 -0
  39. data/test/testcases/span/04_footnote/backlink_inline.options +1 -0
  40. data/test/testcases/span/04_footnote/backlink_inline.text +38 -0
  41. data/test/testcases/span/math/mathjaxnode.html.19 +1 -1
  42. data/test/testcases/span/math/sskatex.html.19 +1 -0
  43. data/test/testcases/span/math/sskatex.options +1 -0
  44. data/test/testcases/span/math/sskatex.text +1 -0
  45. data/test/testcases/span/text_substitutions/typography_subst.html +3 -0
  46. data/test/testcases/span/text_substitutions/typography_subst.latex +4 -0
  47. data/test/testcases/span/text_substitutions/typography_subst.options +8 -0
  48. data/test/testcases/span/text_substitutions/typography_subst.text +3 -0
  49. data/test/testcases_gfm/no_typographic.html +3 -0
  50. data/test/testcases_gfm/no_typographic.html.19 +3 -0
  51. data/test/testcases_gfm/no_typographic.options +1 -0
  52. data/test/testcases_gfm/no_typographic.text +3 -0
  53. data/test/testcases_gfm/task_list.html +31 -0
  54. data/test/testcases_gfm/task_list.text +23 -0
  55. metadata +57 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69c006f3143fcd067cb7c1a27f80baf39870e3e7
4
- data.tar.gz: 88ae530383c5a4cacf7791cfb8c451a2fac49355
3
+ metadata.gz: e02d6b5a2bd270dd4a2801062964c3ce3de48443
4
+ data.tar.gz: d24931a4f74b44f4fcfa5f7a5a69b37de51a77c6
5
5
  SHA512:
6
- metadata.gz: 603752731df3717905665935bd5b3e412943a09de2b5d776f18d6fe1cecca18e210541e81c7863f43a42b469e2a3e5e232b4bce43671abdbfa9a557f01eb78e5
7
- data.tar.gz: 8d62fd7e8905d385fb1d269b03f09abb237e8953830d1e01e7ee5e56b10ec796a47fd03c7ac7c3d87dbcdfe4cfc11a2bbf3f04bef1c25b3a5d5b17aa0ae70048
6
+ metadata.gz: 6a8cf65af4b448aa37056b05c643b0f7af403f7b175e953036d4becea7910e2d111bc715670571e452d241fb6a773ddbb4e00e8f2e8a2045d6a90d4b436411d5
7
+ data.tar.gz: f5848f1db7010a58de4afd1a05b36215e07250110d37a9e8f3e15aa13dbc90cd298e74d1b3a1f9884e3f574db748a8648853ee8966a97b9373f5c2dcb0a7aeb4
@@ -1,6 +1,6 @@
1
1
  Count Name
2
2
  ======= ====
3
- 861 Thomas Leitner <t_leitner@gmx.at>
3
+ 872 Thomas Leitner <t_leitner@gmx.at>
4
4
  6 Gioele Barabucci <gioele@svario.it>
5
5
  4 Ted Pak <powerpak006@gmail.com>
6
6
  4 Shuanglei Tao <tsl0922@gmail.com>
@@ -15,9 +15,11 @@
15
15
  2 Nathanael Jones <nathanael.jones@gmail.com>
16
16
  2 Max Meyer <dev@fedux.org>
17
17
  2 Jo Hund <jhund@clearcove.ca>
18
+ 2 Christian Cornelssen <ccorn@1tein.de>
18
19
  2 Bran <m.versum@gmail.com>
19
20
  1 winniehell <git@winniehell.de>
20
21
  1 William <suttonwilliamd@gmail.com>
22
+ 1 Uwe Kubosch <donv@users.noreply.github.com>
21
23
  1 utenmiki <utenmiki@gmail.com>
22
24
  1 Trevor Wennblom <trevor@well.com>
23
25
  1 tomykaira <tomykaira@gmail.com>
@@ -28,6 +30,7 @@
28
30
  1 Simon Lydell <simon.lydell@gmail.com>
29
31
  1 Shusaku NAKAZATO <cu393uc@gmail.com>
30
32
  1 Sebastian Boehm <sebastian@sometimesfood.org>
33
+ 1 scherr <maximilianscherr@gmail.com>
31
34
  1 Postmodern <postmodern.mod3@gmail.com>
32
35
  1 Pete Michaud <michaudp@gmail.com>
33
36
  1 myqlarson <myqlarson@gmail.com>
@@ -38,6 +41,7 @@
38
41
  1 Marcus Stollsteimer <sto.mar@web.de>
39
42
  1 Luca Barbato <luca.barbato@gmail.com>
40
43
  1 l3kn <hello@l3kn.de>
44
+ 1 Kir Kolyshkin <kolyshkin@gmail.com>
41
45
  1 Jonathan Hooper <jonathan.hooper@gsa.gov>
42
46
  1 John Croisant <jacius@gmail.com>
43
47
  1 Joe Fiorini <joe@faithfulgeek.org>
@@ -50,5 +54,7 @@
50
54
  1 Damien Pollet <damien.pollet@gmail.com>
51
55
  1 Christopher Jefferson <caj21@st-andrews.ac.uk>
52
56
  1 Cédric Boutillier <cedric.boutillier@gmail.com>
57
+ 1 Andrew <andrew.dale.wylie@gmail.com>
58
+ 1 Alpha Chen <alpha.chen@gmail.com>
53
59
  1 Alex Tomlins <alex.tomlins@digital.cabinet-office.gov.uk>
54
60
  1 Alexey Vasiliev <le0pard@users.noreply.github.com>
data/Rakefile CHANGED
@@ -185,6 +185,8 @@ EOF
185
185
  s.add_development_dependency 'prawn-table', '~> 0.2.2'
186
186
  s.add_development_dependency 'ritex', '~> 1.0'
187
187
  s.add_development_dependency 'itextomml', '~> 1.5'
188
+ s.add_development_dependency 'execjs', '~> 2.7'
189
+ s.add_development_dependency 'sskatex', '>= 0.9.23'
188
190
 
189
191
  #### Documentation
190
192
 
@@ -266,6 +268,39 @@ EOF
266
268
  puts "Look through the above mentioned files and correct all problems" if inserted
267
269
  end
268
270
 
271
+ desc "Check for SsKaTeX availability"
272
+ task :test_sskatex_deps do
273
+ katexjs = 'katex/katex.min.js'
274
+ raise (<<TKJ) unless File.exists? katexjs
275
+ Cannot find file '#{katexjs}'.
276
+ You need to download KaTeX e.g. from https://github.com/Khan/KaTeX/releases/
277
+ and extract at least '#{katexjs}'.
278
+ Alternatively, if you have a copy of KaTeX unpacked somewhere else,
279
+ you can create a symbolic link 'katex' pointing to that KaTeX directory.
280
+ TKJ
281
+ html = %x{echo '$$a$$' | #{RbConfig.ruby} -Ilib bin/kramdown --math-engine sskatex}
282
+ raise (<<KTC) unless $?.success?
283
+ Some requirement by SsKaTeX or the employed JS engine has not been satisfied.
284
+ Cf. the above error messages.
285
+ KTC
286
+ raise (<<XJS) unless / class="katex"/ === html
287
+ Some static dependency of SsKaTeX, probably the 'sskatex' or the 'execjs' gem,
288
+ is not available.
289
+ If you 'gem install sskatex', also make sure that some JS engine is available,
290
+ e.g. by installing one of the gems 'duktape', 'therubyracer', or 'therubyrhino'.
291
+ XJS
292
+ puts "SsKaTeX is available, and its default configuration works."
293
+ end
294
+
295
+ desc "Update kramdown SsKaTeX test reference outputs"
296
+ task update_katex_tests: [:test_sskatex_deps] do
297
+ # Not framed in terms of rake file tasks to prevent accidental overwrites.
298
+ stems = ['test/testcases/block/15_math/sskatex',
299
+ 'test/testcases/span/math/sskatex']
300
+ stems.each do |stem|
301
+ ruby "-Ilib bin/kramdown --math-engine sskatex #{stem}.text >#{stem}.html.19"
302
+ end
303
+ end
269
304
  end
270
305
 
271
306
  task :gemspec => ['dev:gemspec']
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.15.0
1
+ 1.16.0
@@ -9,10 +9,31 @@
9
9
  #
10
10
 
11
11
  require 'optparse'
12
+ require 'rbconfig'
13
+ require 'yaml'
12
14
  require 'kramdown'
13
15
 
14
- options = {}
16
+ config_file = nil
17
+ begin
18
+ config_dir = case RbConfig::CONFIG['host_os']
19
+ when /bccwin|cygwin|djgpp|mingw|mswin|wince/i
20
+ File.expand_path((ENV['HOME'] || ENV['USERPROFILE'] || "~") + "/AppData/Local")
21
+ when /darwin|mac os/
22
+ File.expand_path("~/Library/Preferences/")
23
+ else
24
+ File.expand_path(ENV['XDG_CONFIG_HOME'] || '~/.config')
25
+ end
26
+ config_file = File.join(config_dir, "kramdownrc")
27
+ rescue
28
+ end
29
+
30
+ options = if config_file && File.exist?(config_file)
31
+ YAML.safe_load(File.read(config_file), [Symbol])
32
+ else
33
+ {}
34
+ end
15
35
  format = ['html']
36
+
16
37
  OptionParser.new do |opts|
17
38
  opts.banner = "Usage: kramdown [options] [FILE FILE ...]"
18
39
  opts.summary_indent = ' '*4
@@ -8,7 +8,7 @@
8
8
  <meta name="keywords" content="ruby, kramdown, markdown, text markup" />
9
9
  <link href="{relocatable: default.css}" type="text/css" rel="stylesheet" media="screen,projection" />
10
10
  <link href="{relocatable: news.atom}" type="application/atom+xml" rel="alternate" />
11
- <script src="//kramdown.gettalong.org/MathJax/MathJax.js" type="text/javascript"></script>
11
+ <script src="//kramdown.gettalong.org/MathJax/MathJax.js?config=default.js" type="text/javascript"></script>
12
12
  <title>{title:} | kramdown</title>
13
13
  </head>
14
14
  <body>
@@ -24,6 +24,7 @@
24
24
  * [Ritex](math_engine/ritex.html)
25
25
  * [itex2MML](math_engine/itex2mml.html)
26
26
  * [Mathjax-Node](math_engine/mathjaxnode.html)
27
+ * [SsKaTeX](math_engine/sskatex.html)
27
28
  * [Configuration Options](options.html)
28
29
  * [Tests](tests.html)
29
30
 
@@ -97,8 +97,8 @@ extensions that have been made popular by the [PHP Markdown Extra] package and [
97
97
  It is probably the fastest pure-Ruby Markdown converter available (September 2014), being about 3x
98
98
  faster than [Maruku] and about 4.5x faster than [BlueFeather].
99
99
 
100
- Version **1.15.0**{:itemprop="softwareVersion"} released on
101
- **2017-09-08**{:itemprop="datePublished"}, [more news](news.html)
100
+ Version **1.16.0**{:itemprop="softwareVersion"} released on
101
+ **2017-11-27**{:itemprop="datePublished"}, [more news](news.html)
102
102
  {: style="text-align: center; font-size: 80%"}
103
103
 
104
104
  </div>
@@ -8,7 +8,7 @@ sort_info: 5
8
8
  ## Dependencies
9
9
 
10
10
  Since kramdown is written in Ruby, you just need the [Ruby interpreter](http://www.ruby-lang.org),
11
- version 1.8.5, 1.8.6, 1.8.7, 1.9.2, 1.9.3 or 2.x. There are no other dependencies.
11
+ version 2.x. There are no other dependencies.
12
12
 
13
13
 
14
14
  ## Compatibility Notes
@@ -16,7 +16,7 @@ version 1.8.5, 1.8.6, 1.8.7, 1.9.2, 1.9.3 or 2.x. There are no other dependencie
16
16
  kramdown should work on any platform which supports Ruby. It has been successfully tested on the
17
17
  following platforms:
18
18
 
19
- * Linux with Ruby 1.8.7, 1.9.3, 2.x, jruby 1.7.19 and jruby 9.0.0.0.
19
+ * Linux with Ruby 2.x and jruby 9.0.0.0.
20
20
 
21
21
  See the platform specific installation notes for more information!
22
22
 
@@ -25,13 +25,15 @@ See the platform specific installation notes for more information!
25
25
 
26
26
  ### Linux
27
27
 
28
- There are a variety of Linux distributions out there with different package management systems. So
29
- we will focus on instructions for Ubuntu 15.04 here (which should probably also work for any newer
30
- Ubuntu version or any recent Debian based distribution).
31
-
32
- After running the following commands, kramdown is installed and ready to use:
28
+ You need to make sure that Ruby is installed. If it isn't, consult the documentation of the Linux
29
+ distribution you are using on how to install it. For example, in case of Ubuntu 17.10 (this should
30
+ probably also work for any newer Ubuntu version or any recent Debian based distribution) all you
31
+ need to do is:
33
32
 
34
33
  sudo apt-get install ruby
34
+
35
+ Once you have Ruby installed, you need to execute the following command to install kramdown:
36
+
35
37
  sudo gem install kramdown
36
38
 
37
39
 
@@ -50,7 +50,7 @@ module Kramdown
50
50
 
51
51
  configurable(:math_engine)
52
52
 
53
- ['Mathjax', "MathjaxNode", "Ritex", "Itex2MML"].each do |klass_name|
53
+ ['Mathjax', "MathjaxNode", "SsKaTeX", "Ritex", "Itex2MML"].each do |klass_name|
54
54
  kn_down = klass_name.downcase.intern
55
55
  add_math_engine(kn_down) do |converter, el, opts|
56
56
  require "kramdown/converter/math_engine/#{kn_down}"
@@ -305,7 +305,11 @@ module Kramdown
305
305
  :raquo => [::Kramdown::Utils::Entities.entity('raquo')]
306
306
  } # :nodoc:
307
307
  def convert_typographic_sym(el, indent)
308
- TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e)}.join('')
308
+ if (result = @options[:typographic_symbols][el.value])
309
+ escape_html(result, :text)
310
+ else
311
+ TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e)}.join('')
312
+ end
309
313
  end
310
314
 
311
315
  def convert_smart_quote(el, indent)
@@ -459,10 +463,17 @@ module Kramdown
459
463
  li = Element.new(:li, nil, {'id' => "fn:#{name}"})
460
464
  li.children = Marshal.load(Marshal.dump(data.children))
461
465
 
462
- if li.children.last.type == :p
463
- para = li.children.last
466
+ para = nil
467
+ if li.children.last.type == :p || @options[:footnote_backlink_inline]
468
+ parent = li
469
+ while !parent.children.empty? && ![:p, :header].include?(parent.children.last.type)
470
+ parent = parent.children.last
471
+ end
472
+ para = parent.children.last
464
473
  insert_space = true
465
- else
474
+ end
475
+
476
+ unless para
466
477
  li.children << (para = Element.new(:p))
467
478
  insert_space = false
468
479
  end
@@ -292,14 +292,15 @@ module Kramdown
292
292
 
293
293
  def convert_img(el, opts)
294
294
  alt_text = el.attr['alt'].to_s.gsub(ESCAPED_CHAR_RE) { $1 ? "\\#{$1}" : $2 }
295
- if el.attr['src'].empty?
295
+ src = el.attr['src'].to_s
296
+ if src.empty?
296
297
  "![#{alt_text}]()"
297
298
  else
298
299
  title = parse_title(el.attr['title'])
299
- link = if el.attr['src'].count("()") > 0
300
- "<#{el.attr['src']}>"
300
+ link = if src.count("()") > 0
301
+ "<#{src}>"
301
302
  else
302
- el.attr['src']
303
+ src
303
304
  end
304
305
  "![#{alt_text}](#{link}#{title})"
305
306
  end
@@ -534,7 +534,11 @@ module Kramdown
534
534
  :laquo => '\guillemotleft{}', :raquo => '\guillemotright{}'
535
535
  } # :nodoc:
536
536
  def convert_typographic_sym(el, opts)
537
- TYPOGRAPHIC_SYMS[el.value]
537
+ if (result = @options[:typographic_symbols][el.value])
538
+ escape(result)
539
+ else
540
+ TYPOGRAPHIC_SYMS[el.value]
541
+ end
538
542
  end
539
543
 
540
544
  def convert_smart_quote(el, opts)
@@ -9,27 +9,27 @@
9
9
 
10
10
  module Kramdown::Converter::MathEngine
11
11
 
12
- # Uses the mathjax-node library for converting math formulas to MathML.
12
+ # Uses the mathjax-node-cli library for converting math formulas to MathML.
13
13
  module MathjaxNode
14
14
 
15
15
  # MathjaxNode is available if this constant is +true+.
16
- AVAILABLE = RUBY_VERSION >= '1.9' && begin
17
- %x{node --version}[1..-2] >= '4.0'
16
+ AVAILABLE = begin
17
+ %x{node --version}[1..-2] >= '4.5'
18
18
  rescue
19
19
  begin
20
- %x{nodejs --version}[1..-2] >= '4.0'
20
+ %x{nodejs --version}[1..-2] >= '4.5'
21
21
  rescue
22
22
  false
23
23
  end
24
24
  end && begin
25
- npm = %x{npm --global --depth=1 list mathjax-node 2>&1}
25
+ npm = %x{npm --global --depth=1 list mathjax-node-cli 2>&1}
26
26
 
27
- unless /mathjax-node@/ === npm.lines.drop(1).join("\n")
28
- npm = %x{npm --depth=1 list mathjax-node 2>&1}
27
+ unless /mathjax-node-cli@/ === npm.lines.drop(1).join("\n")
28
+ npm = %x{npm --depth=1 list mathjax-node-cli 2>&1}
29
29
  end
30
30
 
31
- T2MPATH = File.join(npm.lines.first.strip, "node_modules/mathjax-node/bin/tex2mml")
32
- /mathjax-node@/ === npm.lines.drop(1).join("\n") && File.exist?(T2MPATH)
31
+ T2MPATH = File.join(npm.lines.first.strip, "node_modules/mathjax-node-cli/bin/tex2mml")
32
+ /mathjax-node-cli@/ === npm.lines.drop(1).join("\n") && File.exist?(T2MPATH)
33
33
  rescue
34
34
  false
35
35
  end
@@ -0,0 +1,97 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2017 Christian Cornelssen <ccorn@1tein.de>
5
+ #
6
+ # This file is part of kramdown which is licensed under the MIT.
7
+ #++
8
+
9
+ module Kramdown::Converter::MathEngine
10
+
11
+ # Consider this a lightweight alternative to MathjaxNode. Uses KaTeX and ExecJS (via ::SsKaTeX)
12
+ # instead of MathJax and Node.js. Javascript execution context initialization is done only once.
13
+ # As a result, the performance is reasonable.
14
+ module SsKaTeX
15
+
16
+ # Indicate whether SsKaTeX may be available.
17
+ #
18
+ # This test is incomplete; it cannot test the existence of _katex_js_ nor the availability of a
19
+ # specific _js_run_ because those depend on configuration not given here. This test mainly
20
+ # indicates whether static dependencies such as the +sskatex+ and +execjs+ gems are available.
21
+ AVAILABLE = begin
22
+ require 'sskatex'
23
+ # No test for any JS engine availability here; specifics are config-dependent anyway
24
+ true
25
+ rescue LoadError
26
+ false
27
+ end
28
+
29
+ if AVAILABLE
30
+
31
+ # Class-level cache for ::SsKaTeX converter state, queried by configuration. Note: KTXC
32
+ # contents may become stale if the contents of used JS files change while the configuration
33
+ # remains unchanged.
34
+ KTXC = ::Kramdown::Utils::LRUCache.new(10)
35
+
36
+ # A logger that routes messages to the debug channel only. No need to create this dynamically.
37
+ DEBUG_LOGGER = lambda { |level, &expr| warn(expr.call) }
38
+
39
+ class << self
40
+ private
41
+
42
+ # Given a Kramdown::Converter::Base object _converter_, retrieves the logging options and
43
+ # builds an object usable for ::SsKaTeX#logger. The result is either +nil+ (no logging) or a
44
+ # +Proc+ object which, when given a _level_ (either +:verbose+ or +:debug+) and a block,
45
+ # decides whether logging is enabled, and if so, evaluates the given block for the message
46
+ # and routes that message to the appropriate channels. With <tt>level == :verbose+</tt>,
47
+ # messages are passed to _converter_.warning if the _converter_'s +:verbose+ option is set.
48
+ # All messages are passed to +warn+ if the _converter_'s +:debug+ option is set.
49
+ #
50
+ # Note that the returned logger may contain references to the given _converter_ and is not
51
+ # affected by subsequent changes in the _converter_'s logging options.
52
+ def logger(converter)
53
+ config = converter.options[:math_engine_opts]
54
+ debug = config[:debug]
55
+ if config[:verbose]
56
+ # Need a closure
57
+ lambda do |level, &expr|
58
+ verbose = (level == :verbose)
59
+ msg = expr.call if debug || verbose
60
+ warn(msg) if debug
61
+ converter.warning(msg) if verbose
62
+ end
63
+ elsif debug
64
+ DEBUG_LOGGER
65
+ end
66
+ end
67
+
68
+ # Given a Kramdown::Converter::Base object _converter_, return a ::SsKaTeX converter _sktx_
69
+ # that has been configured with _converter_'s +math_engine_opts+, but not for logging. Cache
70
+ # _sktx_ for reuse, without references to _converter_.
71
+ def katex_conv(converter)
72
+ config = converter.options[:math_engine_opts]
73
+ # Could .reject { |key, _| [:verbose, :debug].include?(key.to_sym) }
74
+ # because the JS engine setup can be reused for different logging settings.
75
+ # But then the +math_engine_opts+ dict would be essentially dup'ed every time,
76
+ # and late activation of logging would miss the initialization if the engine is reused.
77
+ KTXC[config] ||= ::SsKaTeX.new(config)
78
+ end
79
+
80
+ public
81
+
82
+ # The function used by kramdown for rendering TeX math to HTML
83
+ def call(converter, el, opts)
84
+ display_mode = el.options[:category]
85
+ ans = katex_conv(converter).call(el.value, display_mode == :block, &logger(converter))
86
+ attr = el.attr.dup
87
+ attr.delete('xmlns')
88
+ attr.delete('display')
89
+ ans.insert(ans =~ /[[:space:]>]/, converter.html_attributes(attr))
90
+ ans = ' ' * opts[:indent] << ans << "\n" if display_mode == :block
91
+ ans
92
+ end
93
+
94
+ end
95
+ end
96
+ end
97
+ end
@@ -30,6 +30,8 @@ module Kramdown
30
30
  end
31
31
 
32
32
  def convert(el)
33
+ real_el, el = el, el.value if el.type == :footnote
34
+
33
35
  children = el.children.dup
34
36
  index = 0
35
37
  while index < children.length
@@ -46,7 +48,7 @@ module Kramdown
46
48
  end
47
49
  end
48
50
  el.children = children
49
- el
51
+ real_el || el
50
52
  end
51
53
 
52
54
  end
@@ -17,14 +17,6 @@ module Kramdown::Converter::SyntaxHighlighter
17
17
 
18
18
  # Highlighting via Rouge is available if this constant is +true+.
19
19
  AVAILABLE = true
20
-
21
- begin
22
- # Rouge::Formatters::HTMLLegacy is available on Rouge 2.0 or later
23
- FORMATTER_CLASS = ::Rouge::Formatters::HTMLLegacy
24
- rescue NameError
25
- # Fallbacks to Rouge 1.x formatter if Rouge::Formatters::HTMLLegacy is not available
26
- FORMATTER_CLASS = ::Rouge::Formatters::HTML
27
- end
28
20
  rescue LoadError, SyntaxError
29
21
  AVAILABLE = false # :nodoc:
30
22
  end
@@ -35,7 +27,7 @@ module Kramdown::Converter::SyntaxHighlighter
35
27
  lexer = ::Rouge::Lexer.find_fancy(lang || opts[:default_lang], text)
36
28
  return nil if opts[:disable] || !lexer
37
29
  opts[:css_class] ||= 'highlight' # For backward compatibility when using Rouge 2.0
38
- formatter = (opts.fetch(:formatter, FORMATTER_CLASS)).new(opts)
30
+ formatter = formatter_class(opts).new(opts)
39
31
  formatter.format(lexer.lex(text))
40
32
  end
41
33
 
@@ -62,6 +54,21 @@ module Kramdown::Converter::SyntaxHighlighter
62
54
  cache[:block] = opts.merge(block_opts)
63
55
  end
64
56
 
57
+ def self.formatter_class(opts = {})
58
+ case formatter = opts[:formatter]
59
+ when Class
60
+ formatter
61
+ when /\A[[:upper:]][[:alnum:]_]*\z/
62
+ ::Rouge::Formatters.const_get(formatter)
63
+ else
64
+ # Available in Rouge 2.0 or later
65
+ ::Rouge::Formatters::HTMLLegacy
66
+ end
67
+ rescue NameError
68
+ # Fallback to Rouge 1.x
69
+ ::Rouge::Formatters::HTML
70
+ end
71
+
65
72
  end
66
73
 
67
74
  end