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.
- checksums.yaml +5 -5
- data/README.md +6 -2
- data/lib/kramdown.rb +1 -1
- data/lib/kramdown/converter.rb +10 -11
- data/lib/kramdown/converter/base.rb +19 -12
- data/lib/kramdown/converter/hash_ast.rb +38 -0
- data/lib/kramdown/converter/html.rb +71 -39
- data/lib/kramdown/converter/kramdown.rb +19 -10
- data/lib/kramdown/converter/latex.rb +28 -10
- data/lib/kramdown/converter/man.rb +303 -0
- data/lib/kramdown/converter/math_engine/itex2mml.rb +2 -2
- data/lib/kramdown/converter/math_engine/mathjax.rb +13 -3
- data/lib/kramdown/converter/math_engine/mathjaxnode.rb +56 -0
- data/lib/kramdown/converter/math_engine/ritex.rb +2 -2
- data/lib/kramdown/converter/math_engine/sskatex.rb +97 -0
- data/lib/kramdown/converter/pdf.rb +6 -6
- data/lib/kramdown/converter/remove_html_tags.rb +5 -3
- data/lib/kramdown/converter/syntax_highlighter.rb +5 -2
- data/lib/kramdown/converter/syntax_highlighter/coderay.rb +8 -5
- data/lib/kramdown/converter/syntax_highlighter/minted.rb +35 -0
- data/lib/kramdown/converter/syntax_highlighter/rouge.rb +48 -10
- data/lib/kramdown/converter/toc.rb +2 -2
- data/lib/kramdown/document.rb +16 -19
- data/lib/kramdown/element.rb +5 -1
- data/lib/kramdown/error.rb +1 -1
- data/lib/kramdown/options.rb +103 -7
- data/lib/kramdown/parser.rb +1 -1
- data/lib/kramdown/parser/base.rb +12 -18
- data/lib/kramdown/parser/gfm.rb +142 -11
- data/lib/kramdown/parser/html.rb +28 -18
- data/lib/kramdown/parser/kramdown.rb +45 -36
- data/lib/kramdown/parser/kramdown/abbreviation.rb +1 -1
- data/lib/kramdown/parser/kramdown/autolink.rb +2 -8
- data/lib/kramdown/parser/kramdown/blank_line.rb +2 -2
- data/lib/kramdown/parser/kramdown/block_boundary.rb +4 -4
- data/lib/kramdown/parser/kramdown/blockquote.rb +4 -4
- data/lib/kramdown/parser/kramdown/codeblock.rb +11 -8
- data/lib/kramdown/parser/kramdown/codespan.rb +1 -1
- data/lib/kramdown/parser/kramdown/emphasis.rb +2 -2
- data/lib/kramdown/parser/kramdown/eob.rb +1 -1
- data/lib/kramdown/parser/kramdown/escaped_chars.rb +1 -1
- data/lib/kramdown/parser/kramdown/extensions.rb +6 -3
- data/lib/kramdown/parser/kramdown/footnote.rb +4 -5
- data/lib/kramdown/parser/kramdown/header.rb +2 -2
- data/lib/kramdown/parser/kramdown/horizontal_rule.rb +1 -1
- data/lib/kramdown/parser/kramdown/html.rb +8 -8
- data/lib/kramdown/parser/kramdown/html_entity.rb +2 -2
- data/lib/kramdown/parser/kramdown/line_break.rb +1 -1
- data/lib/kramdown/parser/kramdown/link.rb +5 -4
- data/lib/kramdown/parser/kramdown/list.rb +17 -10
- data/lib/kramdown/parser/kramdown/math.rb +2 -2
- data/lib/kramdown/parser/kramdown/paragraph.rb +19 -8
- data/lib/kramdown/parser/kramdown/smart_quotes.rb +3 -3
- data/lib/kramdown/parser/kramdown/table.rb +10 -12
- data/lib/kramdown/parser/kramdown/typographic_symbol.rb +1 -1
- data/lib/kramdown/parser/markdown.rb +2 -2
- data/lib/kramdown/utils.rb +2 -1
- data/lib/kramdown/utils/configurable.rb +2 -2
- data/lib/kramdown/utils/entities.rb +1 -1
- data/lib/kramdown/utils/html.rb +2 -2
- data/lib/kramdown/utils/lru_cache.rb +40 -0
- data/lib/kramdown/utils/ordered_hash.rb +2 -71
- data/lib/kramdown/utils/string_scanner.rb +2 -2
- data/lib/kramdown/utils/unidecoder.rb +2 -2
- data/lib/kramdown/version.rb +2 -2
- data/lib/rubymotion/require_override.rb +9 -0
- data/lib/rubymotion/version.rb +1 -1
- data/spec/{helpers → motion-kramdown/_helpers}/it_behaves_like.rb +0 -0
- data/spec/{helpers → motion-kramdown/_helpers}/option_file.rb +2 -2
- data/spec/{helpers → motion-kramdown/_helpers}/tidy.rb +0 -0
- data/spec/motion-kramdown/bench_mark.rb +37 -0
- data/spec/{document_tree.rb → motion-kramdown/document_tree.rb} +11 -1
- data/spec/{gfm_to_html.rb → motion-kramdown/gfm_to_html.rb} +51 -18
- data/spec/{html_to_html.rb → motion-kramdown/html_to_html.rb} +27 -9
- data/spec/{html_to_kramdown_to_html.rb → motion-kramdown/html_to_kramdown_to_html.rb} +35 -16
- data/spec/motion-kramdown/kramdown_to_xxx.rb +75 -0
- data/spec/{test_location.rb → motion-kramdown/test_location.rb} +0 -0
- data/spec/{test_string_scanner_kramdown.rb → motion-kramdown/test_string_scanner_kramdown.rb} +0 -0
- data/spec/motion-kramdown/text_manpage.rb +11 -0
- data/spec/{text_to_kramdown_to_html.rb → motion-kramdown/text_to_kramdown_to_html.rb} +30 -19
- data/spec/{text_to_latex.rb → motion-kramdown/text_to_latex.rb} +0 -0
- data/spec/{helpers/spec_options.rb → spec_helper.rb} +13 -2
- metadata +54 -33
- data/lib/kramdown/compatibility.rb +0 -36
- data/spec/bench_mark.rb +0 -43
- 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-
|
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
|
-
|
11
|
-
|
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
|
-
|
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{#{
|
213
|
+
"\\hyperlink{#{url[1..-1].gsub('%', "\\%")}}{#{inner(el, opts)}}"
|
209
214
|
else
|
210
|
-
"\\href{#{
|
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
|
-
|
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
|
-
|
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-
|
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
|
-
|
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-
|
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
|
-
|
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(
|
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
|