remi-maruku 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. data/Rakefile +73 -0
  2. data/bin/marudown +29 -0
  3. data/bin/maruku +176 -0
  4. data/bin/marutest +338 -0
  5. data/bin/marutex +31 -0
  6. data/docs/changelog.md +334 -0
  7. data/docs/div_syntax.md +36 -0
  8. data/docs/entity_test.md +23 -0
  9. data/docs/markdown_syntax.md +899 -0
  10. data/docs/maruku.md +346 -0
  11. data/docs/math.md +194 -0
  12. data/docs/other_stuff.md +51 -0
  13. data/docs/proposal.md +309 -0
  14. data/lib/maruku.rb +141 -0
  15. data/lib/maruku/attributes.rb +227 -0
  16. data/lib/maruku/defaults.rb +70 -0
  17. data/lib/maruku/errors_management.rb +92 -0
  18. data/lib/maruku/ext/div.rb +100 -0
  19. data/lib/maruku/ext/math.rb +41 -0
  20. data/lib/maruku/ext/math/elements.rb +27 -0
  21. data/lib/maruku/ext/math/latex_fix.rb +11 -0
  22. data/lib/maruku/ext/math/mathml_engines/blahtex.rb +104 -0
  23. data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +29 -0
  24. data/lib/maruku/ext/math/mathml_engines/none.rb +20 -0
  25. data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
  26. data/lib/maruku/ext/math/parsing.rb +105 -0
  27. data/lib/maruku/ext/math/to_html.rb +170 -0
  28. data/lib/maruku/ext/math/to_latex.rb +22 -0
  29. data/lib/maruku/helpers.rb +260 -0
  30. data/lib/maruku/input/charsource.rb +326 -0
  31. data/lib/maruku/input/extensions.rb +69 -0
  32. data/lib/maruku/input/html_helper.rb +189 -0
  33. data/lib/maruku/input/linesource.rb +111 -0
  34. data/lib/maruku/input/parse_block.rb +613 -0
  35. data/lib/maruku/input/parse_doc.rb +227 -0
  36. data/lib/maruku/input/parse_span_better.rb +732 -0
  37. data/lib/maruku/input/rubypants.rb +225 -0
  38. data/lib/maruku/input/type_detection.rb +144 -0
  39. data/lib/maruku/input_textile2/t2_parser.rb +163 -0
  40. data/lib/maruku/maruku.rb +33 -0
  41. data/lib/maruku/output/s5/fancy.rb +756 -0
  42. data/lib/maruku/output/s5/to_s5.rb +125 -0
  43. data/lib/maruku/output/to_html.rb +971 -0
  44. data/lib/maruku/output/to_latex.rb +563 -0
  45. data/lib/maruku/output/to_latex_entities.rb +367 -0
  46. data/lib/maruku/output/to_latex_strings.rb +64 -0
  47. data/lib/maruku/output/to_markdown.rb +164 -0
  48. data/lib/maruku/output/to_s.rb +53 -0
  49. data/lib/maruku/string_utils.rb +191 -0
  50. data/lib/maruku/structures.rb +165 -0
  51. data/lib/maruku/structures_inspect.rb +87 -0
  52. data/lib/maruku/structures_iterators.rb +61 -0
  53. data/lib/maruku/tests/benchmark.rb +82 -0
  54. data/lib/maruku/tests/new_parser.rb +370 -0
  55. data/lib/maruku/tests/tests.rb +136 -0
  56. data/lib/maruku/textile2.rb +1 -0
  57. data/lib/maruku/toc.rb +199 -0
  58. data/lib/maruku/usage/example1.rb +33 -0
  59. data/lib/maruku/version.rb +40 -0
  60. data/tests/bugs/code_in_links.md +16 -0
  61. data/tests/bugs/complex_escaping.md +4 -0
  62. data/tests/math/syntax.md +46 -0
  63. data/tests/math_usage/document.md +13 -0
  64. data/tests/others/abbreviations.md +11 -0
  65. data/tests/others/blank.md +4 -0
  66. data/tests/others/code.md +5 -0
  67. data/tests/others/code2.md +8 -0
  68. data/tests/others/code3.md +16 -0
  69. data/tests/others/email.md +4 -0
  70. data/tests/others/entities.md +19 -0
  71. data/tests/others/escaping.md +16 -0
  72. data/tests/others/extra_dl.md +101 -0
  73. data/tests/others/extra_header_id.md +13 -0
  74. data/tests/others/extra_table1.md +40 -0
  75. data/tests/others/footnotes.md +17 -0
  76. data/tests/others/headers.md +10 -0
  77. data/tests/others/hrule.md +10 -0
  78. data/tests/others/images.md +20 -0
  79. data/tests/others/inline_html.md +42 -0
  80. data/tests/others/links.md +38 -0
  81. data/tests/others/list1.md +4 -0
  82. data/tests/others/list2.md +5 -0
  83. data/tests/others/list3.md +8 -0
  84. data/tests/others/lists.md +32 -0
  85. data/tests/others/lists_after_paragraph.md +44 -0
  86. data/tests/others/lists_ol.md +39 -0
  87. data/tests/others/misc_sw.md +105 -0
  88. data/tests/others/one.md +1 -0
  89. data/tests/others/paragraphs.md +13 -0
  90. data/tests/others/sss06.md +352 -0
  91. data/tests/others/test.md +4 -0
  92. data/tests/s5/s5profiling.md +48 -0
  93. data/tests/unittest/abbreviations.md +72 -0
  94. data/tests/unittest/alt.md +30 -0
  95. data/tests/unittest/attributes/att2.md +34 -0
  96. data/tests/unittest/attributes/att3.md +45 -0
  97. data/tests/unittest/attributes/attributes.md +82 -0
  98. data/tests/unittest/attributes/circular.md +43 -0
  99. data/tests/unittest/attributes/default.md +38 -0
  100. data/tests/unittest/blank.md +39 -0
  101. data/tests/unittest/blanks_in_code.md +106 -0
  102. data/tests/unittest/bug_def.md +29 -0
  103. data/tests/unittest/bug_table.md +67 -0
  104. data/tests/unittest/code.md +53 -0
  105. data/tests/unittest/code2.md +46 -0
  106. data/tests/unittest/code3.md +102 -0
  107. data/tests/unittest/data_loss.md +42 -0
  108. data/tests/unittest/divs/div1.md +204 -0
  109. data/tests/unittest/divs/div2.md +34 -0
  110. data/tests/unittest/divs/div3_nest.md +62 -0
  111. data/tests/unittest/easy.md +28 -0
  112. data/tests/unittest/email.md +33 -0
  113. data/tests/unittest/encoding/iso-8859-1.md +38 -0
  114. data/tests/unittest/encoding/utf-8.md +33 -0
  115. data/tests/unittest/entities.md +124 -0
  116. data/tests/unittest/escaping.md +89 -0
  117. data/tests/unittest/extra_dl.md +72 -0
  118. data/tests/unittest/extra_header_id.md +86 -0
  119. data/tests/unittest/extra_table1.md +55 -0
  120. data/tests/unittest/footnotes.md +126 -0
  121. data/tests/unittest/headers.md +54 -0
  122. data/tests/unittest/hex_entities.md +50 -0
  123. data/tests/unittest/hrule.md +60 -0
  124. data/tests/unittest/html2.md +38 -0
  125. data/tests/unittest/html3.md +47 -0
  126. data/tests/unittest/html4.md +42 -0
  127. data/tests/unittest/html5.md +38 -0
  128. data/tests/unittest/ie.md +82 -0
  129. data/tests/unittest/images.md +114 -0
  130. data/tests/unittest/images2.md +46 -0
  131. data/tests/unittest/inline_html.md +260 -0
  132. data/tests/unittest/inline_html2.md +36 -0
  133. data/tests/unittest/links.md +197 -0
  134. data/tests/unittest/list1.md +66 -0
  135. data/tests/unittest/list2.md +76 -0
  136. data/tests/unittest/list3.md +88 -0
  137. data/tests/unittest/list4.md +116 -0
  138. data/tests/unittest/lists.md +241 -0
  139. data/tests/unittest/lists11.md +31 -0
  140. data/tests/unittest/lists6.md +54 -0
  141. data/tests/unittest/lists7.md +79 -0
  142. data/tests/unittest/lists7b.md +136 -0
  143. data/tests/unittest/lists8.md +83 -0
  144. data/tests/unittest/lists9.md +85 -0
  145. data/tests/unittest/lists_after_paragraph.md +268 -0
  146. data/tests/unittest/lists_ol.md +324 -0
  147. data/tests/unittest/loss.md +29 -0
  148. data/tests/unittest/math/equations.md +69 -0
  149. data/tests/unittest/math/inline.md +66 -0
  150. data/tests/unittest/math/math2.md +110 -0
  151. data/tests/unittest/math/notmath.md +40 -0
  152. data/tests/unittest/math/table.md +43 -0
  153. data/tests/unittest/math/table2.md +60 -0
  154. data/tests/unittest/misc_sw.md +615 -0
  155. data/tests/unittest/notyet/escape.md +36 -0
  156. data/tests/unittest/notyet/header_after_par.md +81 -0
  157. data/tests/unittest/notyet/ticks.md +31 -0
  158. data/tests/unittest/notyet/triggering.md +206 -0
  159. data/tests/unittest/olist.md +64 -0
  160. data/tests/unittest/one.md +28 -0
  161. data/tests/unittest/paragraph.md +29 -0
  162. data/tests/unittest/paragraph_rules/dont_merge_ref.md +57 -0
  163. data/tests/unittest/paragraph_rules/tab_is_blank.md +39 -0
  164. data/tests/unittest/paragraphs.md +66 -0
  165. data/tests/unittest/pending/amps.md +29 -0
  166. data/tests/unittest/pending/empty_cells.md +53 -0
  167. data/tests/unittest/pending/link.md +103 -0
  168. data/tests/unittest/recover/recover_links.md +28 -0
  169. data/tests/unittest/references/long_example.md +88 -0
  170. data/tests/unittest/references/spaces_and_numbers.md +28 -0
  171. data/tests/unittest/smartypants.md +171 -0
  172. data/tests/unittest/syntax_hl.md +80 -0
  173. data/tests/unittest/table_attributes.md +52 -0
  174. data/tests/unittest/test.md +32 -0
  175. data/tests/unittest/wrapping.md +88 -0
  176. data/tests/unittest/xml.md +54 -0
  177. data/tests/unittest/xml2.md +34 -0
  178. data/tests/unittest/xml3.md +44 -0
  179. data/tests/unittest/xml_instruction.md +72 -0
  180. data/tests/utf8-files/simple.md +1 -0
  181. data/unit_test_block.sh +5 -0
  182. data/unit_test_span.sh +2 -0
  183. metadata +243 -0
@@ -0,0 +1,41 @@
1
+
2
+
3
+ require 'maruku/ext/math/elements'
4
+ require 'maruku/ext/math/parsing'
5
+ require 'maruku/ext/math/to_latex'
6
+ require 'maruku/ext/math/to_html'
7
+
8
+ require 'maruku/ext/math/mathml_engines/none'
9
+ require 'maruku/ext/math/mathml_engines/ritex'
10
+ require 'maruku/ext/math/mathml_engines/itex2mml'
11
+ require 'maruku/ext/math/mathml_engines/blahtex'
12
+
13
+
14
+ =begin maruku_doc
15
+ Attribute: math_enabled
16
+ Scope: global, document
17
+ Summary: Enables parsing of LaTeX math
18
+
19
+ To explicitly disable the math parsing:
20
+
21
+ Maruku.new(string, {:math_enabled => false})
22
+ {:ruby}
23
+
24
+ =end
25
+
26
+ MaRuKu::Globals[:math_enabled] = true
27
+
28
+
29
+ =begin maruku_doc
30
+ Attribute: math_numbered
31
+ Scope: global, document
32
+ Summary: Math openings which should be numerated
33
+
34
+ Array containing any of `'\\['`, `'\\begin{equation}'`, `'$$'`.
35
+
36
+ MaRuKu::Globals[:math_numbered] = ['\\[']
37
+
38
+ =end
39
+
40
+
41
+ MaRuKu::Globals[:math_numbered] = []
@@ -0,0 +1,27 @@
1
+ module MaRuKu; class MDElement
2
+
3
+ def md_inline_math(math)
4
+ self.md_el(:inline_math, [], meta={:math=>math})
5
+ end
6
+
7
+ def md_equation(math, label, numerate)
8
+ reglabel= /\\label\{(\w+)\}/
9
+ if math =~ reglabel
10
+ label = $1
11
+ math.gsub!(reglabel,'')
12
+ end
13
+ # puts "Found label = #{label} math #{math.inspect} "
14
+ num = nil
15
+ if (label || numerate) && @doc #take number
16
+ @doc.eqid2eq ||= {}
17
+ num = @doc.eqid2eq.size + 1
18
+ label = "eq#{num}" if not label # FIXME do id for document
19
+ end
20
+ e = self.md_el(:equation, [], meta={:math=>math, :label=>label,:num=>num})
21
+ if label && @doc #take number
22
+ @doc.eqid2eq[label] = e
23
+ end
24
+ e
25
+ end
26
+
27
+ end end
@@ -0,0 +1,11 @@
1
+ class String
2
+ # fix some LaTeX command-name clashes
3
+ def fix_latex
4
+ if #{html_math_engine} == 'itex2mml'
5
+ s = self.gsub("\\mathop{", "\\operatorname{")
6
+ s.gsub("\\space{", "\\itexspace{")
7
+ else
8
+ self
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,104 @@
1
+
2
+ require 'tempfile'
3
+ require 'fileutils'
4
+ require 'digest/md5'
5
+ require 'pstore'
6
+
7
+ module MaRuKu; module Out; module HTML
8
+
9
+ PNG = Struct.new(:src,:depth,:height)
10
+
11
+ def convert_to_png_blahtex(kind, tex)
12
+ begin
13
+ FileUtils::mkdir_p MaRuKu::Globals[:html_png_dir]
14
+
15
+ # first, we check whether this image has already been processed
16
+ md5sum = Digest::MD5.hexdigest(tex+" params: ")
17
+ result_file = File.join(MaRuKu::Globals[:html_png_dir], md5sum+".txt")
18
+
19
+ if not File.exists?(result_file)
20
+ tmp_in = Tempfile.new('maruku_blahtex')
21
+ f = tmp_in.open
22
+ f.write tex
23
+ f.close
24
+
25
+ resolution = get_setting(:html_png_resolution)
26
+
27
+ options = "--png --use-preview-package --shell-dvipng 'dvipng -D #{resolution}' "
28
+ options += ("--png-directory '%s'" % MaRuKu::Globals[:html_png_dir])
29
+
30
+ cmd = "blahtex #{options} < #{tmp_in.path} > #{result_file}"
31
+ $stderr.puts "$ #{cmd}"
32
+ system cmd
33
+ tmp_in.delete
34
+ end
35
+
36
+ result = File.read(result_file)
37
+ if result.nil? || result.empty?
38
+ raise "Blahtex error: empty output"
39
+ end
40
+
41
+ doc = Document.new(result, {:respect_whitespace =>:all})
42
+ png = doc.root.elements[1]
43
+ if png.name != 'png'
44
+ raise "Blahtex error: \n#{doc}"
45
+ end
46
+ depth = png.elements['depth'] || (raise "No depth element in:\n #{doc}")
47
+ height = png.elements['height'] || (raise "No height element in:\n #{doc}")
48
+ md5 = png.elements['md5'] || (raise "No md5 element in:\n #{doc}")
49
+
50
+ depth = depth.text.to_f
51
+ height = height.text.to_f # XXX check != 0
52
+ md5 = md5.text
53
+
54
+ dir_url = MaRuKu::Globals[:html_png_url]
55
+ return PNG.new("#{dir_url}#{md5}.png", depth, height)
56
+ rescue Exception => e
57
+ maruku_error "Error: #{e}"
58
+ end
59
+ nil
60
+ end
61
+
62
+ BlahtexCache = PStore.new("blahtex_cache.pstore")
63
+
64
+ def convert_to_mathml_blahtex(kind, tex)
65
+ begin
66
+ BlahtexCache.transaction do
67
+ if BlahtexCache[tex].nil?
68
+ tmp_in = Tempfile.new('maruku_blahtex')
69
+ f = tmp_in.open
70
+ f.write tex
71
+ f.close
72
+ tmp_out = Tempfile.new('maruku_blahtex')
73
+
74
+ options = "--mathml"
75
+ cmd = "blahtex #{options} < #{tmp_in.path} > #{tmp_out.path}"
76
+ $stderr.puts "$ #{cmd}"
77
+ system cmd
78
+ tmp_in.delete
79
+
80
+ result = nil
81
+ File.open(tmp_out.path) do |f| result=f.read end
82
+ puts result
83
+
84
+ BlahtexCache[tex] = result
85
+ end
86
+
87
+ blahtex = BlahtexCache[tex]
88
+ doc = Document.new(blahtex, {:respect_whitespace =>:all})
89
+ mathml = doc.root.elements['mathml']
90
+ if not mathml
91
+ maruku_error "Blahtex error: \n#{doc}"
92
+ return nil
93
+ else
94
+ return mathml
95
+ end
96
+ end
97
+
98
+ rescue Exception => e
99
+ maruku_error "Error: #{e}"
100
+ end
101
+ nil
102
+ end
103
+
104
+ end end end
@@ -0,0 +1,29 @@
1
+
2
+ module MaRuKu; module Out; module HTML
3
+
4
+ def convert_to_mathml_itex2mml(kind, tex)
5
+ begin
6
+ if not $itex2mml_parser
7
+ require 'itextomml'
8
+ $itex2mml_parser = Itex2MML::Parser.new
9
+ end
10
+
11
+ itex_method = {:equation=>:block_filter,:inline=>:inline_filter}
12
+
13
+ mathml = $itex2mml_parser.send(itex_method[kind], tex)
14
+ doc = Document.new(mathml, {:respect_whitespace =>:all}).root
15
+ return doc
16
+ rescue LoadError => e
17
+ maruku_error "Could not load package 'itex2mml'.\n"+ "Please install it." unless $already_warned_itex2mml
18
+ $already_warned_itex2mml = true
19
+ rescue REXML::ParseException => e
20
+ maruku_error "Invalid MathML TeX: \n#{add_tabs(tex,1,'tex>')}"+
21
+ "\n\n #{e.inspect}"
22
+ rescue
23
+ maruku_error "Could not produce MathML TeX: \n#{tex}"+
24
+ "\n\n #{e.inspect}"
25
+ end
26
+ nil
27
+ end
28
+
29
+ end end end
@@ -0,0 +1,20 @@
1
+ module MaRuKu; module Out; module HTML
2
+
3
+ def convert_to_mathml_none(kind, tex)
4
+ # You can: either return a REXML::Element
5
+ # return Element.new 'div'
6
+ # or return an empty array on error
7
+ # return []
8
+ # or have a string parsed by REXML:
9
+ tex = tex.gsub('&','&amp;')
10
+ mathml = "<code>#{tex}</code>"
11
+ return Document.new(mathml).root
12
+ end
13
+
14
+ def convert_to_png_none(kind, tex)
15
+ return nil
16
+ end
17
+
18
+
19
+ end end end
20
+
@@ -0,0 +1,24 @@
1
+ module MaRuKu; module Out; module HTML
2
+
3
+ def convert_to_mathml_ritex(kind, tex)
4
+ begin
5
+ if not $ritex_parser
6
+ require 'ritex'
7
+ $ritex_parser = Ritex::Parser.new
8
+ end
9
+
10
+ mathml = $ritex_parser.parse(tex.strip)
11
+ doc = Document.new(mathml, {:respect_whitespace =>:all}).root
12
+ return doc
13
+ rescue LoadError => e
14
+ maruku_error "Could not load package 'ritex'.\n"+
15
+ "Please install it using:\n"+
16
+ " $ gem install ritex\n\n"+e.inspect
17
+ rescue Racc::ParseError => e
18
+ maruku_error "Could not parse TeX: \n#{tex}"+
19
+ "\n\n #{e.inspect}"
20
+ end
21
+ nil
22
+ end
23
+
24
+ end end end
@@ -0,0 +1,105 @@
1
+ module MaRuKu
2
+
3
+ class MDDocument
4
+ # Hash equation id (String) to equation element (MDElement)
5
+ attr_accessor :eqid2eq
6
+
7
+ def is_math_enabled?
8
+ get_setting :math_enabled
9
+ end
10
+ end
11
+ end
12
+
13
+
14
+ # Everything goes; takes care of escaping the "\$" inside the expression
15
+ RegInlineMath = /\${1}((?:[^\$]|\\\$)+)\$/
16
+
17
+ MaRuKu::In::Markdown::register_span_extension(
18
+ :chars => ?$,
19
+ :regexp => RegInlineMath,
20
+ :handler => lambda { |doc, src, con|
21
+ return false if not doc.is_math_enabled?
22
+
23
+ if m = src.read_regexp(RegInlineMath)
24
+ math = m.captures.compact.first
25
+ con.push doc.md_inline_math(math)
26
+ true
27
+ else
28
+ #puts "not math: #{src.cur_chars 10}"
29
+ false
30
+ end
31
+ }
32
+ )
33
+
34
+
35
+ MathOpen1 = Regexp.escape('\\begin{equation}')
36
+ MathClose1 = Regexp.escape('\\end{equation}')
37
+ MathOpen2 = Regexp.escape('\\[')
38
+ MathClose2 = Regexp.escape('\\]')
39
+ MathOpen3 = Regexp.escape('$$')
40
+ MathClose3 = Regexp.escape('$$')
41
+
42
+ EqLabel = /(?:\((\w+)\))/
43
+ EquationOpen = /#{MathOpen1}|#{MathOpen2}|#{MathOpen3}/
44
+ EquationClose = /#{MathClose1}|#{MathClose2}|#{MathClose3}/
45
+
46
+ # $1 is opening, $2 is tex
47
+ EquationStart = /^[ ]{0,3}(#{EquationOpen})(.*)$/
48
+ # $1 is tex, $2 is closing, $3 is tex
49
+ EquationEnd = /^(.*)(#{EquationClose})\s*#{EqLabel}?\s*$/
50
+ # $1 is opening, $2 is tex, $3 is closing, $4 is label
51
+ OneLineEquation = /^[ ]{0,3}(#{EquationOpen})(.*)(#{EquationClose})\s*#{EqLabel}?\s*$/
52
+
53
+ MaRuKu::In::Markdown::register_block_extension(
54
+ :regexp => EquationStart,
55
+ :handler => lambda { |doc, src, con|
56
+ return false if not doc.is_math_enabled?
57
+ first = src.shift_line
58
+ if first =~ OneLineEquation
59
+ opening, tex, closing, label = $1, $2, $3, $4
60
+ numerate = doc.get_setting(:math_numbered).include?(opening)
61
+ con.push doc.md_equation(tex, label, numerate)
62
+ else
63
+ first =~ EquationStart
64
+ opening, tex = $1, $2
65
+
66
+ numerate = doc.get_setting(:math_numbered).include?(opening)
67
+ label = nil
68
+ while true
69
+ if not src.cur_line
70
+ doc.maruku_error("Stream finished while reading equation\n\n"+
71
+ doc.add_tabs(tex,1,'$> '), src, con)
72
+ break
73
+ end
74
+ line = src.shift_line
75
+ if line =~ EquationEnd
76
+ tex_line, closing = $1, $2
77
+ label = $3 if $3
78
+ tex += tex_line + "\n"
79
+ break
80
+ else
81
+ tex += line + "\n"
82
+ end
83
+ end
84
+ con.push doc.md_equation(tex, label, numerate)
85
+ end
86
+ true
87
+ })
88
+
89
+
90
+ # This adds support for \eqref
91
+ RegEqrefLatex = /\\eqref\{(\w+)\}/
92
+ RegEqPar = /\(eq:(\w+)\)/
93
+ RegEqref = Regexp::union(RegEqrefLatex, RegEqPar)
94
+
95
+ MaRuKu::In::Markdown::register_span_extension(
96
+ :chars => [?\\, ?(],
97
+ :regexp => RegEqref,
98
+ :handler => lambda { |doc, src, con|
99
+ return false if not doc.is_math_enabled?
100
+ eqid = src.read_regexp(RegEqref).captures.compact.first
101
+ r = doc.md_el(:eqref, [], meta={:eqid=>eqid})
102
+ con.push r
103
+ true
104
+ }
105
+ )
@@ -0,0 +1,170 @@
1
+
2
+ =begin maruku_doc
3
+ Extension: math
4
+ Attribute: html_math_engine
5
+ Scope: document, element
6
+ Output: html
7
+ Summary: Select the rendering engine for MathML.
8
+ Default: <?mrk Globals[:html_math_engine].to_s ?>
9
+
10
+ Select the rendering engine for math.
11
+
12
+ If you want to use your custom engine `foo`, then set:
13
+
14
+ HTML math engine: foo
15
+ {:lang=markdown}
16
+
17
+ and then implement two functions:
18
+
19
+ def convert_to_mathml_foo(kind, tex)
20
+ ...
21
+ end
22
+ =end
23
+
24
+ =begin maruku_doc
25
+ Extension: math
26
+ Attribute: html_png_engine
27
+ Scope: document, element
28
+ Output: html
29
+ Summary: Select the rendering engine for math.
30
+ Default: <?mrk Globals[:html_math_engine].to_s ?>
31
+
32
+ Same thing as `html_math_engine`, only for PNG output.
33
+
34
+ def convert_to_png_foo(kind, tex)
35
+ # same thing
36
+ ...
37
+ end
38
+ {:lang=ruby}
39
+
40
+ =end
41
+
42
+ module MaRuKu; module Out; module HTML
43
+
44
+
45
+
46
+ # Creates an xml Mathml document of self.math
47
+ def render_mathml(kind, tex)
48
+ engine = get_setting(:html_math_engine)
49
+ method = "convert_to_mathml_#{engine}".to_sym
50
+ if self.respond_to? method
51
+ mathml = self.send(method, kind, tex)
52
+ return mathml || convert_to_mathml_none(kind, tex)
53
+ else
54
+ puts "A method called #{method} should be defined."
55
+ return convert_to_mathml_none(kind, tex)
56
+ end
57
+ end
58
+
59
+ # Creates an xml Mathml document of self.math
60
+ def render_png(kind, tex)
61
+ engine = get_setting(:html_png_engine)
62
+ method = "convert_to_png_#{engine}".to_sym
63
+ if self.respond_to? method
64
+ return self.send(method, kind, tex)
65
+ else
66
+ puts "A method called #{method} should be defined."
67
+ return nil
68
+ end
69
+ end
70
+
71
+ def pixels_per_ex
72
+ if not $pixels_per_ex
73
+ x = render_png(:inline, "x")
74
+ $pixels_per_ex = x.height # + x.depth
75
+ end
76
+ $pixels_per_ex
77
+ end
78
+
79
+ def adjust_png(png, use_depth)
80
+ src = png.src
81
+
82
+ height_in_px = png.height
83
+ depth_in_px = png.depth
84
+ height_in_ex = height_in_px / pixels_per_ex
85
+ depth_in_ex = depth_in_px / pixels_per_ex
86
+ total_height_in_ex = height_in_ex + depth_in_ex
87
+ style = ""
88
+ style += "vertical-align: -#{depth_in_ex}ex;" if use_depth
89
+ style += "height: #{total_height_in_ex}ex;"
90
+ img = Element.new 'img'
91
+ img.attributes['src'] = src
92
+ img.attributes['style'] = style
93
+ img.attributes['alt'] = "equation"
94
+ img
95
+ end
96
+
97
+ def to_html_inline_math
98
+ mathml = get_setting(:html_math_output_mathml) && render_mathml(:inline, self.math)
99
+ png = get_setting(:html_math_output_png) && render_png(:inline, self.math)
100
+
101
+ span = create_html_element 'span'
102
+ add_class_to(span, 'maruku-inline')
103
+
104
+ if mathml
105
+ add_class_to(mathml, 'maruku-mathml')
106
+ span << mathml
107
+ end
108
+
109
+ if png
110
+ img = adjust_png(png, use_depth=true)
111
+ add_class_to(img, 'maruku-png')
112
+ span << img
113
+ end
114
+ span
115
+
116
+ end
117
+
118
+ def to_html_equation
119
+ mathml = get_setting(:html_math_output_mathml) && render_mathml(:equation, self.math)
120
+ png = get_setting(:html_math_output_png) && render_png(:equation, self.math)
121
+
122
+ div = create_html_element 'div'
123
+ add_class_to(div, 'maruku-equation')
124
+ if self.label # then numerate
125
+ span = Element.new 'span'
126
+ span.attributes['class'] = 'maruku-eq-number'
127
+ num = self.num
128
+ span << Text.new("(#{num})")
129
+ div << span
130
+ div.attributes['id'] = "eq:#{self.label}"
131
+ end
132
+
133
+ if mathml
134
+ add_class_to(mathml, 'maruku-mathml')
135
+ div << mathml
136
+ end
137
+
138
+ if png
139
+ img = adjust_png(png, use_depth=false)
140
+ add_class_to(img, 'maruku-png')
141
+ div << img
142
+ end
143
+
144
+ source_div = Element.new 'div'
145
+ add_class_to(source_div, 'maruku-eq-tex')
146
+ code = convert_to_mathml_none(:equation, self.math)
147
+ code.attributes['style'] = 'display: none'
148
+ source_div << code
149
+ div << source_div
150
+ div
151
+ end
152
+
153
+ def to_html_eqref
154
+ if eq = self.doc.eqid2eq[self.eqid]
155
+ num = eq.num
156
+ a = Element.new 'a'
157
+ a.attributes['class'] = 'maruku-eqref'
158
+ a.attributes['href'] = "#eq:#{self.eqid}"
159
+ a << Text.new("(#{num})")
160
+ a
161
+ else
162
+ maruku_error "Cannot find equation #{self.eqid.inspect}"
163
+ Text.new "(eq:#{self.eqid})"
164
+ end
165
+ end
166
+
167
+
168
+ end end end
169
+
170
+