math_ml 0.14 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +339 -0
- data/lib/math_ml/element.rb +233 -225
- data/lib/math_ml/latex/builtin/symbol.rb +546 -546
- data/lib/math_ml/latex/builtin.rb +3 -3
- data/lib/math_ml/latex.rb +1140 -1103
- data/lib/math_ml/string.rb +17 -16
- data/lib/math_ml/symbol/character_reference.rb +2100 -2101
- data/lib/math_ml/symbol/entity_reference.rb +2100 -2100
- data/lib/math_ml/symbol/utf8.rb +2100 -2102
- data/lib/math_ml/util.rb +350 -339
- data/lib/math_ml.rb +14 -14
- metadata +43 -75
- data/Rakefile +0 -60
- data/Rakefile.utirake +0 -392
- data/spec/math_ml/element_spec.rb +0 -32
- data/spec/math_ml/latex/macro_spec.rb +0 -122
- data/spec/math_ml/latex/parser_spec.rb +0 -580
- data/spec/math_ml/latex/scanner_spec.rb +0 -202
- data/spec/math_ml/string_spec.rb +0 -29
- data/spec/math_ml/util_spec.rb +0 -700
- data/spec/math_ml_spec.rb +0 -14
- data/spec/util.rb +0 -43
@@ -1,580 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
require "eim_xml/parser"
|
3
|
-
require "eim_xml/dsl"
|
4
|
-
require "math_ml"
|
5
|
-
require "spec/util"
|
6
|
-
require "math_ml/symbol/character_reference"
|
7
|
-
require "math_ml/symbol/utf8"
|
8
|
-
|
9
|
-
describe MathML::LaTeX::Parser do
|
10
|
-
include MathML::Spec::Util
|
11
|
-
|
12
|
-
def check_chr(tag, src)
|
13
|
-
src.scan(/./) do |c|
|
14
|
-
tag_re = Regexp.escape(tag)
|
15
|
-
smml(c).should =~ /\A<#{tag_re}(\s+[^>]+)?>#{Regexp.escape(c)}<\/#{tag_re}>\z/
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def check_hash(tag, hash)
|
20
|
-
hash.each do |k, v|
|
21
|
-
tag_re = Regexp.escape(tag)
|
22
|
-
smml(k).should =~ /\A<#{tag_re}(\s+[^>]+)?>#{Regexp.escape(v)}<\/#{tag_re}>\z/
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def check_entity(tag, hash)
|
27
|
-
check_hash(tag, hash.inject({}){|r, i| r[i[0]]="&#{i[1]};"; r})
|
28
|
-
end
|
29
|
-
|
30
|
-
it "Spec#strip_math_ml" do
|
31
|
-
src = "<math test='dummy'> <a> b </a> <c> d </c></math>"
|
32
|
-
strip_math_ml(src).should == "<a>b</a><c>d</c>"
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "#parse" do
|
36
|
-
it "should return math element" do
|
37
|
-
ns = "http://www.w3.org/1998/Math/MathML"
|
38
|
-
|
39
|
-
e = new_parser.parse("")
|
40
|
-
e.should match(EimXML::Element.new(:math, :display=>"inline", "xmlns"=>ns))
|
41
|
-
e.attributes.keys.size.should == 2
|
42
|
-
e.contents.should be_empty
|
43
|
-
|
44
|
-
e = new_parser.parse("", true)
|
45
|
-
e.should match(EimXML::Element.new(:math, :display=>"block", "xmlns"=>ns))
|
46
|
-
e.attributes.keys.size.should == 2
|
47
|
-
e.contents.should be_empty
|
48
|
-
|
49
|
-
e = new_parser.parse("", false)
|
50
|
-
e.should match(EimXML::Element.new(:math, :display=>"inline", "xmlns"=>ns))
|
51
|
-
e.attributes.keys.size.should == 2
|
52
|
-
e.contents.should be_empty
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should ignore space" do
|
56
|
-
smml("{ a }").should == "<mrow><mi>a</mi></mrow>"
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should process latex block" do
|
60
|
-
lambda{smml("test {test} {test")}.should raise_parse_error("Block not closed.", "test {test} ", "{test")
|
61
|
-
end
|
62
|
-
|
63
|
-
it "should raise error when error happened" do
|
64
|
-
src = 'a\hoge c'
|
65
|
-
lambda{smml(src)}.should raise_parse_error("Undefined command.", "a", '\hoge c')
|
66
|
-
|
67
|
-
src = '\sqrt\sqrt1'
|
68
|
-
lambda{smml(src)}.should raise_parse_error("Syntax error.", '\sqrt\sqrt', "1")
|
69
|
-
|
70
|
-
src = "a{b"
|
71
|
-
lambda{smml(src)}.should raise_parse_error("Block not closed.", "a", "{b")
|
72
|
-
end
|
73
|
-
|
74
|
-
it "should process numerics" do
|
75
|
-
smml('1234567890').should == "<mn>1234567890</mn>"
|
76
|
-
smml('1.2').should == "<mn>1.2</mn>"
|
77
|
-
smml('1.').should == "<mn>1</mn><mo stretchy='false'>.</mo>"
|
78
|
-
smml('.2').should == "<mn>.2</mn>"
|
79
|
-
smml('1.2.3').should == "<mn>1.2</mn><mn>.3</mn>"
|
80
|
-
end
|
81
|
-
|
82
|
-
it "should process alphabets" do
|
83
|
-
smml("abc").should == "<mi>a</mi><mi>b</mi><mi>c</mi>"
|
84
|
-
check_chr("mi", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
85
|
-
end
|
86
|
-
|
87
|
-
it "should process non alphabet command" do
|
88
|
-
smml('\|').should == "<mo stretchy='false'>∥</mo>"
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should process space commands" do
|
92
|
-
smml('\ ').should == "<mspace width='1em' />"
|
93
|
-
smml('\quad').should == "<mspace width='1em' />"
|
94
|
-
smml('\qquad').should == "<mspace width='2em' />"
|
95
|
-
smml('\,').should == "<mspace width='0.167em' />"
|
96
|
-
smml('\:').should == "<mspace width='0.222em' />"
|
97
|
-
smml('\;').should == "<mspace width='0.278em' />"
|
98
|
-
smml('\!').should == "<mspace width='-0.167em' />"
|
99
|
-
smml('~').should == "<mspace width='1em' />"
|
100
|
-
end
|
101
|
-
|
102
|
-
it "should process operators" do
|
103
|
-
check_chr("mo", ",.+-*=/()[]|;:!")
|
104
|
-
check_entity("mo", {"<"=>"lt", ">"=>"gt", '"'=>"quot"})
|
105
|
-
check_hash("mo", {'\backslash'=>'\\', '\%'=>'%', '\{'=>'{', '\}'=>'}', '\$'=>'$', '\#'=>'#'})
|
106
|
-
end
|
107
|
-
|
108
|
-
describe "should process prime" do
|
109
|
-
it "entity reference" do
|
110
|
-
smml("a'").should == "<msup><mi>a</mi><mo>′</mo></msup>"
|
111
|
-
smml("a''").should == "<msup><mi>a</mi><mo>′′</mo></msup>"
|
112
|
-
smml("a'''").should == "<msup><mi>a</mi><mo>′′′</mo></msup>"
|
113
|
-
smml("'").should == "<msup><none /><mo>′</mo></msup>"
|
114
|
-
|
115
|
-
lambda{smml("a^b'")}.should raise_parse_error("Double superscript.", "a^b", "'")
|
116
|
-
|
117
|
-
smml("a'^b").should == "<msup><mi>a</mi><mrow><mo>′</mo><mi>b</mi></mrow></msup>"
|
118
|
-
smml("a'''^b").should == "<msup><mi>a</mi><mrow><mo>′′′</mo><mi>b</mi></mrow></msup>"
|
119
|
-
smml("a'b").should == "<msup><mi>a</mi><mo>′</mo></msup><mi>b</mi>"
|
120
|
-
end
|
121
|
-
|
122
|
-
it "utf8" do
|
123
|
-
@parser = MathML::LaTeX::Parser.new(:symbol=>MathML::Symbol::UTF8)
|
124
|
-
smml("a'").should == "<msup><mi>a</mi><mo>′</mo></msup>"
|
125
|
-
smml("a'''").should == "<msup><mi>a</mi><mo>′′′</mo></msup>"
|
126
|
-
end
|
127
|
-
|
128
|
-
it "character reference" do
|
129
|
-
@parser = MathML::LaTeX::Parser.new(:symbol=>MathML::Symbol::CharacterReference)
|
130
|
-
smml("a'").should == "<msup><mi>a</mi><mo>′</mo></msup>"
|
131
|
-
smml("a'''").should == "<msup><mi>a</mi><mo>′′′</mo></msup>"
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
it "should process sqrt" do
|
136
|
-
smml('\sqrt a').should == "<msqrt><mi>a</mi></msqrt>"
|
137
|
-
smml('\sqrt[2]3').should == "<mroot><mn>3</mn><mn>2</mn></mroot>"
|
138
|
-
smml('\sqrt[2a]3').should == "<mroot><mn>3</mn><mrow><mn>2</mn><mi>a</mi></mrow></mroot>"
|
139
|
-
lambda{smml('\sqrt[12')}.should raise_parse_error("Option not closed.", '\sqrt', "[12")
|
140
|
-
end
|
141
|
-
|
142
|
-
it "should process subsup" do
|
143
|
-
smml("a_b^c").should == "<msubsup><mi>a</mi><mi>b</mi><mi>c</mi></msubsup>"
|
144
|
-
smml("a_b").should == "<msub><mi>a</mi><mi>b</mi></msub>"
|
145
|
-
smml("a^b").should == "<msup><mi>a</mi><mi>b</mi></msup>"
|
146
|
-
smml("_a^b").should == "<msubsup><none /><mi>a</mi><mi>b</mi></msubsup>"
|
147
|
-
|
148
|
-
lambda{smml("a_b_c")}.should raise_parse_error("Double subscript.", "a_b", "_c")
|
149
|
-
lambda{smml("a^b^c")}.should raise_parse_error("Double superscript.", "a^b", "^c")
|
150
|
-
lambda{smml("a_")}.should raise_parse_error("Subscript not exist.", "a_", "")
|
151
|
-
lambda{smml("a^")}.should raise_parse_error("Superscript not exist.", "a^", "")
|
152
|
-
end
|
153
|
-
|
154
|
-
it "should process underover" do
|
155
|
-
smml('\sum_a^b', true).should == "<munderover><mo stretchy='false'>∑</mo><mi>a</mi><mi>b</mi></munderover>"
|
156
|
-
smml('\sum_a^b').should == "<msubsup><mo stretchy='false'>∑</mo><mi>a</mi><mi>b</mi></msubsup>"
|
157
|
-
smml('\sum_a', true).should == "<munder><mo stretchy='false'>∑</mo><mi>a</mi></munder>"
|
158
|
-
smml('\sum^a', true).should == "<mover><mo stretchy='false'>∑</mo><mi>a</mi></mover>"
|
159
|
-
smml('\sum_a').should == "<msub><mo stretchy='false'>∑</mo><mi>a</mi></msub>"
|
160
|
-
smml('\sum^a').should == "<msup><mo stretchy='false'>∑</mo><mi>a</mi></msup>"
|
161
|
-
|
162
|
-
lambda{smml('\sum_b_c')}.should raise_parse_error("Double subscript.", '\sum_b', "_c")
|
163
|
-
lambda{smml('\sum^b^c')}.should raise_parse_error("Double superscript.", '\sum^b', "^c")
|
164
|
-
lambda{smml('\sum_')}.should raise_parse_error("Subscript not exist.", '\sum_', "")
|
165
|
-
lambda{smml('\sum^')}.should raise_parse_error("Superscript not exist.", '\sum^', "")
|
166
|
-
end
|
167
|
-
|
168
|
-
it "should process font commands" do
|
169
|
-
smml('a{\bf b c}d').should == "<mi>a</mi><mrow><mi mathvariant='bold'>b</mi><mi mathvariant='bold'>c</mi></mrow><mi>d</mi>"
|
170
|
-
smml('\bf a{\it b c}d').should == "<mi mathvariant='bold'>a</mi><mrow><mi>b</mi><mi>c</mi></mrow><mi mathvariant='bold'>d</mi>"
|
171
|
-
smml('a{\rm b c}d').should == "<mi>a</mi><mrow><mi mathvariant='normal'>b</mi><mi mathvariant='normal'>c</mi></mrow><mi>d</mi>"
|
172
|
-
|
173
|
-
smml('a \mathbf{bc}d').should == "<mi>a</mi><mrow><mrow><mi mathvariant='bold'>b</mi><mi mathvariant='bold'>c</mi></mrow></mrow><mi>d</mi>"
|
174
|
-
smml('\mathbf12').should == "<mrow><mn mathvariant='bold'>1</mn></mrow><mn>2</mn>"
|
175
|
-
smml('\bf a \mathit{bc} d').should == "<mi mathvariant='bold'>a</mi><mrow><mrow><mi>b</mi><mi>c</mi></mrow></mrow><mi mathvariant='bold'>d</mi>"
|
176
|
-
smml('a\mathrm{bc}d').should == "<mi>a</mi><mrow><mrow><mi mathvariant='normal'>b</mi><mi mathvariant='normal'>c</mi></mrow></mrow><mi>d</mi>"
|
177
|
-
|
178
|
-
smml('a \mathbb{b c} d').should == "<mi>a</mi><mrow><mrow><mi>𝕓</mi><mi>𝕔</mi></mrow></mrow><mi>d</mi>"
|
179
|
-
smml('a \mathscr{b c} d').should == "<mi>a</mi><mrow><mrow><mi>𝒷</mi><mi>𝒸</mi></mrow></mrow><mi>d</mi>"
|
180
|
-
smml('a \mathfrak{b c} d').should == "<mi>a</mi><mrow><mrow><mi>𝔟</mi><mi>𝔠</mi></mrow></mrow><mi>d</mi>"
|
181
|
-
smml('a \bm{bc}d').should == "<mi>a</mi><mrow><mrow><mi mathvariant='bold-italic'>b</mi><mi mathvariant='bold-italic'>c</mi></mrow></mrow><mi>d</mi>"
|
182
|
-
smml('\bm ab').should == "<mrow><mi mathvariant='bold-italic'>a</mi></mrow><mi>b</mi>"
|
183
|
-
|
184
|
-
lambda{smml('\mathit')}.should raise_parse_error("Syntax error.", '\mathit', "")
|
185
|
-
lambda{smml('\mathrm')}.should raise_parse_error("Syntax error.", '\mathrm', "")
|
186
|
-
lambda{smml('\mathbf')}.should raise_parse_error("Syntax error.", '\mathbf', "")
|
187
|
-
lambda{smml('\mathbb')}.should raise_parse_error("Syntax error.", '\mathbb', "")
|
188
|
-
lambda{smml('\mathscr')}.should raise_parse_error("Syntax error.", '\mathscr', "")
|
189
|
-
lambda{smml('\mathfrak')}.should raise_parse_error("Syntax error.", '\mathfrak', "")
|
190
|
-
end
|
191
|
-
|
192
|
-
it "should process mbox" do
|
193
|
-
smml('a\mbox{b c}d').should == "<mi>a</mi><mtext>b c</mtext><mi>d</mi>"
|
194
|
-
smml('\mbox{<>\'"&}').should == '<mtext><>'"&</mtext>'
|
195
|
-
end
|
196
|
-
|
197
|
-
it "should process frac" do
|
198
|
-
smml('\frac ab').should == "<mfrac><mi>a</mi><mi>b</mi></mfrac>"
|
199
|
-
smml('\frac12').should == "<mfrac><mn>1</mn><mn>2</mn></mfrac>"
|
200
|
-
|
201
|
-
lambda{smml('\frac a')}.should raise_parse_error("Syntax error.", '\frac a', "")
|
202
|
-
end
|
203
|
-
|
204
|
-
it "should process environment" do
|
205
|
-
lambda{smml('{\begin}rest')}.should raise_parse_error("Environment name not exist.", '{\begin', '}rest')
|
206
|
-
|
207
|
-
lambda{smml('{\begin{array}{c}dummy}rest')}.should raise_parse_error('Matching \end not exist.', '{\begin{array}{c}dummy', '}rest')
|
208
|
-
|
209
|
-
lambda{smml('\begin{array}c dummy\end{test}')}.should raise_parse_error("Environment mismatched.", '\begin{array}c dummy\end', "{test}")
|
210
|
-
|
211
|
-
lambda{smml('\left(\begin{array}\right)')}.should raise_parse_error("Syntax error.", '\left(\begin{array}', '\right)')
|
212
|
-
end
|
213
|
-
|
214
|
-
it "should process array" do
|
215
|
-
smml('\begin{array}{lrc} a & b & c \\\\ d & e & f \\\\ \end{array}').should == "<mtable columnalign='left right center'><mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd><mtd><mi>c</mi></mtd></mtr><mtr><mtd><mi>d</mi></mtd><mtd><mi>e</mi></mtd><mtd><mi>f</mi></mtd></mtr></mtable>"
|
216
|
-
|
217
|
-
smml('\begin{array}{lrc}a&b&c\\\\d&e&f \end{array}').should == "<mtable columnalign='left right center'><mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd><mtd><mi>c</mi></mtd></mtr><mtr><mtd><mi>d</mi></mtd><mtd><mi>e</mi></mtd><mtd><mi>f</mi></mtd></mtr></mtable>"
|
218
|
-
|
219
|
-
smml('\begin{array}{c}\end{array}').should == "<mtable />"
|
220
|
-
|
221
|
-
lambda{smml('\begin{array}\end{array}')}.should raise_parse_error('Syntax error.', '\begin{array}', '\end{array}')
|
222
|
-
|
223
|
-
lambda{smml('\begin{array}{a}\end{array}')}.should raise_parse_error("Syntax error.", '\begin{array}{', 'a}\end{array}')
|
224
|
-
|
225
|
-
lambda{smml('\begin{array}{cc}a\\\\b&c\end{array}')}.should raise_parse_error("Need more column.", '\begin{array}{cc}a', '\\\\b&c\end{array}')
|
226
|
-
|
227
|
-
lambda{smml('\begin{array}{cc}a\end{array}')}.should raise_parse_error("Need more column.", '\begin{array}{cc}a', '\end{array}')
|
228
|
-
|
229
|
-
lambda{smml('\begin{array}{c}a&\end{array}')}.should raise_parse_error("Too many column.", '\begin{array}{c}a', '&\end{array}')
|
230
|
-
|
231
|
-
smml('\begin{array}{cc}&\end{array}').should == "<mtable><mtr><mtd /><mtd /></mtr></mtable>"
|
232
|
-
|
233
|
-
math_ml('\left\{\begin{array}ca_b\end{array}\right\}')[0].should =~ EimXML::DSL.element(:mfenced, :open=>"{", :close=>"}"){
|
234
|
-
element :mrow do
|
235
|
-
element :mtable do
|
236
|
-
element :mtr do
|
237
|
-
element :mtd do
|
238
|
-
element :msub do
|
239
|
-
element(:mi).add("a")
|
240
|
-
element(:mi).add("b")
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
}
|
247
|
-
|
248
|
-
smml('\begin{array}{@{a_1}l@bc@cr@d}A&B&C\end{array}').should == "<mtable columnalign='center left center center center right center'><mtr><mtd><mrow><msub><mi>a</mi><mn>1</mn></msub></mrow></mtd><mtd><mi>A</mi></mtd><mtd><mi>b</mi></mtd><mtd><mi>B</mi></mtd><mtd><mi>c</mi></mtd><mtd><mi>C</mi></mtd><mtd><mi>d</mi></mtd></mtr></mtable>"
|
249
|
-
|
250
|
-
math_ml('\left\{\begin{array}ca_b\end{array}\right\}')[0].should =~ EimXML::DSL.element(:mfenced, :open=>"{", :close=>"}"){
|
251
|
-
element :mrow do
|
252
|
-
element :mtable do
|
253
|
-
element :mtr do
|
254
|
-
element :mtd do
|
255
|
-
element :msub do
|
256
|
-
element(:mi).add("a")
|
257
|
-
element(:mi).add("b")
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
}
|
264
|
-
|
265
|
-
smml('\begin{array}{c|c}a&b\\\\c&d\end{array}').should == "<mtable columnlines='solid'><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>"
|
266
|
-
smml('\begin{array}{|c|}a\\\\c\end{array}').should == "<mtable columnlines='solid solid'><mtr><mtd /><mtd><mi>a</mi></mtd><mtd /></mtr><mtr><mtd /><mtd><mi>c</mi></mtd><mtd /></mtr></mtable>"
|
267
|
-
smml('\begin{array}{c}\hline c\end{array}').should == "<mtable rowlines='solid'><mtr /><mtr><mtd><mi>c</mi></mtd></mtr></mtable>"
|
268
|
-
smml('\begin{array}{c@acc}c&c&c\\\\\hline\end{array}').should == "<mtable rowlines='solid'><mtr><mtd><mi>c</mi></mtd><mtd><mi>a</mi></mtd><mtd><mi>c</mi></mtd><mtd><mi>c</mi></mtd></mtr><mtr><mtd /><mtd /><mtd /><mtd /></mtr></mtable>"
|
269
|
-
smml('\begin{array}{c}\hline a\\\\b\\\\\hline\end{array}').should == "<mtable rowlines='solid none solid'><mtr /><mtr><mtd><mi>a</mi></mtd></mtr><mtr><mtd><mi>b</mi></mtd></mtr><mtr><mtd /></mtr></mtable>"
|
270
|
-
end
|
271
|
-
|
272
|
-
it "should parse \\left and \\right" do
|
273
|
-
math_ml('\left(\frac12\right)')[0].should =~ EimXML::DSL.element(:mfenced, :open=>"(", :close=>")"){
|
274
|
-
element :mrow do
|
275
|
-
element :mfrac do
|
276
|
-
element(:mn).add("1")
|
277
|
-
element(:mn).add("2")
|
278
|
-
end
|
279
|
-
end
|
280
|
-
}
|
281
|
-
|
282
|
-
math_ml('\left \lfloor a\right \rfloor')[0].should =~ EimXML::DSL.element(:mfenced, :open=>EimXML::PCString.new("⌊", true), :close=>EimXML::PCString.new("⌋", true)){
|
283
|
-
element :mrow do
|
284
|
-
element(:mi).add("a")
|
285
|
-
end
|
286
|
-
}
|
287
|
-
|
288
|
-
math_ml('\left \{ a \right \}')[0].should =~ EimXML::DSL.element(:mfenced, :open=>"{", :close=>"}"){
|
289
|
-
element :mrow do
|
290
|
-
element(:mi).add("a")
|
291
|
-
end
|
292
|
-
}
|
293
|
-
|
294
|
-
math_ml('\left\{\begin{array}c\begin{array}ca\end{array}\end{array}\right\}')[0].should =~ EimXML::DSL.element(:mfenced, :open=>"{", :close=>"}"){
|
295
|
-
element :mrow do
|
296
|
-
element :mtable do
|
297
|
-
element :mtr do
|
298
|
-
element :mtd do
|
299
|
-
element :mtable do
|
300
|
-
element :mtr do
|
301
|
-
element :mtd do
|
302
|
-
element(:mi).add("a")
|
303
|
-
end
|
304
|
-
end
|
305
|
-
end
|
306
|
-
end
|
307
|
-
end
|
308
|
-
end
|
309
|
-
end
|
310
|
-
}
|
311
|
-
|
312
|
-
math_ml('\left(\sum_a\right)')[0].should =~ EimXML::DSL.element(:mfenced, :open=>"(", :close=>")"){
|
313
|
-
element :mrow do
|
314
|
-
element :msub do
|
315
|
-
element(:mo).add(EimXML::PCString.new("∑", true))
|
316
|
-
element(:mi).add("a")
|
317
|
-
end
|
318
|
-
end
|
319
|
-
}
|
320
|
-
|
321
|
-
math_ml('\left(\sum_a\right)', true)[0].should =~ EimXML::DSL.element(:mfenced, :open=>"(", :close=>")"){
|
322
|
-
element :mrow do
|
323
|
-
element :munder do
|
324
|
-
element(:mo).add(EimXML::PCString.new("∑", true))
|
325
|
-
element(:mi).add("a")
|
326
|
-
end
|
327
|
-
end
|
328
|
-
}
|
329
|
-
|
330
|
-
lambda{smml('\left(test')}.should raise_parse_error("Brace not closed.", '\left', '(test')
|
331
|
-
|
332
|
-
math_ml('\left\|a\right\|')[0].should =~ EimXML::DSL.element(:mfenced, :open=>EimXML::PCString.new("∥", true), :close=>EimXML::PCString.new("∥", true)){
|
333
|
-
element :mrow do
|
334
|
-
element(:mi).add("a")
|
335
|
-
end
|
336
|
-
}
|
337
|
-
|
338
|
-
lambda{smml('\left')}.should raise_parse_error("Need brace here.", '\left', "")
|
339
|
-
end
|
340
|
-
|
341
|
-
it "should parse overs" do
|
342
|
-
smml('\hat a').should == "<mover><mi>a</mi><mo>ˆ</mo></mover>"
|
343
|
-
smml('\hat12').should == "<mover><mn>1</mn><mo>ˆ</mo></mover><mn>2</mn>"
|
344
|
-
lambda{smml('{\hat}a')}.should raise_parse_error("Syntax error.", '{\hat', '}a')
|
345
|
-
end
|
346
|
-
|
347
|
-
it "should parse unders" do
|
348
|
-
smml('\underline a').should == "<munder><mi>a</mi><mo>¯</mo></munder>"
|
349
|
-
smml('\underline12').should == "<munder><mn>1</mn><mo>¯</mo></munder><mn>2</mn>"
|
350
|
-
lambda{smml('{\underline}a')}.should raise_parse_error("Syntax error.", '{\underline', '}a')
|
351
|
-
end
|
352
|
-
|
353
|
-
it "should parse stackrel" do
|
354
|
-
smml('\stackrel\to=').should == "<mover><mo stretchy='false'>=</mo><mo stretchy='false'>→</mo></mover>"
|
355
|
-
smml('\stackrel12').should == "<mover><mn>2</mn><mn>1</mn></mover>"
|
356
|
-
end
|
357
|
-
|
358
|
-
it "should parse comment" do
|
359
|
-
smml('a%b').should == "<mi>a</mi>"
|
360
|
-
end
|
361
|
-
|
362
|
-
it "should parse entity" do
|
363
|
-
p = new_parser
|
364
|
-
lambda{smml('\entity{therefore}', false, p)}.should raise_parse_error("Unregistered entity.", '\entity{', "therefore}")
|
365
|
-
|
366
|
-
p.unsecure_entity = true
|
367
|
-
smml('\entity{therefore}', false, p).should == "<mo>∴</mo>"
|
368
|
-
|
369
|
-
p.unsecure_entity = false
|
370
|
-
lambda{smml('\entity{therefore}', false, p)}.should raise_parse_error("Unregistered entity.", '\entity{', "therefore}")
|
371
|
-
|
372
|
-
p.add_entity(['therefore'])
|
373
|
-
smml('\entity{therefore}', false, p).should == "<mo>∴</mo>"
|
374
|
-
end
|
375
|
-
|
376
|
-
it "should parse backslash" do
|
377
|
-
smml('\\\\').should == "<br xmlns='http://www.w3.org/1999/xhtml' />"
|
378
|
-
end
|
379
|
-
|
380
|
-
it "can be used with macro" do
|
381
|
-
macro = <<'EOS'
|
382
|
-
\newcommand{\root}[2]{\sqrt[#1]{#2}}
|
383
|
-
\newcommand{\ROOT}[2]{\sqrt[#1]#2}
|
384
|
-
\newenvironment{braced}[2]{\left#1}{\right#2}
|
385
|
-
\newenvironment{sq}[2]{\sqrt[#2]{#1}}{\sqrt#2}
|
386
|
-
\newcommand{\R}{\mathbb R}
|
387
|
-
\newenvironment{BB}{\mathbb A}{\mathbb B}
|
388
|
-
EOS
|
389
|
-
p = new_parser
|
390
|
-
p.macro.parse(macro)
|
391
|
-
|
392
|
-
smml('\root12', false, p).should == "<mroot><mrow><mn>2</mn></mrow><mn>1</mn></mroot>"
|
393
|
-
smml('\root{12}{34}', false, p).should == "<mroot><mrow><mn>34</mn></mrow><mn>12</mn></mroot>"
|
394
|
-
smml('\ROOT{12}{34}', false, p).should == "<mroot><mn>3</mn><mn>12</mn></mroot><mn>4</mn>"
|
395
|
-
lambda{smml('\root', false, p)}.should raise_parse_error('Error in macro(Need more parameter. "").', '', '\root')
|
396
|
-
|
397
|
-
|
398
|
-
math_ml('\begin{braced}{|}{)}\frac12\end{braced}', false, p)[0].should =~ EimXML::DSL.element(:mfenced, :open=>"|", :close=>")"){
|
399
|
-
element(:mrow) do
|
400
|
-
element(:mfrac) do
|
401
|
-
element(:mn).add("1")
|
402
|
-
element(:mn).add("2")
|
403
|
-
end
|
404
|
-
end
|
405
|
-
}
|
406
|
-
|
407
|
-
smml('\begin{sq}{12}{34}a\end{sq}', false, p).should == "<mroot><mrow><mn>12</mn></mrow><mn>34</mn></mroot><mi>a</mi><msqrt><mn>3</mn></msqrt><mn>4</mn>"
|
408
|
-
lambda{smml('\begin{braced}', false, p)}.should raise_parse_error("Need more parameter.", '\begin{braced}', "")
|
409
|
-
lambda{smml('\begin{braced}123', false, p)}.should raise_parse_error('Matching \end not exist.', '\begin{braced}', "123")
|
410
|
-
lambda{smml('\begin{braced}123\end{brace}', false, p)}.should raise_parse_error("Environment mismatched.", '\begin{braced}123\end', '{brace}')
|
411
|
-
smml('\R', false, p).should == "<mrow><mi>ℝ</mi></mrow>"
|
412
|
-
smml('\begin{BB}\end{BB}', false, p).should == "<mrow><mi>𝔸</mi></mrow><mrow><mi>𝔹</mi></mrow>"
|
413
|
-
end
|
414
|
-
|
415
|
-
it "should raise error when macro define circular reference" do
|
416
|
-
macro = <<'EOT'
|
417
|
-
\newcommand{\C}{\C}
|
418
|
-
\newenvironment{E}{\begin{E}}{\end{E}}
|
419
|
-
\newcommand{\D}{\begin{F}\end{F}}
|
420
|
-
\newenvironment{F}{\D}{}
|
421
|
-
EOT
|
422
|
-
ps = new_parser
|
423
|
-
ps.macro.parse(macro)
|
424
|
-
|
425
|
-
lambda{smml('\C', false, ps)}.should raise_parse_error("Circular reference.", "", '\C')
|
426
|
-
lambda{smml('\begin{E}\end{E}', false, ps)}.should raise_parse_error("Circular reference.", "", '\begin{E}\end{E}')
|
427
|
-
lambda{smml('\D', false, ps)}.should raise_parse_error("Circular reference.", "", '\D')
|
428
|
-
lambda{smml('\begin{F}\end{F}', false, ps)}.should raise_parse_error("Circular reference.", "", '\begin{F}\end{F}')
|
429
|
-
end
|
430
|
-
|
431
|
-
it "should raise error when macro uses undefined command" do
|
432
|
-
macro = <<'EOT'
|
433
|
-
\newcommand{\C}{\dummy}
|
434
|
-
\newenvironment{E}{\dummy}{}
|
435
|
-
EOT
|
436
|
-
ps = new_parser
|
437
|
-
ps.macro.parse(macro)
|
438
|
-
|
439
|
-
lambda{smml('\C', false, ps)}.should raise_parse_error('Error in macro(Undefined command. "\dummy").', "", '\C')
|
440
|
-
lambda{smml('\C', false, ps)}.should raise_parse_error('Error in macro(Undefined command. "\dummy").', "", '\C')
|
441
|
-
|
442
|
-
lambda{smml('\begin{E}\end{E}', false, ps)}.should raise_parse_error('Error in macro(Undefined command. "\dummy").', '', '\begin{E}\end{E}')
|
443
|
-
lambda{smml('\begin{E}\end{E}', false, ps)}.should raise_parse_error('Error in macro(Undefined command. "\dummy").', "", '\begin{E}\end{E}')
|
444
|
-
end
|
445
|
-
|
446
|
-
it "can be used with macro with option" do
|
447
|
-
macro = <<'EOS'
|
448
|
-
\newcommand{\opt}[1][x]{#1}
|
449
|
-
\newcommand{\optparam}[2][]{#1#2}
|
450
|
-
\newenvironment{newenv}[1][x]{#1}{#1}
|
451
|
-
\newenvironment{optenv}[2][]{#1}{#2}
|
452
|
-
EOS
|
453
|
-
|
454
|
-
p = new_parser
|
455
|
-
p.macro.parse(macro)
|
456
|
-
|
457
|
-
smml('\opt a', false, p).should == "<mi>x</mi><mi>a</mi>"
|
458
|
-
smml('\opt[0] a', false, p).should == "<mn>0</mn><mi>a</mi>"
|
459
|
-
smml('\optparam a', false, p).should == "<mi>a</mi>"
|
460
|
-
smml('\optparam[0] a', false, p).should == "<mn>0</mn><mi>a</mi>"
|
461
|
-
|
462
|
-
smml('\begin{newenv}a\end{newenv}', false, p).should == "<mi>x</mi><mi>a</mi><mi>x</mi>"
|
463
|
-
smml('\begin{newenv}[0]a\end{newenv}', false, p).should == "<mn>0</mn><mi>a</mi><mn>0</mn>"
|
464
|
-
smml('\begin{optenv}0a\end{optenv}', false, p).should == "<mi>a</mi><mn>0</mn>"
|
465
|
-
smml('\begin{optenv}[0]1a\end{optenv}', false, p).should == "<mn>0</mn><mi>a</mi><mn>1</mn>"
|
466
|
-
end
|
467
|
-
|
468
|
-
it "should parse matrix environment" do
|
469
|
-
smml('\begin{matrix}&&\\\\&\end{matrix}').should == "<mtable><mtr><mtd /><mtd /><mtd /></mtr><mtr><mtd /><mtd /></mtr></mtable>"
|
470
|
-
lambda{smml('\begin{matrix}&&\\\\&\end{mat}')}.should raise_parse_error("Environment mismatched.", '\begin{matrix}&&\\\\&\end', "{mat}")
|
471
|
-
lambda{smml('\begin{matrix}&&\\\\&')}.should raise_parse_error("Matching \\end not exist.", '\begin{matrix}&&\\\\&', '')
|
472
|
-
smml('\begin{matrix}\begin{matrix}a&b\\\\c&d\end{matrix}&1\\\\0&1\\\\\end{matrix}').should == "<mtable><mtr><mtd><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></mtd><mtd><mn>1</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable>"
|
473
|
-
smml('\begin{matrix}\end{matrix}').should == "<mtable />"
|
474
|
-
smml('\begin{matrix}\hline a\\\\b\\\\\hline\end{matrix}').should == "<mtable rowlines='solid none solid'><mtr /><mtr><mtd><mi>a</mi></mtd></mtr><mtr><mtd><mi>b</mi></mtd></mtr><mtr /></mtable>"
|
475
|
-
|
476
|
-
smml('\begin{smallmatrix}\end{smallmatrix}').should == "<mtable />"
|
477
|
-
math_ml('\begin{pmatrix}\end{pmatrix}')[0].should =~ EimXML::Element.new(:mfenced, :open=>"(", :close=>")")
|
478
|
-
math_ml('\begin{bmatrix}\end{bmatrix}')[0].should =~ EimXML::Element.new(:mfenced, :open=>"[", :close=>"]")
|
479
|
-
math_ml('\begin{Bmatrix}\end{Bmatrix}')[0].should =~ EimXML::Element.new(:mfenced, :open=>"{", :close=>"}")
|
480
|
-
math_ml('\begin{vmatrix}\end{vmatrix}')[0].should =~ EimXML::Element.new(:mfenced, :open=>"|", :close=>"|")
|
481
|
-
math_ml('\begin{Vmatrix}\end{Vmatrix}')[0].should =~ EimXML::Element.new(:mfenced, :open=>EimXML::PCString.new("∥", true), :close=>EimXML::PCString.new("∥", true))
|
482
|
-
end
|
483
|
-
|
484
|
-
it "can be used in safe mode" do
|
485
|
-
Thread.start do
|
486
|
-
$SAFE=1
|
487
|
-
$SAFE.should == 1
|
488
|
-
lambda{smml('\alpha'.taint)}.should_not raise_error
|
489
|
-
end.join
|
490
|
-
|
491
|
-
$SAFE.should == 0
|
492
|
-
end
|
493
|
-
|
494
|
-
it "should parse symbols" do
|
495
|
-
smml('\precneqq').should == "<mo stretchy='false'>⪵</mo>"
|
496
|
-
end
|
497
|
-
end
|
498
|
-
|
499
|
-
context ".new should accept symbol table" do
|
500
|
-
it "character reference" do
|
501
|
-
@parser = MathML::LaTeX::Parser.new(:symbol=>MathML::Symbol::CharacterReference)
|
502
|
-
smml('\alpha').should == "<mi>α</mi>"
|
503
|
-
smml('\mathbb{abcABC}').should == "<mrow><mrow><mi>𝕒</mi><mi>𝕓</mi><mi>𝕔</mi><mi>𝔸</mi><mi>𝔹</mi><mi>ℂ</mi></mrow></mrow>"
|
504
|
-
smml('\mathscr{abcABC}').should == "<mrow><mrow><mi>𝒶</mi><mi>𝒷</mi><mi>𝒸</mi><mi>𝒜</mi><mi>ℬ</mi><mi>𝒞</mi></mrow></mrow>"
|
505
|
-
smml('\mathfrak{abcABC}').should == "<mrow><mrow><mi>𝔞</mi><mi>𝔟</mi><mi>𝔠</mi><mi>𝔄</mi><mi>𝔅</mi><mi>ℭ</mi></mrow></mrow>"
|
506
|
-
end
|
507
|
-
|
508
|
-
it "utf8" do
|
509
|
-
@parser = MathML::LaTeX::Parser.new(:symbol=>MathML::Symbol::UTF8)
|
510
|
-
smml('\alpha').should == "<mi>α</mi>"
|
511
|
-
smml('\mathbb{abcABC}').should == "<mrow><mrow><mi>𝕒</mi><mi>𝕓</mi><mi>𝕔</mi><mi>𝔸</mi><mi>𝔹</mi><mi>ℂ</mi></mrow></mrow>"
|
512
|
-
smml('\mathscr{abcABC}').should == "<mrow><mrow><mi>𝒶</mi><mi>𝒷</mi><mi>𝒸</mi><mi>𝒜</mi><mi>ℬ</mi><mi>𝒞</mi></mrow></mrow>"
|
513
|
-
smml('\mathfrak{abcABC}').should == "<mrow><mrow><mi>𝔞</mi><mi>𝔟</mi><mi>𝔠</mi><mi>𝔄</mi><mi>𝔅</mi><mi>ℭ</mi></mrow></mrow>"
|
514
|
-
end
|
515
|
-
end
|
516
|
-
|
517
|
-
context "#symbol_table" do
|
518
|
-
it "should return when .new was given name of symbol-module" do
|
519
|
-
ps = MathML::LaTeX::Parser
|
520
|
-
symbol = MathML::Symbol
|
521
|
-
|
522
|
-
ps.new(:symbol=>symbol::UTF8).symbol_table.should == symbol::UTF8
|
523
|
-
ps.new(:symbol=>symbol::EntityReference).symbol_table.should == symbol::EntityReference
|
524
|
-
ps.new(:symbol=>symbol::CharacterReference).symbol_table.should == symbol::CharacterReference
|
525
|
-
|
526
|
-
ps.new(:symbol=>:utf8).symbol_table.should == symbol::UTF8
|
527
|
-
ps.new(:symbol=>:entity).symbol_table.should == symbol::EntityReference
|
528
|
-
ps.new(:symbol=>:character).symbol_table.should == symbol::CharacterReference
|
529
|
-
|
530
|
-
ps.new.symbol_table.should == symbol::EntityReference
|
531
|
-
ps.new(:symbol=>nil).symbol_table.should == symbol::EntityReference
|
532
|
-
end
|
533
|
-
|
534
|
-
context "should return default symbol module" do
|
535
|
-
before do
|
536
|
-
@loaded_features = $LOADED_FEATURES.dup
|
537
|
-
$LOADED_FEATURES.delete_if{|i| i=~/math_ml/}
|
538
|
-
if ::Object.const_defined?(:MathML)
|
539
|
-
@MathML = ::Object.const_get(:MathML)
|
540
|
-
::Object.module_eval{remove_const(:MathML)}
|
541
|
-
end
|
542
|
-
end
|
543
|
-
|
544
|
-
after do
|
545
|
-
$LOADED_FEATURES.clear
|
546
|
-
$LOADED_FEATURES.push(@loaded_features.shift) until @loaded_features.empty?
|
547
|
-
if @MathML
|
548
|
-
::Object.module_eval{remove_const(:MathML)}
|
549
|
-
::Object.const_set(:MathML, @MathML)
|
550
|
-
end
|
551
|
-
end
|
552
|
-
|
553
|
-
it "character entity reference version by default" do
|
554
|
-
require("math_ml").should be_true
|
555
|
-
MathML::LaTeX::Parser.new.symbol_table.should == MathML::Symbol::EntityReference
|
556
|
-
end
|
557
|
-
|
558
|
-
describe "character entity reference version when set by requiring" do
|
559
|
-
it do
|
560
|
-
require("math_ml/symbol/entity_reference").should be_true
|
561
|
-
MathML::LaTeX::Parser.new.symbol_table.should == MathML::Symbol::EntityReference
|
562
|
-
end
|
563
|
-
end
|
564
|
-
|
565
|
-
describe "utf8 version when set by requiring" do
|
566
|
-
it do
|
567
|
-
require("math_ml/symbol/utf8").should be_true
|
568
|
-
MathML::LaTeX::Parser.new.symbol_table.should == MathML::Symbol::UTF8
|
569
|
-
end
|
570
|
-
end
|
571
|
-
|
572
|
-
describe "numeric character reference version when set by requiring" do
|
573
|
-
it do
|
574
|
-
require("math_ml/symbol/character_reference").should be_true
|
575
|
-
MathML::LaTeX::Parser.new.symbol_table.should == MathML::Symbol::CharacterReference
|
576
|
-
end
|
577
|
-
end
|
578
|
-
end
|
579
|
-
end
|
580
|
-
end
|