math_ml 0.14 → 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,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