math_ml 0.14 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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'>&DoubleVerticalBar;</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>&prime;</mo></msup>"
111
- smml("a''").should == "<msup><mi>a</mi><mo>&prime;&prime;</mo></msup>"
112
- smml("a'''").should == "<msup><mi>a</mi><mo>&prime;&prime;&prime;</mo></msup>"
113
- smml("'").should == "<msup><none /><mo>&prime;</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>&prime;</mo><mi>b</mi></mrow></msup>"
118
- smml("a'''^b").should == "<msup><mi>a</mi><mrow><mo>&prime;&prime;&prime;</mo><mi>b</mi></mrow></msup>"
119
- smml("a'b").should == "<msup><mi>a</mi><mo>&prime;</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>&#x2032;</mo></msup>"
131
- smml("a'''").should == "<msup><mi>a</mi><mo>&#x2032;&#x2032;&#x2032;</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'>&sum;</mo><mi>a</mi><mi>b</mi></munderover>"
156
- smml('\sum_a^b').should == "<msubsup><mo stretchy='false'>&sum;</mo><mi>a</mi><mi>b</mi></msubsup>"
157
- smml('\sum_a', true).should == "<munder><mo stretchy='false'>&sum;</mo><mi>a</mi></munder>"
158
- smml('\sum^a', true).should == "<mover><mo stretchy='false'>&sum;</mo><mi>a</mi></mover>"
159
- smml('\sum_a').should == "<msub><mo stretchy='false'>&sum;</mo><mi>a</mi></msub>"
160
- smml('\sum^a').should == "<msup><mo stretchy='false'>&sum;</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>&bopf;</mi><mi>&copf;</mi></mrow></mrow><mi>d</mi>"
179
- smml('a \mathscr{b c} d').should == "<mi>a</mi><mrow><mrow><mi>&bscr;</mi><mi>&cscr;</mi></mrow></mrow><mi>d</mi>"
180
- smml('a \mathfrak{b c} d').should == "<mi>a</mi><mrow><mrow><mi>&bfr;</mi><mi>&cfr;</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>&lt;&gt;&apos;&quot;&amp;</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("&lfloor;", true), :close=>EimXML::PCString.new("&rfloor;", 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("&sum;", 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("&sum;", 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("&DoubleVerticalBar;", true), :close=>EimXML::PCString.new("&DoubleVerticalBar;", 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>&circ;</mo></mover>"
343
- smml('\hat12').should == "<mover><mn>1</mn><mo>&circ;</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>&macr;</mo></munder>"
349
- smml('\underline12').should == "<munder><mn>1</mn><mo>&macr;</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'>&rightarrow;</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>&therefore;</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>&therefore;</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>&Ropf;</mi></mrow>"
412
- smml('\begin{BB}\end{BB}', false, p).should == "<mrow><mi>&Aopf;</mi></mrow><mrow><mi>&Bopf;</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("&DoubleVerticalBar;", true), :close=>EimXML::PCString.new("&DoubleVerticalBar;", 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'>&#x2ab5;</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>&#x3b1;</mi>"
503
- smml('\mathbb{abcABC}').should == "<mrow><mrow><mi>&#x1d552;</mi><mi>&#x1d553;</mi><mi>&#x1d554;</mi><mi>&#x1d538;</mi><mi>&#x1d539;</mi><mi>&#x2102;</mi></mrow></mrow>"
504
- smml('\mathscr{abcABC}').should == "<mrow><mrow><mi>&#x1d4b6;</mi><mi>&#x1d4b7;</mi><mi>&#x1d4b8;</mi><mi>&#x1d49c;</mi><mi>&#x212c;</mi><mi>&#x1d49e;</mi></mrow></mrow>"
505
- smml('\mathfrak{abcABC}').should == "<mrow><mrow><mi>&#x1d51e;</mi><mi>&#x1d51f;</mi><mi>&#x1d520;</mi><mi>&#x1d504;</mi><mi>&#x1d505;</mi><mi>&#x212d;</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