asciimath 1.0.9 → 2.0.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.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/AST.adoc +457 -0
  3. data/CHANGELOG.adoc +12 -0
  4. data/Gemfile.lock +39 -0
  5. data/README.adoc +27 -3
  6. data/asciimath.gemspec +9 -5
  7. data/lib/asciimath.rb +5 -4
  8. data/lib/asciimath/ast.rb +456 -0
  9. data/lib/asciimath/cli.rb +4 -1
  10. data/lib/asciimath/color_table.rb +21 -0
  11. data/lib/asciimath/html.rb +126 -111
  12. data/lib/asciimath/latex.rb +386 -0
  13. data/lib/asciimath/markup.rb +478 -0
  14. data/lib/asciimath/mathml.rb +189 -87
  15. data/lib/asciimath/parser.rb +498 -343
  16. data/lib/asciimath/symbol_table.rb +25 -0
  17. data/lib/asciimath/version.rb +1 -1
  18. data/spec/ast.rb +144 -0
  19. data/spec/parser_spec.rb +592 -165
  20. data/spec/schema/mathml2/common/common-attribs.xsd +41 -0
  21. data/spec/schema/mathml2/common/math.xsd +126 -0
  22. data/spec/schema/mathml2/common/xlink-href.xsd +20 -0
  23. data/spec/schema/mathml2/content/arith.xsd +90 -0
  24. data/spec/schema/mathml2/content/calculus.xsd +146 -0
  25. data/spec/schema/mathml2/content/common-attrib.xsd +30 -0
  26. data/spec/schema/mathml2/content/constants.xsd +83 -0
  27. data/spec/schema/mathml2/content/constructs.xsd +260 -0
  28. data/spec/schema/mathml2/content/elementary-functions.xsd +117 -0
  29. data/spec/schema/mathml2/content/functions.xsd +73 -0
  30. data/spec/schema/mathml2/content/linear-algebra.xsd +173 -0
  31. data/spec/schema/mathml2/content/logic.xsd +53 -0
  32. data/spec/schema/mathml2/content/relations.xsd +55 -0
  33. data/spec/schema/mathml2/content/semantics.xsd +85 -0
  34. data/spec/schema/mathml2/content/sets.xsd +236 -0
  35. data/spec/schema/mathml2/content/statistics.xsd +136 -0
  36. data/spec/schema/mathml2/content/tokens.xsd +120 -0
  37. data/spec/schema/mathml2/content/vector-calculus.xsd +88 -0
  38. data/spec/schema/mathml2/mathml2.xsd +59 -0
  39. data/spec/schema/mathml2/presentation/action.xsd +44 -0
  40. data/spec/schema/mathml2/presentation/characters.xsd +37 -0
  41. data/spec/schema/mathml2/presentation/common-attribs.xsd +113 -0
  42. data/spec/schema/mathml2/presentation/common-types.xsd +103 -0
  43. data/spec/schema/mathml2/presentation/error.xsd +40 -0
  44. data/spec/schema/mathml2/presentation/layout.xsd +195 -0
  45. data/spec/schema/mathml2/presentation/scripts.xsd +186 -0
  46. data/spec/schema/mathml2/presentation/space.xsd +52 -0
  47. data/spec/schema/mathml2/presentation/style.xsd +69 -0
  48. data/spec/schema/mathml2/presentation/table.xsd +216 -0
  49. data/spec/schema/mathml2/presentation/tokens.xsd +124 -0
  50. data/spec/schema/mathml3/mathml3-common.xsd +99 -0
  51. data/spec/schema/mathml3/mathml3-content.xsd +684 -0
  52. data/spec/schema/mathml3/mathml3-presentation.xsd +2151 -0
  53. data/spec/schema/mathml3/mathml3-strict-content.xsd +186 -0
  54. data/spec/schema/mathml3/mathml3.xsd +9 -0
  55. metadata +102 -10
  56. data/.gitignore +0 -16
  57. data/.travis.yml +0 -18
@@ -0,0 +1,25 @@
1
+ module AsciiMath
2
+ class SymbolTableBuilder
3
+ def initialize()
4
+ @table = {}
5
+ end
6
+
7
+ def add(*args)
8
+ raise 'Insufficient arguments' if args.length < 3
9
+
10
+ entry = {}
11
+ if args.last.is_a?(Hash)
12
+ entry.merge!(args.pop)
13
+ end
14
+ entry[:type] = args.pop
15
+ entry[:value] = args.pop
16
+
17
+ entry.freeze
18
+ args.each { |name| @table[name.freeze] = entry }
19
+ end
20
+
21
+ def build
22
+ @table.dup.freeze
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module AsciiMath
2
- VERSION = "1.0.9"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -0,0 +1,144 @@
1
+ require_relative '../lib/asciimath/ast'
2
+
3
+ module AsciiMath
4
+ module ASTHelper
5
+ ACTUAL_AST = Class.new do
6
+ include ::AsciiMath::AST
7
+ end.new
8
+
9
+ def grseq(*expressions)
10
+ group(seq(*expressions))
11
+ end
12
+
13
+ def seq(*expressions)
14
+ mapped = expressions.map { |e| to_ast(e) }
15
+ ACTUAL_AST.expression(*mapped)
16
+ end
17
+
18
+ def paren(*args)
19
+ case args.length
20
+ when 1
21
+ lparen = symbol('(')
22
+ e = to_ast(args[0])
23
+ rparen = symbol(')')
24
+ when 3
25
+ lparen = args[0]
26
+ e = to_ast(args[1])
27
+ rparen = args[2]
28
+ else
29
+ raise "Incorrect argument count #{args.length}"
30
+ end
31
+ ACTUAL_AST.paren(lparen, e, rparen)
32
+ end
33
+
34
+ def group(*args)
35
+ case args.length
36
+ when 1
37
+ lparen = symbol('(')
38
+ e = to_ast(args[0])
39
+ rparen = symbol(')')
40
+ when 3
41
+ lparen = args[0]
42
+ e = to_ast(args[1])
43
+ rparen = args[2]
44
+ else
45
+ raise "Incorrect argument count #{args.length}"
46
+ end
47
+ ACTUAL_AST.group(lparen, e, rparen)
48
+ end
49
+
50
+ def subsup(e, sub, sup)
51
+ ACTUAL_AST.subsup(to_ast(e), to_ast(sub), to_ast(sup))
52
+ end
53
+
54
+ def sub(e, sub)
55
+ ACTUAL_AST.sub(to_ast(e), to_ast(sub))
56
+ end
57
+
58
+ def sup(e, sup)
59
+ ACTUAL_AST.sup(to_ast(e), to_ast(sup))
60
+ end
61
+
62
+ def unary(operator, e)
63
+ ACTUAL_AST.unary(to_ast(operator), to_ast(e))
64
+ end
65
+
66
+ def binary(operator, e1, e2)
67
+ ACTUAL_AST.binary(to_ast(operator), to_ast(e1), to_ast(e2))
68
+ end
69
+
70
+ def infix(e1, operator, e2)
71
+ ACTUAL_AST.infix(to_ast(e1), to_ast(operator), to_ast(e2))
72
+ end
73
+
74
+ def text(value)
75
+ ACTUAL_AST.text(value)
76
+ end
77
+
78
+ def identifier(value)
79
+ ACTUAL_AST.identifier(value)
80
+ end
81
+
82
+ def number(value)
83
+ ACTUAL_AST.number(value)
84
+ end
85
+
86
+ def color(r, g, b, value)
87
+ ACTUAL_AST.color(r, g, b, value)
88
+ end
89
+
90
+ def symbol(text)
91
+ symbol = ::AsciiMath::Parser::DEFAULT_PARSER_SYMBOL_TABLE[text]
92
+ if symbol
93
+ ACTUAL_AST.symbol(symbol[:value], text)
94
+ else
95
+ nil
96
+ end
97
+ end
98
+
99
+ def matrix(*args)
100
+ case args.length
101
+ when 1
102
+ lparen = symbol('(')
103
+ rows = args[0]
104
+ rparen = symbol(')')
105
+ when 3
106
+ lparen = args[0]
107
+ rows = args[1]
108
+ rparen = args[2]
109
+ else
110
+ raise "Incorrect argument count #{args.length}"
111
+ end
112
+
113
+ rows = rows.map do |row|
114
+ row.map do |col|
115
+ to_ast(col)
116
+ end
117
+ end
118
+
119
+ ACTUAL_AST.matrix(lparen, rows, rparen)
120
+ end
121
+
122
+ def to_ast(e)
123
+ case e
124
+ when String
125
+ s = symbol(e)
126
+ if s
127
+ s
128
+ elsif e =~ /[0-9]+(.[0-9]+)?/
129
+ number(e)
130
+ elsif e.length > 1
131
+ text(e)
132
+ else
133
+ identifier(e)
134
+ end
135
+ when Symbol
136
+ raise "Not supported"
137
+ when Array
138
+ seq(*e)
139
+ else
140
+ e
141
+ end
142
+ end
143
+ end
144
+ end
@@ -1,179 +1,606 @@
1
1
  #encoding: utf-8
2
2
  require 'rspec'
3
3
  require 'asciimath'
4
+ require 'ast'
5
+ require 'nokogiri'
4
6
 
5
- TEST_CASES = {
6
- 'x+b/(2a)<+-sqrt((b^2)/(4a^2)-c/a)' =>
7
- {
8
- :mathml => '<math><mi>x</mi><mo>+</mo><mfrac><mi>b</mi><mrow><mn>2</mn><mi>a</mi></mrow></mfrac><mo>&lt;</mo><mo>&#xB1;</mo><msqrt><mrow><mfrac><msup><mi>b</mi><mn>2</mn></msup><mrow><mn>4</mn><msup><mi>a</mi><mn>2</mn></msup></mrow></mfrac><mo>&#x2212;</mo><mfrac><mi>c</mi><mi>a</mi></mfrac></mrow></msqrt></math>',
9
- :html => nil,
10
- },
11
- 'a^2 + b^2 = c^2' =>
12
- {
13
- :mathml => '<math><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup><mo>=</mo><msup><mi>c</mi><mn>2</mn></msup></math>',
14
- :html => '<span class="math-inline"><span class="math-row"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">2</span></span><span class="math-smaller">&#x200D;</span></span><span class="math-operator">+</span><span class="math-identifier">b</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">2</span></span><span class="math-smaller">&#x200D;</span></span><span class="math-operator">=</span><span class="math-identifier">c</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">2</span></span><span class="math-smaller">&#x200D;</span></span></span></span>',
15
- },
16
- 'x = (-b+-sqrt(b^2-4ac))/(2a)' =>
17
- {
18
- :mathml => '<math><mi>x</mi><mo>=</mo><mfrac><mrow><mo>&#x2212;</mo><mi>b</mi><mo>&#xB1;</mo><msqrt><mrow><msup><mi>b</mi><mn>2</mn></msup><mn>-4</mn><mi>a</mi><mi>c</mi></mrow></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></math>',
19
- :html => nil
20
- },
21
- 'm = (y_2 - y_1)/(x_2 - x_1) = (Deltay)/(Deltax)' =>
22
- {
23
- :mathml => '<math><mi>m</mi><mo>=</mo><mfrac><mrow><msub><mi>y</mi><mn>2</mn></msub><mo>&#x2212;</mo><msub><mi>y</mi><mn>1</mn></msub></mrow><mrow><msub><mi>x</mi><mn>2</mn></msub><mo>&#x2212;</mo><msub><mi>x</mi><mn>1</mn></msub></mrow></mfrac><mo>=</mo><mfrac><mrow><mo>&#x394;</mo><mi>y</mi></mrow><mrow><mo>&#x394;</mo><mi>x</mi></mrow></mfrac></math>',
24
- :html => '<span class="math-inline"><span class="math-row"><span class="math-identifier">m</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">y</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-number">2</span></span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">y</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-number">1</span></span></span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-number">2</span></span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-number">1</span></span></span></span></span></span></span></span></span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-operator">&#x394;</span><span class="math-identifier">y</span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-operator">&#x394;</span><span class="math-identifier">x</span></span></span></span></span></span></span></span></span>'
25
- },
26
- 'f\'(x) = lim_(Deltax->0)(f(x+Deltax)-f(x))/(Deltax)' =>
27
- {
28
- :mathml => '<math><mi>f</mi><mi>\'</mi><mfenced open="(" close=")"><mi>x</mi></mfenced><mo>=</mo><munder><mo>lim</mo><mrow><mo>&#x394;</mo><mi>x</mi><mo>&#x2192;</mo><mn>0</mn></mrow></munder><mfrac><mrow><mi>f</mi><mfenced open="(" close=")"><mrow><mi>x</mi><mo>+</mo><mo>&#x394;</mo><mi>x</mi></mrow></mfenced><mo>&#x2212;</mo><mi>f</mi><mfenced open="(" close=")"><mi>x</mi></mfenced></mrow><mrow><mo>&#x394;</mo><mi>x</mi></mrow></mfrac></math>',
29
- :html => '<span class="math-inline"><span class="math-row"><span class="math-identifier">f</span><span class="math-identifier">\'</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span></span><span class="math-brace">)</span></span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-blank">&#x200D;</span></span><span class="math-operator">lim</span><span class="math-smaller"><span class="math-row"><span class="math-operator">&#x394;</span><span class="math-identifier">x</span><span class="math-operator">&#x2192;</span><span class="math-number">0</span></span></span></span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span><span class="math-operator">+</span><span class="math-operator">&#x394;</span><span class="math-identifier">x</span></span><span class="math-brace">)</span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span></span><span class="math-brace">)</span></span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-operator">&#x394;</span><span class="math-identifier">x</span></span></span></span></span></span></span></span></span>'
30
- },
31
- 'd/dx [x^n] = nx^(n - 1)' =>
32
- {
33
- :mathml => '<math><mfrac><mi>d</mi><mi>dx</mi></mfrac><mfenced open="[" close="]"><msup><mi>x</mi><mi>n</mi></msup></mfenced><mo>=</mo><mi>n</mi><msup><mi>x</mi><mrow><mi>n</mi><mo>&#x2212;</mo><mn>1</mn></mrow></msup></math>',
34
- :html => '<span class="math-inline"><span class="math-row"><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">d</span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">dx</span></span></span></span></span></span><span class="math-row"><span class="math-brace">[</span><span class="math-row"><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">n</span></span><span class="math-smaller">&#x200D;</span></span></span><span class="math-brace">]</span></span><span class="math-operator">=</span><span class="math-identifier">n</span><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller"><span class="math-row"><span class="math-identifier">n</span><span class="math-operator">&#x2212;</span><span class="math-number">1</span></span></span><span class="math-smaller">&#x200D;</span></span></span></span>'
35
- },
36
- 'int_a^b f(x) dx = [F(x)]_a^b = F(b) - F(a)' =>
37
- {
38
- :mathml => '<math><msubsup><mo>&#x222B;</mo><mi>a</mi><mi>b</mi></msubsup><mi>f</mi><mfenced open="(" close=")"><mi>x</mi></mfenced><mi>dx</mi><mo>=</mo><msubsup><mfenced open="[" close="]"><mrow><mi>F</mi><mfenced open="(" close=")"><mi>x</mi></mfenced></mrow></mfenced><mi>a</mi><mi>b</mi></msubsup><mo>=</mo><mi>F</mi><mfenced open="(" close=")"><mi>b</mi></mfenced><mo>&#x2212;</mo><mi>F</mi><mfenced open="(" close=")"><mi>a</mi></mfenced></math>',
39
- :html => '<span class="math-inline"><span class="math-row"><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span></span><span class="math-brace">)</span></span><span class="math-identifier">dx</span><span class="math-operator">=</span><span class="math-row"><span class="math-brace">[</span><span class="math-row"><span class="math-identifier">F</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span></span><span class="math-brace">)</span></span></span><span class="math-brace">]</span></span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-operator">=</span><span class="math-identifier">F</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">b</span></span><span class="math-brace">)</span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">F</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">a</span></span><span class="math-brace">)</span></span></span></span>'
40
- },
41
- 'int_a^b f(x) dx = f(c)(b - a)' =>
42
- {
43
- :mathml => '<math><msubsup><mo>&#x222B;</mo><mi>a</mi><mi>b</mi></msubsup><mi>f</mi><mfenced open="(" close=")"><mi>x</mi></mfenced><mi>dx</mi><mo>=</mo><mi>f</mi><mfenced open="(" close=")"><mi>c</mi></mfenced><mfenced open="(" close=")"><mrow><mi>b</mi><mo>&#x2212;</mo><mi>a</mi></mrow></mfenced></math>',
44
- :html => '<span class="math-inline"><span class="math-row"><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span></span><span class="math-brace">)</span></span><span class="math-identifier">dx</span><span class="math-operator">=</span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">c</span></span><span class="math-brace">)</span></span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">b</span><span class="math-operator">&#x2212;</span><span class="math-identifier">a</span></span><span class="math-brace">)</span></span></span></span>'
45
- },
46
- 'ax^2 + bx + c = 0' =>
47
- {
48
- :mathml => '<math><mi>a</mi><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mi>b</mi><mi>x</mi><mo>+</mo><mi>c</mi><mo>=</mo><mn>0</mn></math>',
49
- :html => '<span class="math-inline"><span class="math-row"><span class="math-identifier">a</span><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">2</span></span><span class="math-smaller">&#x200D;</span></span><span class="math-operator">+</span><span class="math-identifier">b</span><span class="math-identifier">x</span><span class="math-operator">+</span><span class="math-identifier">c</span><span class="math-operator">=</span><span class="math-number">0</span></span></span>'
50
- },
51
- '"average value"=1/(b-a) int_a^b f(x) dx' =>
52
- {
53
- :mathml => '<math><mtext>average value</mtext><mo>=</mo><mfrac><mn>1</mn><mrow><mi>b</mi><mo>&#x2212;</mo><mi>a</mi></mrow></mfrac><msubsup><mo>&#x222B;</mo><mi>a</mi><mi>b</mi></msubsup><mi>f</mi><mfenced open="(" close=")"><mi>x</mi></mfenced><mi>dx</mi></math>',
54
- :html => '<span class="math-inline"><span class="math-row"><span class="math-text">average value</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-number">1</span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">b</span><span class="math-operator">&#x2212;</span><span class="math-identifier">a</span></span></span></span></span></span></span><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span></span><span class="math-brace">)</span></span><span class="math-identifier">dx</span></span></span>'
55
- },
56
- 'd/dx[int_a^x f(t) dt] = f(x)' =>
57
- {
58
- :mathml => '<math><mfrac><mi>d</mi><mi>dx</mi></mfrac><mfenced open="[" close="]"><mrow><msubsup><mo>&#x222B;</mo><mi>a</mi><mi>x</mi></msubsup><mi>f</mi><mfenced open="(" close=")"><mi>t</mi></mfenced><mi>dt</mi></mrow></mfenced><mo>=</mo><mi>f</mi><mfenced open="(" close=")"><mi>x</mi></mfenced></math>',
59
- :html => '<span class="math-inline"><span class="math-row"><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">d</span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">dx</span></span></span></span></span></span><span class="math-row"><span class="math-brace">[</span><span class="math-row"><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">x</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">t</span></span><span class="math-brace">)</span></span><span class="math-identifier">dt</span></span><span class="math-brace">]</span></span><span class="math-operator">=</span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span></span><span class="math-brace">)</span></span></span></span>'
60
- },
61
- 'hat(ab) bar(xy) ul(A) vec(v)' =>
62
- {
63
- :mathml => '<math><mover><mrow><mi>a</mi><mi>b</mi></mrow><mo>^</mo></mover><mover><mrow><mi>x</mi><mi>y</mi></mrow><mo>&#xAF;</mo></mover><munder><mi>A</mi><mo>_</mo></munder><mover><mi>v</mi><mo>&#x2192;</mo></mover></math>',
64
- :html => '<span class="math-inline"><span class="math-row"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-operator">^</span></span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">a</span><span class="math-identifier">b</span></span><span class="math-brace">)</span></span><span class="math-smaller"><span class="math-blank">&#x200D;</span></span></span><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-operator">&#xAF;</span></span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span><span class="math-identifier">y</span></span><span class="math-brace">)</span></span><span class="math-smaller"><span class="math-blank">&#x200D;</span></span></span><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-blank">&#x200D;</span></span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">A</span></span><span class="math-brace">)</span></span><span class="math-smaller"><span class="math-operator">_</span></span></span><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-operator">&#x2192;</span></span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">v</span></span><span class="math-brace">)</span></span><span class="math-smaller"><span class="math-blank">&#x200D;</span></span></span></span></span>'
65
- },
66
- 'z_12^34' =>
67
- {
68
- :mathml => '<math><msubsup><mi>z</mi><mn>12</mn><mn>34</mn></msubsup></math>',
69
- :html => '<span class="math-inline"><span class="math-row"><span class="math-identifier">z</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">34</span></span><span class="math-smaller"><span class="math-number">12</span></span></span></span></span>'
70
- },
71
- 'lim_(x->c)(f(x)-f(c))/(x-c)' =>
72
- {
73
- :mathml => '<math><munder><mo>lim</mo><mrow><mi>x</mi><mo>&#x2192;</mo><mi>c</mi></mrow></munder><mfrac><mrow><mi>f</mi><mfenced open="(" close=")"><mi>x</mi></mfenced><mo>&#x2212;</mo><mi>f</mi><mfenced open="(" close=")"><mi>c</mi></mfenced></mrow><mrow><mi>x</mi><mo>&#x2212;</mo><mi>c</mi></mrow></mfrac></math>',
74
- :html => '<span class="math-inline"><span class="math-row"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-blank">&#x200D;</span></span><span class="math-operator">lim</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">x</span><span class="math-operator">&#x2192;</span><span class="math-identifier">c</span></span></span></span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span></span><span class="math-brace">)</span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">c</span></span><span class="math-brace">)</span></span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">x</span><span class="math-operator">&#x2212;</span><span class="math-identifier">c</span></span></span></span></span></span></span></span></span>'
75
- },
76
- 'int_0^(pi/2) g(x) dx' =>
77
- {
78
- :mathml => '<math><msubsup><mo>&#x222B;</mo><mn>0</mn><mfrac><mi>&#x3C0;</mi><mn>2</mn></mfrac></msubsup><mi>g</mi><mfenced open="(" close=")"><mi>x</mi></mfenced><mi>dx</mi></math>',
79
- :html => '<span class="math-inline"><span class="math-row"><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-row"><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">&#x3C0;</span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-number">2</span></span></span></span></span></span></span></span><span class="math-smaller"><span class="math-number">0</span></span></span><span class="math-identifier">g</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">x</span></span><span class="math-brace">)</span></span><span class="math-identifier">dx</span></span></span>'
80
- },
81
- 'sum_(n=0)^oo a_n' =>
82
- {
83
- :mathml => '<math><munderover><mo>&#x2211;</mo><mrow><mi>n</mi><mo>=</mo><mn>0</mn></mrow><mo>&#x221E;</mo></munderover><msub><mi>a</mi><mi>n</mi></msub></math>',
84
- :html => '<span class="math-inline"><span class="math-row"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-operator">&#x221E;</span></span><span class="math-operator">&#x2211;</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">n</span><span class="math-operator">=</span><span class="math-number">0</span></span></span></span><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-identifier">n</span></span></span></span></span>'
85
- },
86
- '((1,2,3),(4,5,6),(7,8,9))' =>
87
- {
88
- :mathml => '<math><mfenced open="(" close=")"><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>2</mn></mtd><mtd><mn>3</mn></mtd></mtr><mtr><mtd><mn>4</mn></mtd><mtd><mn>5</mn></mtd><mtd><mn>6</mn></mtd></mtr><mtr><mtd><mn>7</mn></mtd><mtd><mn>8</mn></mtd><mtd><mn>9</mn></mtd></mtr></mtable></mfenced></math>',
89
- :html => '<span class="math-inline"><span class="math-row"><span class="math-row"><span class="math-brace" style="font-size: 300%;">(</span><span class="math-matrix" style="grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);"><span class="math-row"><span class="math-number">1</span></span><span class="math-row"><span class="math-number">2</span></span><span class="math-row"><span class="math-number">3</span></span><span class="math-row"><span class="math-number">4</span></span><span class="math-row"><span class="math-number">5</span></span><span class="math-row"><span class="math-number">6</span></span><span class="math-row"><span class="math-number">7</span></span><span class="math-row"><span class="math-number">8</span></span><span class="math-row"><span class="math-number">9</span></span></span><span class="math-brace" style="font-size: 300%;">)</span></span></span></span>'
90
- },
91
- '|(a,b),(c,d)|=ad-bc' =>
92
- {
93
- :mathml => '<math><mfenced open="|" close="|"><mtable><mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd></mtr><mtr><mtd><mi>c</mi></mtd><mtd><mi>d</mi></mtd></mtr></mtable></mfenced><mo>=</mo><mi>a</mi><mi>d</mi><mo>&#x2212;</mo><mi>b</mi><mi>c</mi></math>',
94
- :html => '<span class="math-inline"><span class="math-row"><span class="math-row"><span class="math-brace" style="font-size: 200%;">|</span><span class="math-matrix" style="grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(2,1fr);"><span class="math-row"><span class="math-identifier">a</span></span><span class="math-row"><span class="math-identifier">b</span></span><span class="math-row"><span class="math-identifier">c</span></span><span class="math-row"><span class="math-identifier">d</span></span></span><span class="math-brace" style="font-size: 200%;">|</span></span><span class="math-operator">=</span><span class="math-identifier">a</span><span class="math-identifier">d</span><span class="math-operator">&#x2212;</span><span class="math-identifier">b</span><span class="math-identifier">c</span></span></span>'
95
- },
96
- '((a_(11), cdots , a_(1n)),(vdots, ddots, vdots),(a_(m1), cdots , a_(mn)))' =>
97
- {
98
- :mathml => '<math><mfenced open="(" close=")"><mtable><mtr><mtd><msub><mi>a</mi><mn>11</mn></msub></mtd><mtd><mo>&#x22EF;</mo></mtd><mtd><msub><mi>a</mi><mrow><mn>1</mn><mi>n</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>&#x22EE;</mo></mtd><mtd><mo>&#x22F1;</mo></mtd><mtd><mo>&#x22EE;</mo></mtd></mtr><mtr><mtd><msub><mi>a</mi><mrow><mi>m</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>&#x22EF;</mo></mtd><mtd><msub><mi>a</mi><mrow><mi>m</mi><mi>n</mi></mrow></msub></mtd></mtr></mtable></mfenced></math>',
99
- :html => '<span class="math-inline"><span class="math-row"><span class="math-row"><span class="math-brace" style="font-size: 300%;">(</span><span class="math-matrix" style="grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);"><span class="math-row"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-row"><span class="math-number">11</span></span></span></span></span><span class="math-row"><span class="math-operator">&#x22EF;</span></span><span class="math-row"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-row"><span class="math-number">1</span><span class="math-identifier">n</span></span></span></span></span><span class="math-row"><span class="math-operator">&#x22EE;</span></span><span class="math-row"><span class="math-operator">&#x22F1;</span></span><span class="math-row"><span class="math-operator">&#x22EE;</span></span><span class="math-row"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">m</span><span class="math-number">1</span></span></span></span></span><span class="math-row"><span class="math-operator">&#x22EF;</span></span><span class="math-row"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">m</span><span class="math-identifier">n</span></span></span></span></span></span><span class="math-brace" style="font-size: 300%;">)</span></span></span></span>'
100
- },
101
- 'sum_(k=1)^n k = 1+2+ cdots +n=(n(n+1))/2' =>
102
- {
103
- :mathml => '<math><munderover><mo>&#x2211;</mo><mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow><mi>n</mi></munderover><mi>k</mi><mo>=</mo><mn>1</mn><mo>+</mo><mn>2</mn><mo>+</mo><mo>&#x22EF;</mo><mo>+</mo><mi>n</mi><mo>=</mo><mfrac><mrow><mi>n</mi><mfenced open="(" close=")"><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></mfenced></mrow><mn>2</mn></mfrac></math>',
104
- :html => '<span class="math-inline"><span class="math-row"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-identifier">n</span></span><span class="math-operator">&#x2211;</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">k</span><span class="math-operator">=</span><span class="math-number">1</span></span></span></span><span class="math-identifier">k</span><span class="math-operator">=</span><span class="math-number">1</span><span class="math-operator">+</span><span class="math-number">2</span><span class="math-operator">+</span><span class="math-operator">&#x22EF;</span><span class="math-operator">+</span><span class="math-identifier">n</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">n</span><span class="math-row"><span class="math-brace">(</span><span class="math-row"><span class="math-identifier">n</span><span class="math-operator">+</span><span class="math-number">1</span></span><span class="math-brace">)</span></span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-number">2</span></span></span></span></span></span></span></span>'
105
- },
106
- '"Скорость"=("Расстояние")/("Время")' =>
107
- {
108
- :mathml => '<math><mtext>&#x421;&#x43A;&#x43E;&#x440;&#x43E;&#x441;&#x442;&#x44C;</mtext><mo>=</mo><mfrac><mtext>&#x420;&#x430;&#x441;&#x441;&#x442;&#x43E;&#x44F;&#x43D;&#x438;&#x435;</mtext><mtext>&#x412;&#x440;&#x435;&#x43C;&#x44F;</mtext></mfrac></math>',
109
- :html => '<span class="math-inline"><span class="math-row"><span class="math-text">&#x421;&#x43A;&#x43E;&#x440;&#x43E;&#x441;&#x442;&#x44C;</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-text">&#x420;&#x430;&#x441;&#x441;&#x442;&#x43E;&#x44F;&#x43D;&#x438;&#x435;</span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-text">&#x412;&#x440;&#x435;&#x43C;&#x44F;</span></span></span></span></span></span></span></span></span>'
110
- },
111
- 'bb (a + b) + cc c = fr (d^n)' =>
112
- {
113
- :mathml => '<math><mstyle mathvariant="bold"><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></mstyle><mo>+</mo><mstyle mathvariant="script"><mi>c</mi></mstyle><mo>=</mo><mstyle mathvariant="fraktur"><msup><mi>d</mi><mi>n</mi></msup></mstyle></math>',
114
- :html => nil
115
- },
116
- 'max()' =>
117
- {
118
- :mathml => '<math><mi>max</mi><mfenced open="(" close=")"></mfenced></math>',
119
- :html => '<span class="math-inline"><span class="math-row"><span class="math-identifier">max</span><span class="math-row"><span class="math-brace">(</span><span class="math-brace">)</span></span></span></span>'
120
- },
121
- 'text("foo")' => {
122
- :mathml => '<math><mtext>"foo"</mtext></math>',
123
- :html => '<span class="math-inline"><span class="math-row"><span class="math-text">"foo"</span></span></span>'
124
- },
125
- 'ubrace(1 + 2) obrace(3 + 4' => {
126
- :mathml => '<math><munder><mrow><mn>1</mn><mo>+</mo><mn>2</mn></mrow><mo>&#x23DF;</mo></munder><mover><mrow><mn>3</mn><mo>+</mo><mn>4</mn></mrow><mo>&#x23DE;</mo></mover></math>'
127
- },
128
- "s'_i = {(- 1, if s_i > s_(i + 1)),( + 1, if s_i <= s_(i + 1)):}" => {
129
- :mathml => '<math><mi>s</mi><msub><mi>\'</mi><mi>i</mi></msub><mo>=</mo><mfenced open="{" close=""><mtable><mtr><mtd><mrow><mo>&#x2212;</mo><mn>1</mn></mrow></mtd><mtd><mrow><mo>if</mo><msub><mi>s</mi><mi>i</mi></msub><mo>&gt;</mo><msub><mi>s</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow></mtd></mtr><mtr><mtd><mrow><mo>+</mo><mn>1</mn></mrow></mtd><mtd><mrow><mo>if</mo><msub><mi>s</mi><mi>i</mi></msub><mo>&#x2264;</mo><msub><mi>s</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow></mtd></mtr></mtable></mfenced></math>'
130
- },
131
- "s'_i = {(, if s_i > s_(i + 1)),( + 1,):}" => {
132
- :mathml => '<math><mi>s</mi><msub><mi>\'</mi><mi>i</mi></msub><mo>=</mo><mfenced open="{" close=""><mtable><mtr><mtd></mtd><mtd><mrow><mo>if</mo><msub><mi>s</mi><mi>i</mi></msub><mo>&gt;</mo><msub><mi>s</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow></mtd></mtr><mtr><mtd><mrow><mo>+</mo><mn>1</mn></mrow></mtd><mtd></mtd></mtr></mtable></mfenced></math>'
133
- },
134
- '{:(a,b),(c,d):}' => {
135
- :mathml => '<math><mtable><mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd></mtr><mtr><mtd><mi>c</mi></mtd><mtd><mi>d</mi></mtd></mtr></mtable></math>'
136
- },
137
- }
138
-
139
- version = RUBY_VERSION.split('.').map { |s| s.to_i }
140
-
141
- if version[0] > 1 || version[1] > 8
142
- TEST_CASES['Скорость=(Расстояние)/(Время)'] =
143
- {
144
- :mathml => '<math><mi>&#x421;</mi><mi>&#x43A;</mi><mi>&#x43E;</mi><mi>&#x440;</mi><mi>&#x43E;</mi><mi>&#x441;</mi><mi>&#x442;</mi><mi>&#x44C;</mi><mo>=</mo><mfrac><mrow><mi>&#x420;</mi><mi>&#x430;</mi><mi>&#x441;</mi><mi>&#x441;</mi><mi>&#x442;</mi><mi>&#x43E;</mi><mi>&#x44F;</mi><mi>&#x43D;</mi><mi>&#x438;</mi><mi>&#x435;</mi></mrow><mrow><mi>&#x412;</mi><mi>&#x440;</mi><mi>&#x435;</mi><mi>&#x43C;</mi><mi>&#x44F;</mi></mrow></mfrac></math>',
145
- :html => '<span class="math-inline"><span class="math-row"><span class="math-identifier">&#x421;</span><span class="math-identifier">&#x43A;</span><span class="math-identifier">&#x43E;</span><span class="math-identifier">&#x440;</span><span class="math-identifier">&#x43E;</span><span class="math-identifier">&#x441;</span><span class="math-identifier">&#x442;</span><span class="math-identifier">&#x44C;</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">&#x420;</span><span class="math-identifier">&#x430;</span><span class="math-identifier">&#x441;</span><span class="math-identifier">&#x441;</span><span class="math-identifier">&#x442;</span><span class="math-identifier">&#x43E;</span><span class="math-identifier">&#x44F;</span><span class="math-identifier">&#x43D;</span><span class="math-identifier">&#x438;</span><span class="math-identifier">&#x435;</span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">&#x412;</span><span class="math-identifier">&#x440;</span><span class="math-identifier">&#x435;</span><span class="math-identifier">&#x43C;</span><span class="math-identifier">&#x44F;</span></span></span></span></span></span></span></span></span>'
146
- }
147
- end
148
7
 
149
- module AsciiMathHelper
150
- def expect_mathml(asciimath, mathml)
151
- expect(AsciiMath.parse(asciimath).to_mathml).to eq(mathml)
152
- end
153
-
154
- def expect_html(asciimath, html)
155
- expect(AsciiMath.parse(asciimath).to_html).to eq(html)
8
+ module Xml
9
+ def self.mathml2_xsd
10
+ @schema ||= File.open(File.expand_path('../schema/mathml2/mathml2.xsd', __FILE__)) { |io| Nokogiri::XML::Schema(io) }
156
11
  end
157
- end
158
12
 
159
- RSpec.configure do |c|
160
- c.include AsciiMathHelper
161
- end
13
+ def self.mathml3_xsd
14
+ @schema ||= File.open(File.expand_path('../schema/mathml3/mathml3.xsd', __FILE__)) { |io| Nokogiri::XML::Schema(io) }
15
+ end
162
16
 
163
- describe "AsciiMath::MathMLBuilder" do
164
- TEST_CASES.each_pair do |asciimath, output|
165
- it "'#{asciimath}' to MathML" do
166
- expect_mathml(asciimath, output[:mathml])
167
- end
17
+ def self.parse(content)
18
+ Nokogiri::XML(content)
168
19
  end
169
20
  end
170
21
 
171
- describe "AsciiMath::HTMLBuilder" do
172
- TEST_CASES.each_pair do |asciimath, output|
173
- if output[:html]
174
- it "'#{asciimath}' to HTML" do
175
- expect_html(asciimath, output[:html])
22
+ def should_generate(expected_output)
23
+ Proc.new { |example|
24
+ parsed = AsciiMath.parse(example.description)
25
+ variant = example.metadata[:variant]
26
+ if variant
27
+ if expected_output.key?(variant)
28
+ expected = expected_output[variant]
29
+ case variant
30
+ when :ast
31
+ expect(parsed.ast).to eq(expected)
32
+ when :mathml
33
+ expect(parsed.to_mathml).to eq(expected)
34
+ xml_dom = Xml.parse(parsed.to_mathml(:xmlns => 'http://www.w3.org/1998/Math/MathML'))
35
+ Xml.mathml2_xsd.validate(xml_dom).each do |error|
36
+ fail(error.message)
37
+ end
38
+ Xml.mathml3_xsd.validate(xml_dom).each do |error|
39
+ fail(error.message)
40
+ end
41
+ when :mathml_word
42
+ expect(::AsciiMath::MathMLBuilder.new(:msword => true).append_expression(parsed.ast).to_s).to eq(expected)
43
+ when :html
44
+ expect(parsed.to_html).to eq(expected)
45
+ when :latex
46
+ expect(parsed.to_latex).to eq(expected)
47
+ else
48
+ skip("Unsupported output variant '#{variant}'")
49
+ end
50
+ else
51
+ skip("No example output provided for '#{variant}'")
176
52
  end
53
+ else
54
+ skip('No known output variant found')
177
55
  end
56
+ }
57
+ end
58
+
59
+ RSpec.shared_examples 'AsciiMath Examples' do
60
+ class << self
61
+ include ::AsciiMath::ASTHelper
62
+ end
63
+
64
+ example('underset(_)(hat A) = hat A exp j vartheta_0', &should_generate(
65
+ :ast => seq(
66
+ binary(
67
+ symbol('underset'),
68
+ group(symbol('_')),
69
+ group(unary(symbol('hat'), 'A'))
70
+ ),
71
+ symbol('='),
72
+ unary(symbol('hat'), 'A'),
73
+ symbol('exp'),
74
+ 'j',
75
+ sub(symbol('vartheta'), '0')
76
+ ),
77
+ :mathml => '<math><munder><mover><mi>A</mi><mo>^</mo></mover><mo>_</mo></munder><mo>=</mo><mover><mi>A</mi><mo>^</mo></mover><mi>exp</mi><mi>j</mi><msub><mi>&#x3D1;</mi><mn>0</mn></msub></math>',
78
+ :mathml_word => '<math><munder><mrow><mover><mrow><mi>A</mi></mrow><mrow><mo>^</mo></mrow></mover></mrow><mrow><mo>_</mo></mrow></munder><mo>=</mo><mover><mrow><mi>A</mi></mrow><mrow><mo>^</mo></mrow></mover><mi>exp</mi><mi>j</mi><msub><mrow><mi>&#x3D1;</mi></mrow><mrow><mn>0</mn></mrow></msub></math>',
79
+ :latex => '\\underset{\\text{–}}{\\hat{A}} = \\hat{A} \\exp j \\vartheta_0'
80
+ ))
81
+
82
+ example('x+b/(2a)<+-sqrt((b^2)/(4a^2)-c/a)', &should_generate(
83
+ :ast => seq(
84
+ 'x',
85
+ symbol('+'),
86
+ infix('b', symbol('/'), grseq('2', 'a')),
87
+ symbol('<'),
88
+ symbol('+-'),
89
+ unary(
90
+ symbol('sqrt'),
91
+ grseq(
92
+ infix(
93
+ group(sup('b', '2')),
94
+ symbol('/'),
95
+ grseq('4', sup('a', '2'))
96
+ ),
97
+ symbol('-'),
98
+ infix('c', symbol('/'), 'a')
99
+ )
100
+ )
101
+ ),
102
+ :mathml => '<math><mi>x</mi><mo>+</mo><mfrac><mi>b</mi><mrow><mn>2</mn><mi>a</mi></mrow></mfrac><mo>&lt;</mo><mo>&#xB1;</mo><msqrt><mrow><mfrac><msup><mi>b</mi><mn>2</mn></msup><mrow><mn>4</mn><msup><mi>a</mi><mn>2</mn></msup></mrow></mfrac><mo>&#x2212;</mo><mfrac><mi>c</mi><mi>a</mi></mfrac></mrow></msqrt></math>',
103
+ :latex => 'x + \\frac{b}{2 a} < \\pm \\sqrt{\\frac{b^2}{4 a^2} - \\frac{c}{a}}',
104
+ ))
105
+
106
+ example('a^2 + b^2 = c^2', &should_generate(
107
+ :ast => seq(
108
+ sup('a', '2'),
109
+ symbol('+'),
110
+ sup('b', '2'),
111
+ symbol('='),
112
+ sup('c', '2')
113
+ ),
114
+ :mathml => '<math><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup><mo>=</mo><msup><mi>c</mi><mn>2</mn></msup></math>',
115
+ :html => '<span class="math-inline"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">2</span></span><span class="math-smaller">&#x200D;</span></span><span class="math-operator">+</span><span class="math-identifier">b</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">2</span></span><span class="math-smaller">&#x200D;</span></span><span class="math-operator">=</span><span class="math-identifier">c</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">2</span></span><span class="math-smaller">&#x200D;</span></span></span>',
116
+ :latex => 'a^2 + b^2 = c^2',
117
+
118
+ ))
119
+
120
+ example('x = (-b+-sqrt(b^2-4ac))/(2a)', &should_generate(
121
+ :ast => seq(
122
+ 'x',
123
+ symbol('='),
124
+ infix(
125
+ grseq(
126
+ symbol('-'), 'b',
127
+ symbol('+-'),
128
+ unary(symbol('sqrt'), grseq(sup('b', '2'), symbol('-'), '4', 'a', 'c'))
129
+ ),
130
+ symbol('/'),
131
+ grseq('2', 'a'),
132
+ )
133
+ ),
134
+ :mathml => '<math><mi>x</mi><mo>=</mo><mfrac><mrow><mo>&#x2212;</mo><mi>b</mi><mo>&#xB1;</mo><msqrt><mrow><msup><mi>b</mi><mn>2</mn></msup><mo>&#x2212;</mo><mn>4</mn><mi>a</mi><mi>c</mi></mrow></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></math>',
135
+ :latex => 'x = \\frac{- b \\pm \\sqrt{b^2 - 4 a c}}{2 a}',
136
+ ))
137
+
138
+ example('m = (y_2 - y_1)/(x_2 - x_1) = (Deltay)/(Deltax)', &should_generate(
139
+ :ast => seq(
140
+ 'm',
141
+ symbol('='),
142
+ infix(grseq(sub('y', '2'), symbol('-'), sub('y', '1')), symbol('/'), grseq(sub('x', '2'), symbol('-'), sub('x', '1'))),
143
+ symbol('='),
144
+ infix(grseq(symbol('Delta'), 'y'), symbol('/'), grseq(symbol('Delta'), 'x')),
145
+ ),
146
+ :mathml => '<math><mi>m</mi><mo>=</mo><mfrac><mrow><msub><mi>y</mi><mn>2</mn></msub><mo>&#x2212;</mo><msub><mi>y</mi><mn>1</mn></msub></mrow><mrow><msub><mi>x</mi><mn>2</mn></msub><mo>&#x2212;</mo><msub><mi>x</mi><mn>1</mn></msub></mrow></mfrac><mo>=</mo><mfrac><mrow><mo>&#x394;</mo><mi>y</mi></mrow><mrow><mo>&#x394;</mo><mi>x</mi></mrow></mfrac></math>',
147
+ :html => '<span class="math-inline"><span class="math-identifier">m</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">y</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-number">2</span></span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">y</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-number">1</span></span></span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-number">2</span></span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-number">1</span></span></span></span></span></span></span></span></span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-operator">&#x394;</span><span class="math-identifier">y</span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-operator">&#x394;</span><span class="math-identifier">x</span></span></span></span></span></span></span></span>',
148
+ :latex => 'm = \\frac{y_2 - y_1}{x_2 - x_1} = \\frac{\\Delta y}{\\Delta x}',
149
+ ))
150
+
151
+ example('f\'(x) = lim_(Deltax->0)(f(x+Deltax)-f(x))/(Deltax)', &should_generate(
152
+ :ast => seq(
153
+ symbol('f'),
154
+ symbol('\''),
155
+ paren('x'),
156
+ symbol('='),
157
+ sub(
158
+ symbol('lim'),
159
+ grseq(symbol('Delta'), 'x', symbol('->'), '0')
160
+ ),
161
+ infix(
162
+ grseq(symbol('f'), paren(seq('x', symbol('+'), symbol('Delta'), 'x')), symbol('-'), symbol('f'), paren('x')),
163
+ symbol('/'),
164
+ grseq(symbol('Delta'), 'x')
165
+ )
166
+ ),
167
+ :mathml => '<math><mi>f</mi><mo>&#x2032;</mo><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mo>=</mo><munder><mo>lim</mo><mrow><mo>&#x394;</mo><mi>x</mi><mo>&#x2192;</mo><mn>0</mn></mrow></munder><mfrac><mrow><mi>f</mi><mrow><mo>(</mo><mrow><mi>x</mi><mo>+</mo><mo>&#x394;</mo><mi>x</mi></mrow><mo>)</mo></mrow><mo>&#x2212;</mo><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow></mrow><mrow><mo>&#x394;</mo><mi>x</mi></mrow></mfrac></math>',
168
+ :html => '<span class="math-inline"><span class="math-identifier">f</span><span class="math-operator">&#x2032;</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-brace">)</span></span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-blank">&#x200D;</span></span><span class="math-operator">lim</span><span class="math-smaller"><span class="math-row"><span class="math-operator">&#x394;</span><span class="math-identifier">x</span><span class="math-operator">&#x2192;</span><span class="math-number">0</span></span></span></span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-operator">+</span><span class="math-operator">&#x394;</span><span class="math-identifier">x</span><span class="math-brace">)</span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-brace">)</span></span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-operator">&#x394;</span><span class="math-identifier">x</span></span></span></span></span></span></span></span>',
169
+ :latex => 'f \' ( x ) = \\lim_{\\Delta x \\rightarrow 0} \\frac{f \\left ( x + \\Delta x \\right ) - f ( x )}{\\Delta x}',
170
+ ))
171
+
172
+ example('d/dx [x^n] = nx^(n - 1)', &should_generate(
173
+ :ast => seq(
174
+ infix('d', symbol('/'), symbol('dx')),
175
+ paren(symbol('['), sup('x', 'n'), symbol(']')),
176
+ symbol('='),
177
+ 'n',
178
+ sup('x', grseq('n', symbol('-'), '1'))
179
+ ),
180
+ :mathml => '<math><mfrac><mi>d</mi><mi>dx</mi></mfrac><mrow><mo>[</mo><msup><mi>x</mi><mi>n</mi></msup><mo>]</mo></mrow><mo>=</mo><mi>n</mi><msup><mi>x</mi><mrow><mi>n</mi><mo>&#x2212;</mo><mn>1</mn></mrow></msup></math>',
181
+ :html => '<span class="math-inline"><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">d</span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">dx</span></span></span></span></span></span><span class="math-row"><span class="math-brace">[</span><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">n</span></span><span class="math-smaller">&#x200D;</span></span><span class="math-brace">]</span></span><span class="math-operator">=</span><span class="math-identifier">n</span><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller"><span class="math-row"><span class="math-identifier">n</span><span class="math-operator">&#x2212;</span><span class="math-number">1</span></span></span><span class="math-smaller">&#x200D;</span></span></span>',
182
+ :latex => '\\frac{d}{dx} [ x^n ] = n x^{n - 1}',
183
+ ))
184
+
185
+ example('int_a^b f(x) dx = [F(x)]_a^b = F(b) - F(a)', &should_generate(
186
+ :ast => seq(
187
+ subsup(symbol('int'), 'a', 'b'),
188
+ symbol('f'),
189
+ paren('x'),
190
+ symbol('dx'),
191
+ symbol('='),
192
+ subsup(paren(symbol('['), seq('F', paren('x')), symbol(']')), 'a', 'b'),
193
+ symbol('='),
194
+ 'F', paren('b'),
195
+ symbol('-'),
196
+ 'F', paren('a')
197
+ ),
198
+ :mathml => '<math><msubsup><mo>&#x222B;</mo><mi>a</mi><mi>b</mi></msubsup><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mi>dx</mi><mo>=</mo><msubsup><mrow><mo>[</mo><mrow><mi>F</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow></mrow><mo>]</mo></mrow><mi>a</mi><mi>b</mi></msubsup><mo>=</mo><mi>F</mi><mrow><mo>(</mo><mi>b</mi><mo>)</mo></mrow><mo>&#x2212;</mo><mi>F</mi><mrow><mo>(</mo><mi>a</mi><mo>)</mo></mrow></math>',
199
+ :html => '<span class="math-inline"><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-brace">)</span></span><span class="math-identifier">dx</span><span class="math-operator">=</span><span class="math-row"><span class="math-brace">[</span><span class="math-identifier">F</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-brace">)</span></span><span class="math-brace">]</span></span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-operator">=</span><span class="math-identifier">F</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">b</span><span class="math-brace">)</span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">F</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">a</span><span class="math-brace">)</span></span></span>',
200
+ :latex => '\\int_a^b f ( x ) dx = {\\left [ F ( x ) \\right ]}_a^b = F ( b ) - F ( a )',
201
+ ))
202
+
203
+ example('int_a^b f(x) dx = f(c)(b - a)', &should_generate(
204
+ :ast => seq(
205
+ subsup(symbol('int'), 'a', 'b'),
206
+ symbol('f'),
207
+ paren('x'),
208
+ symbol('dx'),
209
+ symbol('='),
210
+ symbol('f'),
211
+ paren('c'),
212
+ paren(seq('b', symbol('-'), 'a')),
213
+ ),
214
+ :mathml => '<math><msubsup><mo>&#x222B;</mo><mi>a</mi><mi>b</mi></msubsup><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mi>dx</mi><mo>=</mo><mi>f</mi><mrow><mo>(</mo><mi>c</mi><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mi>b</mi><mo>&#x2212;</mo><mi>a</mi></mrow><mo>)</mo></mrow></math>',
215
+ :html => '<span class="math-inline"><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-brace">)</span></span><span class="math-identifier">dx</span><span class="math-operator">=</span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">c</span><span class="math-brace">)</span></span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">b</span><span class="math-operator">&#x2212;</span><span class="math-identifier">a</span><span class="math-brace">)</span></span></span>',
216
+ :latex => '\\int_a^b f ( x ) dx = f ( c ) ( b - a )',
217
+ ))
218
+
219
+ example('ax^2 + bx + c = 0', &should_generate(
220
+ :ast => seq(
221
+ 'a',
222
+ sup('x', '2'),
223
+ symbol('+'),
224
+ 'b',
225
+ 'x',
226
+ symbol('+'),
227
+ 'c',
228
+ symbol('='),
229
+ '0'
230
+ ),
231
+ :mathml => '<math><mi>a</mi><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mi>b</mi><mi>x</mi><mo>+</mo><mi>c</mi><mo>=</mo><mn>0</mn></math>',
232
+ :html => '<span class="math-inline"><span class="math-identifier">a</span><span class="math-identifier">x</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">2</span></span><span class="math-smaller">&#x200D;</span></span><span class="math-operator">+</span><span class="math-identifier">b</span><span class="math-identifier">x</span><span class="math-operator">+</span><span class="math-identifier">c</span><span class="math-operator">=</span><span class="math-number">0</span></span>',
233
+ :latex => 'a x^2 + b x + c = 0',
234
+ ))
235
+
236
+ example('"average value"=1/(b-a) int_a^b f(x) dx', &should_generate(
237
+ :ast => seq(
238
+ 'average value',
239
+ symbol('='),
240
+ infix('1', symbol('/'), grseq('b', symbol('-'), 'a')),
241
+ subsup(symbol('int'), 'a', 'b'),
242
+ symbol('f'),
243
+ paren('x'),
244
+ symbol('dx')
245
+ ),
246
+ :mathml => '<math><mtext>average value</mtext><mo>=</mo><mfrac><mn>1</mn><mrow><mi>b</mi><mo>&#x2212;</mo><mi>a</mi></mrow></mfrac><msubsup><mo>&#x222B;</mo><mi>a</mi><mi>b</mi></msubsup><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mi>dx</mi></math>',
247
+ :html => '<span class="math-inline"><span class="math-text">average value</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-number">1</span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">b</span><span class="math-operator">&#x2212;</span><span class="math-identifier">a</span></span></span></span></span></span></span><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-brace">)</span></span><span class="math-identifier">dx</span></span>',
248
+ :latex => '\\text{average value} = \\frac{1}{b - a} \\int_a^b f ( x ) dx',
249
+ ))
250
+
251
+ example('d/dx[int_a^x f(t) dt] = f(x)', &should_generate(
252
+ :ast => seq(
253
+ infix('d', symbol('/'), symbol('dx')),
254
+ paren(
255
+ symbol('['),
256
+ seq(subsup(symbol('int'), 'a', 'x'), symbol('f'), paren('t'), symbol('dt')),
257
+ symbol(']')
258
+ ),
259
+ symbol('='),
260
+ symbol('f'),
261
+ paren('x'),
262
+ ),
263
+ :mathml => '<math><mfrac><mi>d</mi><mi>dx</mi></mfrac><mrow><mo>[</mo><mrow><msubsup><mo>&#x222B;</mo><mi>a</mi><mi>x</mi></msubsup><mi>f</mi><mrow><mo>(</mo><mi>t</mi><mo>)</mo></mrow><mi>dt</mi></mrow><mo>]</mo></mrow><mo>=</mo><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow></math>',
264
+ :html => '<span class="math-inline"><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">d</span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">dx</span></span></span></span></span></span><span class="math-row"><span class="math-brace">[</span><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">x</span></span><span class="math-smaller"><span class="math-identifier">a</span></span></span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">t</span><span class="math-brace">)</span></span><span class="math-identifier">dt</span><span class="math-brace">]</span></span><span class="math-operator">=</span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-brace">)</span></span></span>',
265
+ :latex => '\\frac{d}{dx} \\left [ \\int_a^x f ( t ) dt \\right ] = f ( x )',
266
+ ))
267
+
268
+ example('hat(ab) bar(xy) ul(A) vec(v)', &should_generate(
269
+ :ast => seq(
270
+ unary(symbol('hat'), grseq('a', 'b')),
271
+ unary(symbol('bar'), grseq('x', 'y')),
272
+ unary(symbol('ul'), group('A')),
273
+ unary(symbol('vec'), group('v')),
274
+ ),
275
+ :mathml => '<math><mover><mrow><mi>a</mi><mi>b</mi></mrow><mo>^</mo></mover><mover><mrow><mi>x</mi><mi>y</mi></mrow><mo>&#xAF;</mo></mover><munder><mi>A</mi><mo>_</mo></munder><mover><mi>v</mi><mo>&#x2192;</mo></mover></math>',
276
+ :html => '<span class="math-inline"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-operator">^</span></span><span class="math-row"><span class="math-identifier">a</span><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-blank">&#x200D;</span></span></span><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-operator">&#xAF;</span></span><span class="math-row"><span class="math-identifier">x</span><span class="math-identifier">y</span></span><span class="math-smaller"><span class="math-blank">&#x200D;</span></span></span><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-blank">&#x200D;</span></span><span class="math-identifier">A</span><span class="math-smaller"><span class="math-operator">_</span></span></span><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-operator">&#x2192;</span></span><span class="math-identifier">v</span><span class="math-smaller"><span class="math-blank">&#x200D;</span></span></span></span>',
277
+ :latex => '\\hat{a b} \\overline{x y} \\underline{A} \\vec{v}',
278
+ ))
279
+
280
+ example('z_12^34', &should_generate(
281
+ :ast => subsup('z', '12', '34'),
282
+ :mathml => '<math><msubsup><mi>z</mi><mn>12</mn><mn>34</mn></msubsup></math>',
283
+ :html => '<span class="math-inline"><span class="math-identifier">z</span><span class="math-subsup"><span class="math-smaller"><span class="math-number">34</span></span><span class="math-smaller"><span class="math-number">12</span></span></span></span>',
284
+ :latex => 'z_{12}^{34}',
285
+ ))
286
+
287
+ example('lim_(x->c)(f(x)-f(c))/(x-c)', &should_generate(
288
+ :ast => seq(
289
+ sub(symbol('lim'), grseq('x', symbol('->'), 'c')),
290
+ infix(
291
+ grseq(symbol('f'), paren('x'), symbol('-'), symbol('f'), paren('c')),
292
+ symbol('/'),
293
+ grseq('x', symbol('-'), 'c')
294
+ )
295
+ ),
296
+ :mathml => '<math><munder><mo>lim</mo><mrow><mi>x</mi><mo>&#x2192;</mo><mi>c</mi></mrow></munder><mfrac><mrow><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mo>&#x2212;</mo><mi>f</mi><mrow><mo>(</mo><mi>c</mi><mo>)</mo></mrow></mrow><mrow><mi>x</mi><mo>&#x2212;</mo><mi>c</mi></mrow></mfrac></math>',
297
+ :html => '<span class="math-inline"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-blank">&#x200D;</span></span><span class="math-operator">lim</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">x</span><span class="math-operator">&#x2192;</span><span class="math-identifier">c</span></span></span></span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-brace">)</span></span><span class="math-operator">&#x2212;</span><span class="math-identifier">f</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">c</span><span class="math-brace">)</span></span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">x</span><span class="math-operator">&#x2212;</span><span class="math-identifier">c</span></span></span></span></span></span></span></span>',
298
+ :latex => '\\lim_{x \\rightarrow c} \\frac{f ( x ) - f ( c )}{x - c}',
299
+ ))
300
+
301
+ example('int_0^(pi/2) g(x) dx', &should_generate(
302
+ :ast => seq(
303
+ subsup(symbol('int'), '0', group(infix(symbol('pi'), symbol('/'), '2'))),
304
+ symbol('g'), paren('x'),
305
+ symbol('dx')
306
+ ),
307
+ :mathml => '<math><msubsup><mo>&#x222B;</mo><mn>0</mn><mfrac><mi>&#x3C0;</mi><mn>2</mn></mfrac></msubsup><mi>g</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mi>dx</mi></math>',
308
+ :html => '<span class="math-inline"><span class="math-operator">&#x222B;</span><span class="math-subsup"><span class="math-smaller"><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-identifier">&#x3C0;</span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-number">2</span></span></span></span></span></span></span><span class="math-smaller"><span class="math-number">0</span></span></span><span class="math-identifier">g</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">x</span><span class="math-brace">)</span></span><span class="math-identifier">dx</span></span>',
309
+ :latex => '\\int_0^{\\frac{\\pi}{2}} g ( x ) dx',
310
+ ))
311
+
312
+ example('sum_(n=0)^oo a_n', &should_generate(
313
+ :ast => seq(
314
+ subsup(symbol('sum'), grseq('n', symbol('='), '0'), symbol('oo'),),
315
+ sub('a', 'n')
316
+ ),
317
+ :mathml => '<math><munderover><mo>&#x2211;</mo><mrow><mi>n</mi><mo>=</mo><mn>0</mn></mrow><mo>&#x221E;</mo></munderover><msub><mi>a</mi><mi>n</mi></msub></math>',
318
+ :html => '<span class="math-inline"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-operator">&#x221E;</span></span><span class="math-operator">&#x2211;</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">n</span><span class="math-operator">=</span><span class="math-number">0</span></span></span></span><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-identifier">n</span></span></span></span>',
319
+ :latex => '\\sum_{n = 0}^\\infty a_n',
320
+ ))
321
+
322
+ example('((1,2,3),(4,5,6),(7,8,9))', &should_generate(
323
+ :ast => matrix([%w[1 2 3], %w[4 5 6], %w[7 8 9]]),
324
+ :mathml => '<math><mrow><mo>(</mo><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>2</mn></mtd><mtd><mn>3</mn></mtd></mtr><mtr><mtd><mn>4</mn></mtd><mtd><mn>5</mn></mtd><mtd><mn>6</mn></mtd></mtr><mtr><mtd><mn>7</mn></mtd><mtd><mn>8</mn></mtd><mtd><mn>9</mn></mtd></mtr></mtable><mo>)</mo></mrow></math>',
325
+ :html => '<span class="math-inline"><span class="math-row"><span class="math-brace" style="font-size: 300%;">(</span><span class="math-matrix" style="grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);"><span class="math-row"><span class="math-number">1</span></span><span class="math-row"><span class="math-number">2</span></span><span class="math-row"><span class="math-number">3</span></span><span class="math-row"><span class="math-number">4</span></span><span class="math-row"><span class="math-number">5</span></span><span class="math-row"><span class="math-number">6</span></span><span class="math-row"><span class="math-number">7</span></span><span class="math-row"><span class="math-number">8</span></span><span class="math-row"><span class="math-number">9</span></span></span><span class="math-brace" style="font-size: 300%;">)</span></span></span>',
326
+ :latex => '\\left ( \\begin{matrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\\\ 7 & 8 & 9 \\end{matrix} \\right )',
327
+ ))
328
+
329
+ example('|(a,b),(c,d)|=ad-bc', &should_generate(
330
+ :ast => seq(
331
+ matrix(symbol('|'), [%w(a b), %w(c d)], symbol('|'),),
332
+ symbol('='),
333
+ 'a', 'd',
334
+ symbol('-'),
335
+ 'b', 'c'
336
+ ),
337
+ :mathml => '<math><mrow><mo>|</mo><mtable><mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd></mtr><mtr><mtd><mi>c</mi></mtd><mtd><mi>d</mi></mtd></mtr></mtable><mo>|</mo></mrow><mo>=</mo><mi>a</mi><mi>d</mi><mo>&#x2212;</mo><mi>b</mi><mi>c</mi></math>',
338
+ :mathml_word => '<math><mfenced open="|" close="|"><mtable><mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd></mtr><mtr><mtd><mi>c</mi></mtd><mtd><mi>d</mi></mtd></mtr></mtable></mfenced><mo>=</mo><mi>a</mi><mi>d</mi><mo>&#x2212;</mo><mi>b</mi><mi>c</mi></math>',
339
+ :html => '<span class="math-inline"><span class="math-row"><span class="math-brace" style="font-size: 200%;">|</span><span class="math-matrix" style="grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(2,1fr);"><span class="math-row"><span class="math-identifier">a</span></span><span class="math-row"><span class="math-identifier">b</span></span><span class="math-row"><span class="math-identifier">c</span></span><span class="math-row"><span class="math-identifier">d</span></span></span><span class="math-brace" style="font-size: 200%;">|</span></span><span class="math-operator">=</span><span class="math-identifier">a</span><span class="math-identifier">d</span><span class="math-operator">&#x2212;</span><span class="math-identifier">b</span><span class="math-identifier">c</span></span>',
340
+ :latex => '\\left | \\begin{matrix} a & b \\\\ c & d \\end{matrix} \\right | = a d - b c',
341
+ ))
342
+
343
+ example('((a_(11), cdots , a_(1n)),(vdots, ddots, vdots),(a_(m1), cdots , a_(mn)))', &should_generate(
344
+ :ast => matrix([
345
+ [sub('a', group('11')), symbol('cdots'), sub('a', grseq('1', 'n'))],
346
+ [symbol('vdots'), symbol('ddots'), symbol('vdots')],
347
+ [sub('a', grseq('m', '1')), symbol('cdots'), sub('a', grseq('m', 'n'))]
348
+ ]),
349
+ :mathml => '<math><mrow><mo>(</mo><mtable><mtr><mtd><msub><mi>a</mi><mn>11</mn></msub></mtd><mtd><mo>&#x22EF;</mo></mtd><mtd><msub><mi>a</mi><mrow><mn>1</mn><mi>n</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>&#x22EE;</mo></mtd><mtd><mo>&#x22F1;</mo></mtd><mtd><mo>&#x22EE;</mo></mtd></mtr><mtr><mtd><msub><mi>a</mi><mrow><mi>m</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>&#x22EF;</mo></mtd><mtd><msub><mi>a</mi><mrow><mi>m</mi><mi>n</mi></mrow></msub></mtd></mtr></mtable><mo>)</mo></mrow></math>',
350
+ :html => '<span class="math-inline"><span class="math-row"><span class="math-brace" style="font-size: 300%;">(</span><span class="math-matrix" style="grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);"><span class="math-row"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-number">11</span></span></span></span><span class="math-row"><span class="math-operator">&#x22EF;</span></span><span class="math-row"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-row"><span class="math-number">1</span><span class="math-identifier">n</span></span></span></span></span><span class="math-row"><span class="math-operator">&#x22EE;</span></span><span class="math-row"><span class="math-operator">&#x22F1;</span></span><span class="math-row"><span class="math-operator">&#x22EE;</span></span><span class="math-row"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">m</span><span class="math-number">1</span></span></span></span></span><span class="math-row"><span class="math-operator">&#x22EF;</span></span><span class="math-row"><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller">&#x200D;</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">m</span><span class="math-identifier">n</span></span></span></span></span></span><span class="math-brace" style="font-size: 300%;">)</span></span></span>',
351
+ :latex => '\\left ( \\begin{matrix} a_{11} & \\cdots & a_{1 n} \\\\ \\vdots & \\ddots & \\vdots \\\\ a_{m 1} & \\cdots & a_{m n} \\end{matrix} \\right )',
352
+ ))
353
+
354
+ example('sum_(k=1)^n k = 1+2+ cdots +n=(n(n+1))/2', &should_generate(
355
+ :ast => seq(
356
+ subsup(symbol('sum'), grseq('k', symbol('='), '1'), 'n'),
357
+ 'k',
358
+ symbol('='),
359
+ '1', symbol('+'), '2', symbol('+'), symbol('cdots'), symbol('+'), 'n',
360
+ symbol('='),
361
+ infix(
362
+ grseq('n', paren(seq('n', symbol('+'), '1'))),
363
+ symbol('/'),
364
+ '2'
365
+ )
366
+ ),
367
+ :mathml => '<math><munderover><mo>&#x2211;</mo><mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow><mi>n</mi></munderover><mi>k</mi><mo>=</mo><mn>1</mn><mo>+</mo><mn>2</mn><mo>+</mo><mo>&#x22EF;</mo><mo>+</mo><mi>n</mi><mo>=</mo><mfrac><mrow><mi>n</mi><mrow><mo>(</mo><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow><mo>)</mo></mrow></mrow><mn>2</mn></mfrac></math>',
368
+ :html => '<span class="math-inline"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-identifier">n</span></span><span class="math-operator">&#x2211;</span><span class="math-smaller"><span class="math-row"><span class="math-identifier">k</span><span class="math-operator">=</span><span class="math-number">1</span></span></span></span><span class="math-identifier">k</span><span class="math-operator">=</span><span class="math-number">1</span><span class="math-operator">+</span><span class="math-number">2</span><span class="math-operator">+</span><span class="math-operator">&#x22EF;</span><span class="math-operator">+</span><span class="math-identifier">n</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">n</span><span class="math-row"><span class="math-brace">(</span><span class="math-identifier">n</span><span class="math-operator">+</span><span class="math-number">1</span><span class="math-brace">)</span></span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-number">2</span></span></span></span></span></span></span>',
369
+ :latex => '\\sum_{k = 1}^n k = 1 + 2 + \\cdots + n = \\frac{n ( n + 1 )}{2}',
370
+ ))
371
+
372
+ example('"Скорость"=("Расстояние")/("Время")', &should_generate(
373
+ :ast => seq(
374
+ 'Скорость',
375
+ symbol('='),
376
+ infix(group('Расстояние'), symbol('/'), group('Время'))
377
+ ),
378
+ :mathml => '<math><mtext>&#x421;&#x43A;&#x43E;&#x440;&#x43E;&#x441;&#x442;&#x44C;</mtext><mo>=</mo><mfrac><mtext>&#x420;&#x430;&#x441;&#x441;&#x442;&#x43E;&#x44F;&#x43D;&#x438;&#x435;</mtext><mtext>&#x412;&#x440;&#x435;&#x43C;&#x44F;</mtext></mfrac></math>',
379
+ :html => '<span class="math-inline"><span class="math-text">&#x421;&#x43A;&#x43E;&#x440;&#x43E;&#x441;&#x442;&#x44C;</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-text">&#x420;&#x430;&#x441;&#x441;&#x442;&#x43E;&#x44F;&#x43D;&#x438;&#x435;</span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-text">&#x412;&#x440;&#x435;&#x43C;&#x44F;</span></span></span></span></span></span></span>',
380
+ :latex => '\\text{Скорость} = \\frac{\\text{Расстояние}}{\\text{Время}}',
381
+ ))
382
+
383
+ example('bb (a + b) + cc c = fr (d^n)', &should_generate(
384
+ :ast => seq(
385
+ unary(symbol('bb'), grseq('a', symbol('+'), 'b')),
386
+ symbol('+'),
387
+ unary(symbol('cc'), 'c'),
388
+ symbol('='),
389
+ unary(symbol('fr'), group(sup('d', 'n')))
390
+ ),
391
+ :mathml => '<math><mstyle mathvariant="bold"><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></mstyle><mo>+</mo><mstyle mathvariant="script"><mi>c</mi></mstyle><mo>=</mo><mstyle mathvariant="fraktur"><msup><mi>d</mi><mi>n</mi></msup></mstyle></math>',
392
+ :latex => '\\mathbf{a + b} + \\mathscr{c} = \\mathfrak{d^n}',
393
+ ))
394
+
395
+ example('max()', &should_generate(
396
+ :ast => seq(symbol('max'), paren(nil)),
397
+ :mathml => '<math><mo>max</mo><mrow><mo>(</mo><mo>)</mo></mrow></math>',
398
+ :html => '<span class="math-inline"><span class="math-operator">max</span><span class="math-row"><span class="math-brace">(</span><span class="math-brace">)</span></span></span>',
399
+ :latex => '\\max ( )',
400
+ ))
401
+
402
+ example('text("foo")', &should_generate(
403
+ :ast => text('"foo"'),
404
+ :mathml => '<math><mtext>"foo"</mtext></math>',
405
+ :html => '<span class="math-inline"><span class="math-text">"foo"</span></span>',
406
+ :latex => '\\text{"foo"}',
407
+ ))
408
+
409
+ example('ubrace(1 + 2) obrace(3 + 4', &should_generate(
410
+ :ast => seq(
411
+ unary(symbol('ubrace'), grseq('1', symbol('+'), '2')),
412
+ unary(symbol('obrace'), group(symbol('('), seq('3', symbol('+'), '4'), nil))
413
+ ),
414
+ :mathml => '<math><munder><mrow><mn>1</mn><mo>+</mo><mn>2</mn></mrow><mo>&#x23DF;</mo></munder><mover><mrow><mn>3</mn><mo>+</mo><mn>4</mn></mrow><mo>&#x23DE;</mo></mover></math>',
415
+ :latex => '\\underbrace{1 + 2} \\overbrace{3 + 4}',
416
+ ))
417
+
418
+ example('s\'_i = {(- 1, if s_i > s_(i + 1)),( + 1, if s_i <= s_(i + 1)):}', &should_generate(
419
+ :ast => seq(
420
+ 's',
421
+ sub(symbol('\''), 'i'),
422
+ symbol('='),
423
+ matrix(
424
+ symbol('{'),
425
+ [
426
+ [seq(symbol('-'), '1'), seq(symbol('if'), sub('s', 'i'), symbol('>'), sub('s', grseq('i', symbol('+'), '1')))],
427
+ [seq(symbol('+'), '1'), seq(symbol('if'), sub('s', 'i'), symbol('<='), sub('s', grseq('i', symbol('+'), '1')))]
428
+ ],
429
+ symbol(':}'),
430
+ )
431
+ ),
432
+ :mathml => '<math><mi>s</mi><msub><mo>&#x2032;</mo><mi>i</mi></msub><mo>=</mo><mrow><mo>{</mo><mtable><mtr><mtd><mrow><mo>&#x2212;</mo><mn>1</mn></mrow></mtd><mtd><mrow><mo>if</mo><msub><mi>s</mi><mi>i</mi></msub><mo>&gt;</mo><msub><mi>s</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow></mtd></mtr><mtr><mtd><mrow><mo>+</mo><mn>1</mn></mrow></mtd><mtd><mrow><mo>if</mo><msub><mi>s</mi><mi>i</mi></msub><mo>&#x2264;</mo><msub><mi>s</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow></mtd></mtr></mtable></mrow></math>',
433
+ :latex => 's \'_i = \\left \\{ \\begin{matrix} - 1 & \\operatorname{if} s_i > s_{i + 1} \\\\ + 1 & \\operatorname{if} s_i \\le s_{i + 1} \\end{matrix} \\right .',
434
+ ))
435
+
436
+ example('s\'_i = {(, if s_i > s_(i + 1)),( + 1,):}', &should_generate(
437
+ :ast => seq(
438
+ 's',
439
+ sub(symbol('\''), 'i'),
440
+ symbol('='),
441
+ matrix(
442
+ symbol('{'),
443
+ [
444
+ [[], [symbol('if'), sub('s', 'i'), symbol('>'), sub('s', grseq('i', symbol('+'), '1'))]],
445
+ [[symbol('+'), '1'], []]
446
+ ],
447
+ symbol(':}')
448
+ )
449
+ ),
450
+ :mathml => '<math><mi>s</mi><msub><mo>&#x2032;</mo><mi>i</mi></msub><mo>=</mo><mrow><mo>{</mo><mtable><mtr><mtd></mtd><mtd><mrow><mo>if</mo><msub><mi>s</mi><mi>i</mi></msub><mo>&gt;</mo><msub><mi>s</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow></mtd></mtr><mtr><mtd><mrow><mo>+</mo><mn>1</mn></mrow></mtd><mtd></mtd></mtr></mtable></mrow></math>',
451
+ :latex => 's \'_i = \\left \\{ \\begin{matrix} & \\operatorname{if} s_i > s_{i + 1} \\\\ + 1 & \\end{matrix} \\right .',
452
+ ))
453
+
454
+ example('{:(a,b),(c,d):}', &should_generate(
455
+ :ast => matrix(
456
+ symbol('{:'),
457
+ [%w(a b), %w(c d)],
458
+ symbol(':}')
459
+ ),
460
+ :mathml => '<math><mtable><mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd></mtr><mtr><mtd><mi>c</mi></mtd><mtd><mi>d</mi></mtd></mtr></mtable></math>',
461
+ :latex => '\\begin{matrix} a & b \\\\ c & d \\end{matrix}',
462
+ ))
463
+
464
+ example('overset (a + b) (c + d)', &should_generate(
465
+ :ast => binary(
466
+ symbol('overset'),
467
+ grseq('a', symbol('+'), 'b'),
468
+ grseq('c', symbol('+'), 'd')
469
+ ),
470
+ :mathml => '<math><mover><mrow><mi>c</mi><mo>+</mo><mi>d</mi></mrow><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></mover></math>',
471
+ :html => '<span class="math-inline"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-row"><span class="math-identifier">a</span><span class="math-operator">+</span><span class="math-identifier">b</span></span></span><span class="math-row"><span class="math-identifier">c</span><span class="math-operator">+</span><span class="math-identifier">d</span></span><span class="math-smaller"><span class="math-blank">&#x200D;</span></span></span></span>',
472
+ :latex => '\\overset{a + b}{c + d}',
473
+ ))
474
+
475
+ example('underset a b', &should_generate(
476
+ :ast => binary(
477
+ symbol('underset'),
478
+ 'a',
479
+ 'b'
480
+ ),
481
+ :mathml => '<math><munder><mi>b</mi><mi>a</mi></munder></math>',
482
+ :html => '<span class="math-inline"><span class="math-blank">&#x200D;</span><span class="math-underover"><span class="math-smaller"><span class="math-blank">&#x200D;</span></span><span class="math-identifier">b</span><span class="math-smaller"><span class="math-identifier">a</span></span></span></span>',
483
+ :latex => '\\underset{a}{b}',
484
+ ))
485
+
486
+ example('sin a_c^b', &should_generate(
487
+ :ast => seq(
488
+ symbol('sin'),
489
+ subsup('a', 'c', 'b')
490
+ ),
491
+ :mathml => '<math><mi>sin</mi><msubsup><mi>a</mi><mi>c</mi><mi>b</mi></msubsup></math>',
492
+ :html => '<span class="math-inline"><span class="math-identifier">sin</span><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">c</span></span></span></span>',
493
+ :latex => '\\sin a_c^b',
494
+ ))
495
+
496
+ example('max a_c^b', &should_generate(
497
+ :ast => seq(
498
+ symbol('max'),
499
+ subsup('a', 'c', 'b')
500
+ ),
501
+ :mathml => '<math><mo>max</mo><msubsup><mi>a</mi><mi>c</mi><mi>b</mi></msubsup></math>',
502
+ :html => '<span class="math-inline"><span class="math-operator">max</span><span class="math-identifier">a</span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">c</span></span></span></span>',
503
+ :latex => '\\max a_c^b',
504
+ ))
505
+
506
+ example('norm a_c^b', &should_generate(
507
+ :ast => subsup(unary(symbol('norm'), 'a'), 'c', 'b'),
508
+ :mathml => '<math><msubsup><mrow><mo>&#x2225;</mo><mi>a</mi><mo>&#x2225;</mo></mrow><mi>c</mi><mi>b</mi></msubsup></math>',
509
+ :html => '<span class="math-inline"><span class="math-row"><span class="math-brace">&#x2225;</span><span class="math-identifier">a</span><span class="math-brace">&#x2225;</span></span><span class="math-subsup"><span class="math-smaller"><span class="math-identifier">b</span></span><span class="math-smaller"><span class="math-identifier">c</span></span></span></span>',
510
+ :latex => '{\\lVert a \\rVert}_c^b',
511
+ ))
512
+
513
+ example('overarc a_b^c', &should_generate(
514
+ :ast => subsup(unary(symbol('overarc'), 'a'), 'b', 'c'),
515
+ :mathml => '<math><msubsup><mover><mi>a</mi><mo>&#x23DC;</mo></mover><mi>b</mi><mi>c</mi></msubsup></math>',
516
+ :latex => '{\\overset{\\frown}{a}}_b^c'
517
+ ))
518
+
519
+ example('frown a_b^c', &should_generate(
520
+ :ast => seq(symbol('frown'), subsup('a', 'b', 'c')),
521
+ :mathml => '<math><mo>&#x2322;</mo><msubsup><mi>a</mi><mi>b</mi><mi>c</mi></msubsup></math>',
522
+ :latex => '\\frown a_b^c',
523
+ ))
524
+
525
+ example('sin(a_c^b)', &should_generate(
526
+ :ast => seq(symbol('sin'), paren(subsup('a', 'c', 'b'))),
527
+ :mathml => '<math><mi>sin</mi><mrow><mo>(</mo><msubsup><mi>a</mi><mi>c</mi><mi>b</mi></msubsup><mo>)</mo></mrow></math>',
528
+ :latex => '\\sin ( a_c^b )',
529
+ ))
530
+
531
+ example('text(a)a2)', &should_generate(
532
+ :ast => seq(text('a'), identifier('a'), number('2'), symbol(')')),
533
+ :mathml => '<math><mtext>a</mtext><mi>a</mi><mn>2</mn><mo>)</mo></math>',
534
+ :html => '<span class="math-inline"><span class="math-text">a</span><span class="math-identifier">a</span><span class="math-number">2</span><span class="math-operator">)</span></span>',
535
+ :latex => '\\text{a} a 2 )',
536
+ ))
537
+
538
+ example('cancel(a_b^c) cancel a_b^c', &should_generate(
539
+ :ast => seq(
540
+ unary(symbol('cancel'), group(subsup('a', 'b', 'c'))),
541
+ subsup(unary(symbol('cancel'), 'a'), 'b', 'c')
542
+ ),
543
+ :mathml => '<math><menclose notation="updiagonalstrike"><msubsup><mi>a</mi><mi>b</mi><mi>c</mi></msubsup></menclose><msubsup><menclose notation="updiagonalstrike"><mi>a</mi></menclose><mi>b</mi><mi>c</mi></msubsup></math>',
544
+ :latex => '\\cancel{a_b^c} {\\cancel{a}}_b^c',
545
+ ))
546
+
547
+ example('color(red)(x) color(#123)(y) color(#1234ab)(z) colortext(blue)(a_b^c)', &should_generate(
548
+ :ast => seq(
549
+ binary(symbol('color'), color(255, 0, 0, 'red'), group('x')),
550
+ binary(symbol('color'), color(17, 34, 51, '#123'), group('y')),
551
+ binary(symbol('color'), color(18, 52, 171, '#1234ab'), group('z')),
552
+ binary(symbol('color'), color(0, 0, 255, 'blue'), group(subsup('a', 'b', 'c')))
553
+ ),
554
+ :mathml => '<math><mstyle mathcolor="#ff0000"><mi>x</mi></mstyle><mstyle mathcolor="#112233"><mi>y</mi></mstyle><mstyle mathcolor="#1234ab"><mi>z</mi></mstyle><mstyle mathcolor="#0000ff"><msubsup><mi>a</mi><mi>b</mi><mi>c</mi></msubsup></mstyle></math>',
555
+ :latex => '{\\color{red} x} {\\color[RGB]{17,34,51} y} {\\color[RGB]{18,52,171} z} {\\color{blue} a_b^c}',
556
+ ))
557
+
558
+ example('{ x\ : \ x in A ^^ x in B }', &should_generate(
559
+ :ast => paren(
560
+ symbol('{'),
561
+ seq('x', symbol('\ '), ':', symbol('\ '), 'x', symbol('in'), 'A', symbol('^^'), 'x', symbol('in'), 'B'),
562
+ symbol('}')
563
+ ),
564
+ :mathml => '<math><mrow><mo>{</mo><mrow><mi>x</mi><mo>&#xA0;</mo><mi>:</mi><mo>&#xA0;</mo><mi>x</mi><mo>&#x2208;</mo><mi>A</mi><mo>&#x2227;</mo><mi>x</mi><mo>&#x2208;</mo><mi>B</mi></mrow><mo>}</mo></mrow></math>',
565
+ :latex => '\\left \\{ x \\; : \\; x \\in A \\wedge x \\in B \\right \\}',
566
+ ))
567
+
568
+ version = RUBY_VERSION.split('.').map { |s| s.to_i }
569
+
570
+ if version[0] > 1 || version[1] > 8
571
+ example('Скорость=(Расстояние)/(Время)', &should_generate(
572
+ :ast => seq(
573
+ 'С', 'к', 'о', 'р', 'о', 'с', 'т', 'ь',
574
+ symbol('='),
575
+ infix(
576
+ grseq('Р', 'а', 'с', 'с', 'т', 'о', 'я', 'н', 'и', 'е'),
577
+ symbol('/'),
578
+ grseq('В', 'р', 'е', 'м', 'я')
579
+ )
580
+ ),
581
+ :mathml => '<math><mi>&#x421;</mi><mi>&#x43A;</mi><mi>&#x43E;</mi><mi>&#x440;</mi><mi>&#x43E;</mi><mi>&#x441;</mi><mi>&#x442;</mi><mi>&#x44C;</mi><mo>=</mo><mfrac><mrow><mi>&#x420;</mi><mi>&#x430;</mi><mi>&#x441;</mi><mi>&#x441;</mi><mi>&#x442;</mi><mi>&#x43E;</mi><mi>&#x44F;</mi><mi>&#x43D;</mi><mi>&#x438;</mi><mi>&#x435;</mi></mrow><mrow><mi>&#x412;</mi><mi>&#x440;</mi><mi>&#x435;</mi><mi>&#x43C;</mi><mi>&#x44F;</mi></mrow></mfrac></math>',
582
+ :html => '<span class="math-inline"><span class="math-identifier">&#x421;</span><span class="math-identifier">&#x43A;</span><span class="math-identifier">&#x43E;</span><span class="math-identifier">&#x440;</span><span class="math-identifier">&#x43E;</span><span class="math-identifier">&#x441;</span><span class="math-identifier">&#x442;</span><span class="math-identifier">&#x44C;</span><span class="math-operator">=</span><span class="math-blank">&#x200D;</span><span class="math-fraction"><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">&#x420;</span><span class="math-identifier">&#x430;</span><span class="math-identifier">&#x441;</span><span class="math-identifier">&#x441;</span><span class="math-identifier">&#x442;</span><span class="math-identifier">&#x43E;</span><span class="math-identifier">&#x44F;</span><span class="math-identifier">&#x43D;</span><span class="math-identifier">&#x438;</span><span class="math-identifier">&#x435;</span></span></span></span></span></span><span class="math-fraction_row"><span class="math-fraction_cell"><span class="math-smaller"><span class="math-row"><span class="math-row"><span class="math-identifier">&#x412;</span><span class="math-identifier">&#x440;</span><span class="math-identifier">&#x435;</span><span class="math-identifier">&#x43C;</span><span class="math-identifier">&#x44F;</span></span></span></span></span></span></span></span>',
583
+ :latex => 'С к о р о с т ь = \\frac{Р а с с т о я н и е}{В р е м я}'
584
+ ))
178
585
  end
179
- end
586
+ end
587
+
588
+ describe 'AsciiMath::Parser', :variant => :ast do
589
+ include_examples 'AsciiMath Examples'
590
+ end
591
+
592
+ describe 'AsciiMath::MathMLBuilder', :variant => :mathml do
593
+ include_examples 'AsciiMath Examples'
594
+ end
595
+
596
+ describe 'AsciiMath::MathMLBuilder Microsoft Office', :variant => :mathml_word do
597
+ include_examples 'AsciiMath Examples'
598
+ end
599
+
600
+ describe 'AsciiMath::HTMLBuilder', :variant => :html do
601
+ include_examples 'AsciiMath Examples', :html
602
+ end
603
+
604
+ describe 'AsciiMath::LatexBuilder', :variant => :latex do
605
+ include_examples 'AsciiMath Examples'
606
+ end