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