motion-kramdown 0.6.0 → 1.16.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +6 -2
  3. data/lib/kramdown.rb +1 -1
  4. data/lib/kramdown/converter.rb +10 -11
  5. data/lib/kramdown/converter/base.rb +19 -12
  6. data/lib/kramdown/converter/hash_ast.rb +38 -0
  7. data/lib/kramdown/converter/html.rb +71 -39
  8. data/lib/kramdown/converter/kramdown.rb +19 -10
  9. data/lib/kramdown/converter/latex.rb +28 -10
  10. data/lib/kramdown/converter/man.rb +303 -0
  11. data/lib/kramdown/converter/math_engine/itex2mml.rb +2 -2
  12. data/lib/kramdown/converter/math_engine/mathjax.rb +13 -3
  13. data/lib/kramdown/converter/math_engine/mathjaxnode.rb +56 -0
  14. data/lib/kramdown/converter/math_engine/ritex.rb +2 -2
  15. data/lib/kramdown/converter/math_engine/sskatex.rb +97 -0
  16. data/lib/kramdown/converter/pdf.rb +6 -6
  17. data/lib/kramdown/converter/remove_html_tags.rb +5 -3
  18. data/lib/kramdown/converter/syntax_highlighter.rb +5 -2
  19. data/lib/kramdown/converter/syntax_highlighter/coderay.rb +8 -5
  20. data/lib/kramdown/converter/syntax_highlighter/minted.rb +35 -0
  21. data/lib/kramdown/converter/syntax_highlighter/rouge.rb +48 -10
  22. data/lib/kramdown/converter/toc.rb +2 -2
  23. data/lib/kramdown/document.rb +16 -19
  24. data/lib/kramdown/element.rb +5 -1
  25. data/lib/kramdown/error.rb +1 -1
  26. data/lib/kramdown/options.rb +103 -7
  27. data/lib/kramdown/parser.rb +1 -1
  28. data/lib/kramdown/parser/base.rb +12 -18
  29. data/lib/kramdown/parser/gfm.rb +142 -11
  30. data/lib/kramdown/parser/html.rb +28 -18
  31. data/lib/kramdown/parser/kramdown.rb +45 -36
  32. data/lib/kramdown/parser/kramdown/abbreviation.rb +1 -1
  33. data/lib/kramdown/parser/kramdown/autolink.rb +2 -8
  34. data/lib/kramdown/parser/kramdown/blank_line.rb +2 -2
  35. data/lib/kramdown/parser/kramdown/block_boundary.rb +4 -4
  36. data/lib/kramdown/parser/kramdown/blockquote.rb +4 -4
  37. data/lib/kramdown/parser/kramdown/codeblock.rb +11 -8
  38. data/lib/kramdown/parser/kramdown/codespan.rb +1 -1
  39. data/lib/kramdown/parser/kramdown/emphasis.rb +2 -2
  40. data/lib/kramdown/parser/kramdown/eob.rb +1 -1
  41. data/lib/kramdown/parser/kramdown/escaped_chars.rb +1 -1
  42. data/lib/kramdown/parser/kramdown/extensions.rb +6 -3
  43. data/lib/kramdown/parser/kramdown/footnote.rb +4 -5
  44. data/lib/kramdown/parser/kramdown/header.rb +2 -2
  45. data/lib/kramdown/parser/kramdown/horizontal_rule.rb +1 -1
  46. data/lib/kramdown/parser/kramdown/html.rb +8 -8
  47. data/lib/kramdown/parser/kramdown/html_entity.rb +2 -2
  48. data/lib/kramdown/parser/kramdown/line_break.rb +1 -1
  49. data/lib/kramdown/parser/kramdown/link.rb +5 -4
  50. data/lib/kramdown/parser/kramdown/list.rb +17 -10
  51. data/lib/kramdown/parser/kramdown/math.rb +2 -2
  52. data/lib/kramdown/parser/kramdown/paragraph.rb +19 -8
  53. data/lib/kramdown/parser/kramdown/smart_quotes.rb +3 -3
  54. data/lib/kramdown/parser/kramdown/table.rb +10 -12
  55. data/lib/kramdown/parser/kramdown/typographic_symbol.rb +1 -1
  56. data/lib/kramdown/parser/markdown.rb +2 -2
  57. data/lib/kramdown/utils.rb +2 -1
  58. data/lib/kramdown/utils/configurable.rb +2 -2
  59. data/lib/kramdown/utils/entities.rb +1 -1
  60. data/lib/kramdown/utils/html.rb +2 -2
  61. data/lib/kramdown/utils/lru_cache.rb +40 -0
  62. data/lib/kramdown/utils/ordered_hash.rb +2 -71
  63. data/lib/kramdown/utils/string_scanner.rb +2 -2
  64. data/lib/kramdown/utils/unidecoder.rb +2 -2
  65. data/lib/kramdown/version.rb +2 -2
  66. data/lib/rubymotion/require_override.rb +9 -0
  67. data/lib/rubymotion/version.rb +1 -1
  68. data/spec/{helpers → motion-kramdown/_helpers}/it_behaves_like.rb +0 -0
  69. data/spec/{helpers → motion-kramdown/_helpers}/option_file.rb +2 -2
  70. data/spec/{helpers → motion-kramdown/_helpers}/tidy.rb +0 -0
  71. data/spec/motion-kramdown/bench_mark.rb +37 -0
  72. data/spec/{document_tree.rb → motion-kramdown/document_tree.rb} +11 -1
  73. data/spec/{gfm_to_html.rb → motion-kramdown/gfm_to_html.rb} +51 -18
  74. data/spec/{html_to_html.rb → motion-kramdown/html_to_html.rb} +27 -9
  75. data/spec/{html_to_kramdown_to_html.rb → motion-kramdown/html_to_kramdown_to_html.rb} +35 -16
  76. data/spec/motion-kramdown/kramdown_to_xxx.rb +75 -0
  77. data/spec/{test_location.rb → motion-kramdown/test_location.rb} +0 -0
  78. data/spec/{test_string_scanner_kramdown.rb → motion-kramdown/test_string_scanner_kramdown.rb} +0 -0
  79. data/spec/motion-kramdown/text_manpage.rb +11 -0
  80. data/spec/{text_to_kramdown_to_html.rb → motion-kramdown/text_to_kramdown_to_html.rb} +30 -19
  81. data/spec/{text_to_latex.rb → motion-kramdown/text_to_latex.rb} +0 -0
  82. data/spec/{helpers/spec_options.rb → spec_helper.rb} +13 -2
  83. metadata +54 -33
  84. data/lib/kramdown/compatibility.rb +0 -36
  85. data/spec/bench_mark.rb +0 -43
  86. data/spec/kramdown_to_xxx.rb +0 -42
@@ -1,14 +1,14 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  #--
4
- # Copyright (C) 2009-2015 Thomas Leitner <t_leitner@gmx.at>
4
+ # Copyright (C) 2009-2016 Thomas Leitner <t_leitner@gmx.at>
5
5
  #
6
6
  # This file is part of kramdown which is licensed under the MIT.
7
7
  #++
8
8
  #
9
9
 
10
- # RM require 'set'
11
- # RM require 'kramdown/converter'
10
+ require 'set'
11
+ require 'kramdown/converter'
12
12
 
13
13
  module Kramdown
14
14
 
@@ -84,7 +84,12 @@ module Kramdown
84
84
  def convert_codeblock(el, opts)
85
85
  show_whitespace = el.attr['class'].to_s =~ /\bshow-whitespaces\b/
86
86
  lang = extract_code_language(el.attr)
87
- if show_whitespace || lang
87
+
88
+ if @options[:syntax_highlighter] == :minted &&
89
+ (highlighted_code = highlight_code(el.value, lang, :block))
90
+ @data[:packages] << 'minted'
91
+ "#{latex_link_target(el)}#{highlighted_code}\n"
92
+ elsif show_whitespace || lang
88
93
  options = []
89
94
  options << "showspaces=%s,showtabs=%s" % (show_whitespace ? ['true', 'true'] : ['false', 'false'])
90
95
  options << "language=#{lang}" if lang
@@ -132,7 +137,7 @@ module Kramdown
132
137
  end
133
138
 
134
139
  def convert_li(el, opts)
135
- "\\item #{latex_link_target(el, true)}#{inner(el, opts).sub(/\n+\Z/, '')}\n"
140
+ "\\item{} #{latex_link_target(el, true)}#{inner(el, opts).sub(/\n+\Z/, '')}\n"
136
141
  end
137
142
 
138
143
  def convert_dt(el, opts)
@@ -205,9 +210,9 @@ module Kramdown
205
210
  def convert_a(el, opts)
206
211
  url = el.attr['href']
207
212
  if url.start_with?('#')
208
- "\\hyperlink{#{escape(url[1..-1])}}{#{inner(el, opts)}}"
213
+ "\\hyperlink{#{url[1..-1].gsub('%', "\\%")}}{#{inner(el, opts)}}"
209
214
  else
210
- "\\href{#{escape(url)}}{#{inner(el, opts)}}"
215
+ "\\href{#{url.gsub('%', "\\%")}}{#{inner(el, opts)}}"
211
216
  end
212
217
  end
213
218
 
@@ -226,7 +231,14 @@ module Kramdown
226
231
  end
227
232
 
228
233
  def convert_codespan(el, opts)
229
- "{\\tt #{latex_link_target(el)}#{escape(el.value)}}"
234
+ lang = extract_code_language(el.attr)
235
+ if @options[:syntax_highlighter] == :minted &&
236
+ (highlighted_code = highlight_code(el.value, lang, :span))
237
+ @data[:packages] << 'minted'
238
+ "#{latex_link_target(el)}#{highlighted_code}"
239
+ else
240
+ "\\texttt{#{latex_link_target(el)}#{escape(el.value)}}"
241
+ end
230
242
  end
231
243
 
232
244
  def convert_footnote(el, opts)
@@ -522,7 +534,11 @@ module Kramdown
522
534
  :laquo => '\guillemotleft{}', :raquo => '\guillemotright{}'
523
535
  } # :nodoc:
524
536
  def convert_typographic_sym(el, opts)
525
- TYPOGRAPHIC_SYMS[el.value]
537
+ if (result = @options[:typographic_symbols][el.value])
538
+ escape(result)
539
+ else
540
+ TYPOGRAPHIC_SYMS[el.value]
541
+ end
526
542
  end
527
543
 
528
544
  def convert_smart_quote(el, opts)
@@ -586,7 +602,9 @@ module Kramdown
586
602
  "~" => "\\ensuremath{\\sim}",
587
603
  "|" => "\\textbar{}",
588
604
  "<" => "\\textless{}",
589
- ">" => "\\textgreater{}"
605
+ ">" => "\\textgreater{}",
606
+ "[" => "{[}",
607
+ "]" => "{]}",
590
608
  }.merge(Hash[*("{}$%&_#".scan(/./).map {|c| [c, "\\#{c}"]}.flatten)]) # :nodoc:
591
609
  ESCAPE_RE = Regexp.union(*ESCAPE_MAP.collect {|k,v| k}) # :nodoc:
592
610
 
@@ -0,0 +1,303 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2016 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown which is licensed under the MIT.
7
+ #++
8
+ #
9
+
10
+ require 'kramdown/converter'
11
+
12
+ module Kramdown
13
+
14
+ module Converter
15
+
16
+ # Converts a Kramdown::Document to a manpage in groff format. See man(7), groff_man(7) and
17
+ # man-pages(7) for information regarding the output.
18
+ class Man < Base
19
+
20
+ def convert(el, opts = {:indent => 0, :result => ''}) #:nodoc:
21
+ send("convert_#{el.type}", el, opts)
22
+ end
23
+
24
+ private
25
+
26
+ def inner(el, opts, use = :all)
27
+ arr = el.children.reject {|e| e.type == :blank}
28
+ arr.each_with_index do |inner_el, index|
29
+ next if use == :rest && index == 0
30
+ break if use == :first && index > 0
31
+ options = opts.dup
32
+ options[:parent] = el
33
+ options[:index] = index
34
+ options[:prev] = (index == 0 ? nil : arr[index - 1])
35
+ options[:next] = (index == arr.length - 1 ? nil : arr[index + 1])
36
+ convert(inner_el, options)
37
+ end
38
+ end
39
+
40
+ def convert_root(el, opts)
41
+ @title_done = false
42
+ opts[:result] = ".\\\" generated by kramdown\n"
43
+ inner(el, opts)
44
+ opts[:result]
45
+ end
46
+
47
+ def convert_blank(*)
48
+ end
49
+ alias :convert_hr :convert_blank
50
+ alias :convert_xml_pi :convert_blank
51
+
52
+ def convert_p(el, opts)
53
+ if (opts[:index] != 0 && opts[:prev].type != :header) ||
54
+ (opts[:parent].type == :blockquote && opts[:index] == 0)
55
+ opts[:result] << macro("P")
56
+ end
57
+ inner(el, opts)
58
+ newline(opts[:result])
59
+ end
60
+
61
+ def convert_header(el, opts)
62
+ return unless opts[:parent].type == :root
63
+ case el.options[:level]
64
+ when 1
65
+ unless @title_done
66
+ @title_done = true
67
+ data = el.options[:raw_text].scan(/([^(]+)\s*\((\d\w*)\)(?:\s*-+\s*(.*))?/).first ||
68
+ el.options[:raw_text].scan(/([^\s]+)\s*(?:-*\s+)?()(.*)/).first
69
+ return unless data && data[0]
70
+ name = data[0]
71
+ section = (data[1].to_s.empty? ? el.attr['data-section'] || '7' : data[1])
72
+ description = (data[2].to_s.empty? ? nil : " - #{data[2]}")
73
+ date = el.attr['data-date'] ? quote(el.attr['data-date']) : nil
74
+ extra = (el.attr['data-extra'] ? quote(escape(el.attr['data-extra'].to_s)) : nil)
75
+ opts[:result] << macro("TH", quote(escape(name.upcase)), quote(section), date, extra)
76
+ if description
77
+ opts[:result] << macro("SH", "NAME") << escape("#{name}#{description}") << "\n"
78
+ end
79
+ end
80
+ when 2
81
+ opts[:result] << macro("SH", quote(escape(el.options[:raw_text])))
82
+ when 3
83
+ opts[:result] << macro("SS", quote(escape(el.options[:raw_text])))
84
+ else
85
+ warning("Header levels greater than three are not supported")
86
+ end
87
+ end
88
+
89
+ def convert_codeblock(el, opts)
90
+ opts[:result] << macro("sp") << macro("RS", 4) << macro("EX")
91
+ opts[:result] << newline(escape(el.value, true))
92
+ opts[:result] << macro("EE") << macro("RE")
93
+ end
94
+
95
+ def convert_blockquote(el, opts)
96
+ opts[:result] << macro("RS")
97
+ inner(el, opts)
98
+ opts[:result] << macro("RE")
99
+ end
100
+
101
+ def convert_ul(el, opts)
102
+ compact = (el.attr['class'] =~ /\bcompact\b/)
103
+ opts[:result] << macro("sp") << macro("PD", 0) if compact
104
+ inner(el, opts)
105
+ opts[:result] << macro("PD") if compact
106
+ end
107
+ alias :convert_dl :convert_ul
108
+ alias :convert_ol :convert_ul
109
+
110
+ def convert_li(el, opts)
111
+ sym = (opts[:parent].type == :ul ? '\(bu' : "#{opts[:index] + 1}.")
112
+ opts[:result] << macro("IP", sym, 4)
113
+ inner(el, opts, :first)
114
+ if el.children.size > 1
115
+ opts[:result] << macro("RS")
116
+ inner(el, opts, :rest)
117
+ opts[:result] << macro("RE")
118
+ end
119
+ end
120
+
121
+ def convert_dt(el, opts)
122
+ opts[:result] << macro(opts[:prev] && opts[:prev].type == :dt ? "TQ" : "TP")
123
+ inner(el, opts)
124
+ opts[:result] << "\n"
125
+ end
126
+
127
+ def convert_dd(el, opts)
128
+ inner(el, opts, :first)
129
+ if el.children.size > 1
130
+ opts[:result] << macro("RS")
131
+ inner(el, opts, :rest)
132
+ opts[:result] << macro("RE")
133
+ end
134
+ opts[:result] << macro("sp") if opts[:next] && opts[:next].type == :dd
135
+ end
136
+
137
+ TABLE_CELL_ALIGNMENT = {:left => 'l', :center => 'c', :right => 'r', :default => 'l'}
138
+
139
+ def convert_table(el, opts)
140
+ opts[:alignment] = el.options[:alignment].map {|a| TABLE_CELL_ALIGNMENT[a]}
141
+ table_options = ["box"]
142
+ table_options << "center" if el.attr['class'] =~ /\bcenter\b/
143
+ opts[:result] << macro("TS") << "#{table_options.join(" ")} ;\n"
144
+ inner(el, opts)
145
+ opts[:result] << macro("TE") << macro("sp")
146
+ end
147
+
148
+ def convert_thead(el, opts)
149
+ opts[:result] << opts[:alignment].map {|a| "#{a}b"}.join(' ') << " .\n"
150
+ inner(el, opts)
151
+ opts[:result] << "=\n"
152
+ end
153
+
154
+ def convert_tbody(el, opts)
155
+ opts[:result] << ".T&\n" if opts[:index] != 0
156
+ opts[:result] << opts[:alignment].join(' ') << " .\n"
157
+ inner(el, opts)
158
+ opts[:result] << (opts[:next].type == :tfoot ? "=\n" : "_\n") if opts[:next]
159
+ end
160
+
161
+ def convert_tfoot(el, opts)
162
+ inner(el, opts)
163
+ end
164
+
165
+ def convert_tr(el, opts)
166
+ inner(el, opts)
167
+ opts[:result] << "\n"
168
+ end
169
+
170
+ def convert_td(el, opts)
171
+ result = opts[:result]
172
+ opts[:result] = ''
173
+ inner(el, opts)
174
+ if opts[:result] =~ /\n/
175
+ warning("Table cells using links are not supported")
176
+ result << "\t"
177
+ else
178
+ result << opts[:result] << "\t"
179
+ end
180
+ end
181
+
182
+ def convert_html_element(*)
183
+ warning("HTML elements are not supported")
184
+ end
185
+
186
+ def convert_xml_comment(el, opts)
187
+ newline(opts[:result]) << ".\"#{escape(el.value, true).rstrip.gsub(/\n/, "\n.\"")}\n"
188
+ end
189
+ alias :convert_comment :convert_xml_comment
190
+
191
+
192
+ def convert_a(el, opts)
193
+ if el.children.size == 1 && el.children[0].type == :text &&
194
+ el.attr['href'] == el.children[0].value
195
+ newline(opts[:result]) << macro("UR", escape(el.attr['href'])) << macro("UE")
196
+ elsif el.attr['href'].start_with?('mailto:')
197
+ newline(opts[:result]) << macro("MT", escape(el.attr['href'].sub(/^mailto:/, ''))) <<
198
+ macro("UE")
199
+ else
200
+ newline(opts[:result]) << macro("UR", escape(el.attr['href']))
201
+ inner(el, opts)
202
+ newline(opts[:result]) << macro("UE")
203
+ end
204
+ end
205
+
206
+ def convert_img(el, opts)
207
+ warning("Images are not supported")
208
+ end
209
+
210
+ def convert_em(el, opts)
211
+ opts[:result] << '\fI'
212
+ inner(el, opts)
213
+ opts[:result] << '\fP'
214
+ end
215
+
216
+ def convert_strong(el, opts)
217
+ opts[:result] << '\fB'
218
+ inner(el, opts)
219
+ opts[:result] << '\fP'
220
+ end
221
+
222
+ def convert_codespan(el, opts)
223
+ opts[:result] << "\\fB#{escape(el.value)}\\fP"
224
+ end
225
+
226
+ def convert_br(el, opts)
227
+ newline(opts[:result]) << macro("br")
228
+ end
229
+
230
+ def convert_abbreviation(el, opts)
231
+ opts[:result] << escape(el.value)
232
+ end
233
+
234
+ def convert_math(el, opts)
235
+ if el.options[:category] == :block
236
+ convert_codeblock(el, opts)
237
+ else
238
+ convert_codespan(el, opts)
239
+ end
240
+ end
241
+
242
+ def convert_footnote(*)
243
+ warning("Footnotes are not supported")
244
+ end
245
+
246
+ def convert_raw(*)
247
+ warning("Raw content is not supported")
248
+ end
249
+
250
+
251
+
252
+ def convert_text(el, opts)
253
+ text = escape(el.value)
254
+ text.lstrip! if opts[:result][-1] == ?\n
255
+ opts[:result] << text
256
+ end
257
+
258
+ def convert_entity(el, opts)
259
+ opts[:result] << unicode_char(el.value.code_point)
260
+ end
261
+
262
+ def convert_smart_quote(el, opts)
263
+ opts[:result] << unicode_char(::Kramdown::Utils::Entities.entity(el.value.to_s).code_point)
264
+ end
265
+
266
+ TYPOGRAPHIC_SYMS_MAP = {
267
+ :mdash => '\(em', :ndash => '\(em', :hellip => '\.\.\.',
268
+ :laquo_space => '\[Fo]', :raquo_space => '\[Fc]', :laquo => '\[Fo]', :raquo => '\[Fc]'
269
+ }
270
+
271
+ def convert_typographic_sym(el, opts)
272
+ opts[:result] << TYPOGRAPHIC_SYMS_MAP[el.value]
273
+ end
274
+
275
+ def macro(name, *args)
276
+ ".#{[name, *args].compact.join(' ')}\n"
277
+ end
278
+
279
+ def newline(text)
280
+ text << "\n" unless text[-1] == ?\n
281
+ text
282
+ end
283
+
284
+ def quote(text)
285
+ "\"#{text.gsub(/"/, '\\"')}\""
286
+ end
287
+
288
+ def escape(text, preserve_whitespace = false)
289
+ text = (preserve_whitespace ? text.dup : text.gsub(/\s+/, ' '))
290
+ text.gsub!('\\', "\\e")
291
+ text.gsub!(/^\./, '\\\\&.')
292
+ text.gsub!(/[.'-]/) {|m| "\\#{m}"}
293
+ text
294
+ end
295
+
296
+ def unicode_char(codepoint)
297
+ "\\[u#{codepoint.to_s(16).rjust(4, '0')}]"
298
+ end
299
+
300
+ end
301
+
302
+ end
303
+ end
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  #--
4
- # Copyright (C) 2009-2015 Thomas Leitner <t_leitner@gmx.at>
4
+ # Copyright (C) 2009-2016 Thomas Leitner <t_leitner@gmx.at>
5
5
  #
6
6
  # This file is part of kramdown which is licensed under the MIT.
7
7
  #++
@@ -13,7 +13,7 @@ module Kramdown::Converter::MathEngine
13
13
  module Itex2MML
14
14
 
15
15
  begin
16
- # RM require 'itextomml'
16
+ require 'itextomml'
17
17
 
18
18
  # Itex2MML is available if this constant is +true+.
19
19
  AVAILABLE = true
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  #--
4
- # Copyright (C) 2009-2015 Thomas Leitner <t_leitner@gmx.at>
4
+ # Copyright (C) 2009-2016 Thomas Leitner <t_leitner@gmx.at>
5
5
  #
6
6
  # This file is part of kramdown which is licensed under the MIT.
7
7
  #++
@@ -36,10 +36,20 @@ module Kramdown::Converter::MathEngine
36
36
 
37
37
  preview = (preview == true ? converter.escape_html(el.value) : preview.to_s)
38
38
 
39
+ preview_as_code = converter.options[:math_engine_opts][:preview_as_code]
40
+
39
41
  if el.options[:category] == :block
40
- converter.format_as_block_html('div', {'class' => 'MathJax_Preview'}, preview, opts[:indent])
42
+ if preview_as_code
43
+ converter.format_as_block_html('pre', {'class' => 'MathJax_Preview'},
44
+ converter.format_as_span_html('code', {}, preview),
45
+ opts[:indent])
46
+ else
47
+ converter.format_as_block_html('div', {'class' => 'MathJax_Preview'}, preview,
48
+ opts[:indent])
49
+ end
41
50
  else
42
- converter.format_as_span_html('span', {'class' => 'MathJax_Preview'}, preview)
51
+ converter.format_as_span_html(preview_as_code ? 'code' : 'span',
52
+ {'class' => 'MathJax_Preview'}, preview)
43
53
  end
44
54
  end
45
55
 
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2016 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown which is licensed under the MIT.
7
+ #++
8
+ #
9
+
10
+ module Kramdown::Converter::MathEngine
11
+
12
+ # Uses the mathjax-node-cli library for converting math formulas to MathML.
13
+ module MathjaxNode
14
+
15
+ # MathjaxNode is available if this constant is +true+.
16
+ AVAILABLE = begin
17
+ %x{node --version}[1..-2] >= '4.5'
18
+ rescue
19
+ begin
20
+ %x{nodejs --version}[1..-2] >= '4.5'
21
+ rescue
22
+ false
23
+ end
24
+ end && begin
25
+ npm = %x{npm --global --depth=1 list mathjax-node-cli 2>&1}
26
+
27
+ unless /mathjax-node-cli@/ === npm.lines.drop(1).join("\n")
28
+ npm = %x{npm --depth=1 list mathjax-node-cli 2>&1}
29
+ end
30
+
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
+ rescue
34
+ false
35
+ end
36
+
37
+ def self.call(converter, el, opts)
38
+ type = el.options[:category]
39
+
40
+ cmd = [T2MPATH]
41
+ cmd << "--inline" unless type == :block
42
+ cmd << "--semantics" if converter.options[:math_engine_opts][:semantics] == true
43
+ cmd << "--notexhints" if converter.options[:math_engine_opts][:texhints] == false
44
+ result = IO.popen(cmd << el.value).read.strip
45
+
46
+ attr = el.attr.dup
47
+ attr.delete('xmlns')
48
+ attr.delete('display')
49
+ result.insert("<math".length, converter.html_attributes(attr))
50
+
51
+ (type == :block ? "#{' '*opts[:indent]}#{result}\n" : result)
52
+ end
53
+
54
+ end
55
+
56
+ end