mathml 0.8.1 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,202 @@
1
+ require "math_ml"
2
+
3
+ describe MathML::LaTeX::Scanner do
4
+ def new_scanner(src)
5
+ MathML::LaTeX::Scanner.new(src)
6
+ end
7
+
8
+ it "#done, #rest" do
9
+ s = new_scanner("0123")
10
+ s.pos = 2
11
+ s.done.should == "01"
12
+ s.rest.should == "23"
13
+ end
14
+
15
+ it "#_check" do
16
+ s = new_scanner(" ")
17
+ s._check(/\s/).should == " "
18
+ s.pos.should == 0
19
+ end
20
+
21
+ it "#_scan" do
22
+ s = new_scanner(" ")
23
+ s._scan(/\s/).should == " "
24
+ s.pos.should == 1
25
+ end
26
+
27
+ it "#check" do
28
+ s = new_scanner(" a")
29
+ s.check(/a/).should == "a"
30
+ s.pos.should == 0
31
+ end
32
+
33
+ it "#scan, #reset" do
34
+ s = new_scanner(" a")
35
+ s.scan(/a/).should == "a"
36
+ s.pos.should == 2
37
+
38
+ s.reset
39
+ s.pos.should == 0
40
+ s.scan(/b/).should be_nil
41
+ s.pos.should == 0
42
+
43
+ s = new_scanner(" %comment\na")
44
+ s.scan(/a/).should == "a"
45
+ s.pos.should == 11
46
+
47
+ s.reset
48
+ s.scan(/b/).should be_nil
49
+ s.pos.should == 0
50
+ end
51
+
52
+ it "#eos" do
53
+ new_scanner("").should be_eos
54
+ new_scanner(" ").should be_eos
55
+ new_scanner(" %test\n%test").should be_eos
56
+ new_scanner(" a").should_not be_eos
57
+ new_scanner(" \\command").should_not be_eos
58
+ end
59
+
60
+ it "#check_command" do
61
+ '\t'.should == '\\t'
62
+
63
+ new_scanner("test").check_command.should be_nil
64
+ s = new_scanner(' \test')
65
+ s.check_command.should == '\\test'
66
+ s[1].should == "test"
67
+
68
+ new_scanner(' \test next').check_command.should == '\test'
69
+ new_scanner(' \test_a').check_command.should == '\test'
70
+ end
71
+
72
+ it "#scan_command" do
73
+ new_scanner("test").scan_command.should be_nil
74
+
75
+ s = new_scanner(' \test')
76
+ s.scan_command.should == '\test'
77
+ s[1].should == "test"
78
+ s.pos.should == 6
79
+
80
+ s = new_scanner(' \test rest')
81
+ s.scan_command.should == '\test'
82
+ s.pos.should == 6
83
+
84
+ s = new_scanner(' \test_a')
85
+ s.scan_command.should == '\test'
86
+ s.pos.should == 6
87
+
88
+ s = new_scanner(' \_test')
89
+ s.check_command.should == '\_'
90
+ s.scan_command.should == '\_'
91
+ s.rest.should == "test"
92
+ end
93
+
94
+ it "#scan_block" do
95
+ new_scanner(" a").scan_block.should == nil
96
+ new_scanner(" a").check_block.should == nil
97
+
98
+ i = " {{}{}{{}{}}} "
99
+ e = "{#{i}}"
100
+ s = new_scanner(" #{e} test")
101
+ s.check_block.should == e
102
+ s.matched.should == e
103
+ s[1].should == i
104
+ s.scan_block.should == e
105
+ s.matched.should == e
106
+ s[1].should == i
107
+ s.rest.should == " test"
108
+
109
+ new_scanner(' \command test').scan_block.should == nil
110
+ new_scanner(' \command test').check_block.should == nil
111
+
112
+ new_scanner("").scan_block.should == nil
113
+ new_scanner("").check_block.should == nil
114
+
115
+ new_scanner(" ").scan_block.should == nil
116
+ new_scanner(" ").check_block.should == nil
117
+
118
+ s = new_scanner("{test")
119
+ lambda{s.scan_block}.should raise_error(MathML::LaTeX::BlockNotClosed)
120
+ end
121
+
122
+ it "#scan_any" do
123
+ s0 = " %comment\n "
124
+ s1 = "{}"
125
+ s = new_scanner(s0+s1)
126
+ s.scan_any.should == s1
127
+ s.reset
128
+ s.scan_any(true).should == s0+s1
129
+ s.matched.should == s1
130
+
131
+ s1 = '\command'
132
+ s = new_scanner(s0+s1)
133
+ s.scan_any.should == s1
134
+ s.reset
135
+ s.scan_any(true).should == s0+s1
136
+
137
+ s1 = 'a'
138
+ s = new_scanner(s0+s1)
139
+ s.scan_any.should == s1
140
+ s.reset
141
+ s.scan_any(true).should == s0+s1
142
+
143
+ s = new_scanner(" ")
144
+ s.scan_any.should == nil
145
+ s.reset
146
+ s.scan_any(true).should == " "
147
+
148
+ s = new_scanner('\begin{env}test\end{env}')
149
+ s.scan_any.should == '\begin'
150
+ end
151
+
152
+ it "#peek_command" do
153
+ new_scanner(' \test').peek_command.should == "test"
154
+ new_scanner("").peek_command.should == nil
155
+ new_scanner(" ").peek_command.should == nil
156
+ new_scanner(" a").peek_command.should == nil
157
+ end
158
+
159
+ it "#scan_option" do
160
+ s = new_scanner(" []")
161
+ s.scan_option.should == "[]"
162
+ s[1].should == ""
163
+ s.pos.should == 3
164
+
165
+ s = new_scanner(" [ opt ]")
166
+ s.scan_option.should == "[ opt ]"
167
+ s[1].should == " opt "
168
+ s.pos.should == 8
169
+
170
+ s = new_scanner(" [[]]")
171
+ s.scan_option.should == "[[]"
172
+ s[1].should == "["
173
+
174
+ s = new_scanner(" [{[]}]")
175
+ s.scan_option.should == "[{[]}]"
176
+ s[1].should == "{[]}"
177
+
178
+ lambda{new_scanner("[").scan_option}.should raise_error(MathML::LaTeX::OptionNotClosed)
179
+ end
180
+
181
+ it "#check_option" do
182
+ s = new_scanner(" []")
183
+ s.check_option.should == "[]"
184
+ s[1].should == ""
185
+ s.pos.should == 0
186
+
187
+ s = new_scanner(" [ opt ]")
188
+ s.check_option.should == "[ opt ]"
189
+ s[1].should == " opt "
190
+ s.pos.should == 0
191
+
192
+ s = new_scanner(" [[]]")
193
+ s.check_option.should == "[[]"
194
+ s[1].should == "["
195
+
196
+ s = new_scanner(" [{[]}]")
197
+ s.check_option.should == "[{[]}]"
198
+ s[1].should == "{[]}"
199
+
200
+ lambda{new_scanner("[").check_option}.should raise_error(MathML::LaTeX::OptionNotClosed)
201
+ end
202
+ end
@@ -0,0 +1,29 @@
1
+ require "math_ml/string"
2
+
3
+ describe MathML::String do
4
+ it ".mathml_latex_parser" do
5
+ MathML::String.mathml_latex_parser.should be_kind_of(MathML::LaTeX::Parser)
6
+ mlp = MathML::LaTeX::Parser.new
7
+ MathML::String.mathml_latex_parser = mlp
8
+ MathML::String.mathml_latex_parser.should equal(mlp)
9
+ lambda{MathML::String.mathml_latex_parser=String}.should raise_error(TypeError)
10
+ MathML::String.mathml_latex_parser.should equal(mlp)
11
+
12
+ MathML::String.mathml_latex_parser = nil
13
+ MathML::String.mathml_latex_parser.should be_kind_of(MathML::LaTeX::Parser)
14
+ MathML::String.mathml_latex_parser.should_not equal(mlp)
15
+ end
16
+ end
17
+
18
+ describe String do
19
+ it "#parse" do
20
+ mlp = MathML::LaTeX::Parser.new
21
+ "".to_mathml.to_s.should == mlp.parse("").to_s
22
+ "".to_mathml(true).to_s.should == mlp.parse("", true).to_s
23
+
24
+ MathML::String.mathml_latex_parser.macro.parse(<<'EOT')
25
+ \newcommand{\test}{x}
26
+ EOT
27
+ '\test'.to_mathml.to_s.should == mlp.parse("x").to_s
28
+ end
29
+ end
@@ -0,0 +1,700 @@
1
+ require "math_ml/util"
2
+ require "eim_xml/parser"
3
+
4
+ describe MathML::Util do
5
+ include MathML::Util
6
+
7
+ it "#escapeXML" do
8
+ escapeXML("<>&\"'").should == "&lt;&gt;&amp;&quot;&apos;"
9
+ escapeXML("\n").should == "\n"
10
+ escapeXML("\n", true).should == "<br />\n"
11
+ end
12
+
13
+ it ".escapeXML" do
14
+ MathML::Util.escapeXML("<>&\"'").should == "&lt;&gt;&amp;&quot;&apos;"
15
+ MathML::Util.escapeXML("\n").should == "\n"
16
+ MathML::Util.escapeXML("\n", true).should == "<br />\n"
17
+ end
18
+
19
+ it "#collect_regexp" do
20
+ collect_regexp([/a/, /b/, /c/]).should == /#{/a/}|#{/b/}|#{/c/}/
21
+ collect_regexp([[/a/, /b/, /c/]]).should == /#{/a/}|#{/b/}|#{/c/}/
22
+ collect_regexp([]).should == /(?!)/
23
+ collect_regexp(/a/).should == /#{/a/}/
24
+ end
25
+
26
+ it ".collect_regexp" do
27
+ MathML::Util.collect_regexp([/a/, /b/, /c/]).should == /#{/a/}|#{/b/}|#{/c/}/
28
+ MathML::Util.collect_regexp([[/a/, /b/, /c/]]).should == /#{/a/}|#{/b/}|#{/c/}/
29
+ MathML::Util.collect_regexp([]).should == /(?!)/
30
+ MathML::Util.collect_regexp(/a/).should == /#{/a/}/
31
+
32
+ MathML::Util.collect_regexp([nil, /a/, "text", /b/]).should == /#{/a/}|#{/b/}/
33
+
34
+ MathML::Util.collect_regexp([nil, [/a/, [/b/, /c/]]]).should == /#{/a/}|#{/b/}|#{/c/}/
35
+ end
36
+
37
+ it "::INVALID_RE" do
38
+ MathML::Util::INVALID_RE.should == /(?!)/
39
+ end
40
+ end
41
+
42
+ describe MathML::Util::MathData do
43
+ it "#<< and #update" do
44
+ m = MathML::Util::MathData.new
45
+ m.math_list << "ml1"
46
+ m.msrc_list << "sl1"
47
+ m.dmath_list << "dml1"
48
+ m.dsrc_list << "dsl1"
49
+ m.escape_list << "el1"
50
+ m.esrc_list << "es1"
51
+ m.user_list << "ul1"
52
+ m.usrc_list << "usl1"
53
+ m.math_list.should == ["ml1"]
54
+ m.msrc_list.should == ["sl1"]
55
+ m.dmath_list.should == ["dml1"]
56
+ m.dsrc_list.should == ["dsl1"]
57
+ m.escape_list.should == ["el1"]
58
+ m.esrc_list.should == ["es1"]
59
+ m.user_list.should == ["ul1"]
60
+ m.usrc_list.should == ["usl1"]
61
+
62
+ m2 = MathML::Util::MathData.new
63
+ m2.math_list << "ml2"
64
+ m2.msrc_list << "sl2"
65
+ m2.dmath_list << "dml2"
66
+ m2.dsrc_list << "dsl2"
67
+ m2.escape_list << "el2"
68
+ m2.esrc_list << "es2"
69
+ m2.user_list << "ul2"
70
+ m2.usrc_list << "usl2"
71
+
72
+ m.update(m2)
73
+
74
+ m.math_list.should == ["ml1", "ml2"]
75
+ m.msrc_list.should == ["sl1", "sl2"]
76
+ m.dmath_list.should == ["dml1", "dml2"]
77
+ m.dsrc_list.should == ["dsl1", "dsl2"]
78
+ m.escape_list.should == ["el1", "el2"]
79
+ m.esrc_list.should == ["es1", "es2"]
80
+ m.user_list.should == ["ul1", "ul2"]
81
+ m.usrc_list.should == ["usl1", "usl2"]
82
+ end
83
+ end
84
+
85
+ describe MathML::Util::SimpleLaTeX do
86
+ def strip_math(s)
87
+ s.gsub(/>\s*/, ">").gsub(/\s*</, "<")[/<math.*?>(.*)<\/math>/m, 1]
88
+ end
89
+
90
+ def sma(a) # Stripped Mathml Array
91
+ r = []
92
+ a.each do |i|
93
+ r << strip_math(i.to_s)
94
+ end
95
+ r
96
+ end
97
+
98
+ def simplify_math(src)
99
+ attr = []
100
+ r = src.gsub(/<math(\s+[^>]+)>/) do |m|
101
+ attr << $1.scan(/\s+[^\s]+/).map{|i| i[/\A\s*(.*)/, 1]}.sort
102
+ "<math>"
103
+ end
104
+ attr.unshift(r)
105
+ end
106
+
107
+ def assert_data(src,
108
+ expected_math, expected_src,
109
+ expected_dmath, expected_dsrc,
110
+ expected_escaped, expected_esrc,
111
+ expected_encoded, expected_decoded,
112
+ simple_latex = MathML::Util::SimpleLaTeX)
113
+ encoded, data = simple_latex.encode(src)
114
+
115
+ data.math_list.each do |i|
116
+ i.attributes[:display].should == "inline"
117
+ end
118
+ data.dmath_list.each do |i|
119
+ i.attributes[:display].should == "block"
120
+ end
121
+
122
+ sma(data.math_list).should == expected_math
123
+ data.msrc_list.should == expected_src
124
+ sma(data.dmath_list).should == expected_dmath
125
+ data.dsrc_list.should == expected_dsrc
126
+ data.escape_list.should == expected_escaped
127
+ data.esrc_list.should == expected_esrc
128
+ encoded.should == expected_encoded
129
+ target = simple_latex.decode(encoded, data)
130
+ simplify_math(target).should == simplify_math(expected_decoded)
131
+ end
132
+
133
+ it "(spec for helper)" do
134
+ simplify_math("<math c='d' a='b'>..</math><math g='h' e='f'></math>").should == ["<math>..</math><math></math>", %w[a='b' c='d'], %w[e='f' g='h']]
135
+ end
136
+
137
+ it "should parse math environment" do
138
+ assert_data("a\n$\nb\n$\nc\\(\nd\n\\)e",
139
+ ["<mi>b</mi>", "<mi>d</mi>"],
140
+ ["$\nb\n$", "\\(\nd\n\\)"],
141
+ [], [], [], [],
142
+ "a\n\001m0\001\nc\001m1\001e",
143
+ "a\n<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>\nc<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>d</mi></math>e")
144
+
145
+ assert_data('$\\$$',
146
+ ["<mo>$</mo>"],
147
+ ['$\$$'], [], [], [], [], "\001m0\001",
148
+ "<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mo>$</mo></math>")
149
+ end
150
+
151
+ it "should parse dmath environment" do
152
+ assert_data("a\n$$\nb\n$$\nc\\[\nd\n\\]e",
153
+ [], [],
154
+ ["<mi>b</mi>", "<mi>d</mi>"],
155
+ ["$$\nb\n$$", "\\[\nd\n\\]"],
156
+ [], [],
157
+ "a\n\001d0\001\nc\001d1\001e",
158
+ "a\n<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>\nc<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>d</mi></math>e")
159
+ end
160
+
161
+ it "should parse math and dmath environment" do
162
+ assert_data('a$b$c$$d$$e\(f\)g\[h\]i',
163
+ ["<mi>b</mi>", "<mi>f</mi>"],
164
+ ["$b$", '\(f\)'],
165
+ ["<mi>d</mi>", "<mi>h</mi>"],
166
+ ["$$d$$", '\[h\]'],
167
+ [], [],
168
+ "a\001m0\001c\001d0\001e\001m1\001g\001d1\001i",
169
+ "a<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>c<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>d</mi></math>e<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>f</mi></math>g<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>h</mi></math>i")
170
+ end
171
+
172
+ it "should parse escaping" do
173
+ assert_data('a\bc\d\e', [], [], [], [], ['b', 'd', 'e'], ['\b', '\d', '\e'], "a\001e0\001c\001e1\001\001e2\001", 'abcde')
174
+ assert_data('\$a$$b$$', [], [], ["<mi>b</mi>"], ["$$b$$"], [%[$]], ['\$'], "\001e0\001a\001d0\001",
175
+ "$a<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>")
176
+
177
+ assert_data("\\<\\\n", [], [], [], [], ["&lt;", "<br />\n"], ["\\<", "\\\n"], "\001e0\001\001e1\001", "&lt;<br />\n")
178
+ end
179
+
180
+ it "should accept through_list option" do
181
+ s = MathML::Util::SimpleLaTeX.new(:through_list=>[/\{\{.*\}\}/, /\(.*\)/])
182
+ assert_data("{{$a$}}($b$)", [], [], [], [], [], [], "{{$a$}}($b$)", "{{$a$}}($b$)", s)
183
+
184
+ s = MathML::Util::SimpleLaTeX.new(:through_list=>/\{.*\}/)
185
+ assert_data("{$a$}", [], [], [], [], [], [], "{$a$}", "{$a$}", s)
186
+ end
187
+
188
+ it "should accept parser option" do
189
+ ps = MathML::LaTeX::Parser.new
190
+ ps.macro.parse('\newcommand{\test}{t}')
191
+ s = MathML::Util::SimpleLaTeX.new(:parser=>ps)
192
+ assert_data('$\test$', ["<mi>t</mi>"], ['$\test$'], [], [], [], [], "\001m0\001",
193
+ "<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>t</mi></math>", s)
194
+ end
195
+
196
+ it "should accept escape option" do
197
+ s = MathML::Util::SimpleLaTeX.new(:escape_list=>[/\/(.)/, /(\^.)/])
198
+ assert_data('\$a$', ["<mi>a</mi>"], ['$a$'], [], [], [], [], "\\\001m0\001",
199
+ "\\<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>a</mi></math>", s)
200
+ assert_data(%[/$a/$], [], [], [], [], [%[$], %[$]], [%[/$], %[/$]], "\001e0\001a\001e1\001", "$a$", s)
201
+ assert_data('^\(a^\)', [], [], [], [], ['^\\', '^\\'], ['^\\', '^\\'], "\001e0\001(a\001e1\001)", '^\(a^\)', s)
202
+
203
+ s = MathML::Util::SimpleLaTeX.new(:escape_list=>/_(.)/)
204
+ assert_data("_$a$", [], [], [], [], ['$'], ["_$"], %[\001e0\001a$], '$a$', s)
205
+ end
206
+
207
+ it "should accept delimiter option" do
208
+ s = MathML::Util::SimpleLaTeX.new(:delimiter=>"\002\003")
209
+ assert_data("a$b$c", ["<mi>b</mi>"], ["$b$"], [], [], [], [], "a\002\003m0\002\003c",
210
+ "a<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>c", s)
211
+
212
+ s = MathML::Util::SimpleLaTeX.new(:delimiter=>%[$])
213
+ assert_data("a$b$c", ["<mi>b</mi>"], ["$b$"], [], [], [], [], "a$m0$c",
214
+ "a<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>c", s)
215
+ end
216
+
217
+ it "should accept (d)math_env_list option" do
218
+ s = MathML::Util::SimpleLaTeX.new(:math_env_list=>/%(.*?)%/, :dmath_env_list=>/\[(.*?)\]/)
219
+ assert_data("a$b$c%d%e[f]", ["<mi>d</mi>"], ["%d%"], ["<mi>f</mi>"], ["[f]"], [], [],
220
+ "a$b$c\001m0\001e\001d0\001",
221
+ "a$b$c<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>d</mi></math>e<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>f</mi></math>", s)
222
+
223
+ s = MathML::Util::SimpleLaTeX.new(:math_env_list=>[/!(.*?)!/, /"(.*)"/], :dmath_env_list=>[/\#(.*)\#/, /&(.*)&/])
224
+ assert_data('a!b!c"d"e#f#g&h&i',
225
+ ["<mi>b</mi>", "<mi>d</mi>"], ['!b!', '"d"'],
226
+ ["<mi>f</mi>", "<mi>h</mi>"], ['#f#', '&h&'],
227
+ [], [],
228
+ "a\001m0\001c\001m1\001e\001d0\001g\001d1\001i",
229
+ "a<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>c<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>d</mi></math>e<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>f</mi></math>g<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>h</mi></math>i", s)
230
+ end
231
+
232
+ it "should accept throu_list option" do
233
+ s = MathML::Util::SimpleLaTeX.new(:through_list=>[/<%=.*?%>/m, /\(\(.*?\)\)/m])
234
+ assert_data("<%=$a$%>(($b$))", [], [], [], [], [], [], "<%=$a$%>(($b$))", "<%=$a$%>(($b$))", s)
235
+
236
+ s = MathML::Util::SimpleLaTeX.new(:through_list=>/<%=.*?%>/)
237
+ assert_data("<%=$a$%>", [], [], [], [], [], [], "<%=$a$%>", "<%=$a$%>", s)
238
+ end
239
+
240
+ it "should accept through_list=>[]" do
241
+ s = MathML::Util::SimpleLaTeX.new(:through_list=>[])
242
+ assert_data("$a$", ["<mi>a</mi>"], [%[$a$]], [], [], [], [], "\001m0\001",
243
+ "<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>a</mi></math>", s)
244
+ end
245
+
246
+ it "should accept without_parse option" do
247
+ s = MathML::Util::SimpleLaTeX.new(:without_parse=>true)
248
+ encoded, data = s.encode("$a$ $$b$$")
249
+ data.math_list.should == []
250
+ data.msrc_list.should == ["$a$"]
251
+ data.dmath_list.should == []
252
+ data.dsrc_list.should == ["$$b$$"]
253
+ encoded.should == "\001m0\001 \001d0\001"
254
+
255
+ s.parse(data)
256
+ data.math_list[0].attributes[:display].should == "inline"
257
+ data.dmath_list[0].attributes[:display].should == "block"
258
+ sma(data.math_list).should == ["<mi>a</mi>"]
259
+ sma(data.dmath_list).should == ["<mi>b</mi>"]
260
+ simplify_math(s.decode(encoded, data)).should == simplify_math("<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>a</mi></math> <math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>")
261
+ end
262
+
263
+ it "#set_encode_proc" do
264
+ s = MathML::Util::SimpleLaTeX.new
265
+ s.set_encode_proc(/\{\{/) do |scanner|
266
+ if scanner.scan(/\{\{(.*?)\}\}/m)
267
+ "<%=#{scanner[1]}%>"
268
+ end
269
+ end
270
+ src = "{{$a$}}{{$$b$$}}{{"
271
+ assert_data(src, [], [], [], [], [], [], "\001u0\001\001u1\001{{", "<%=$a$%><%=$$b$$%>{{", s)
272
+ encoded, data = s.encode(src)
273
+ data.user_list.should == ["<%=$a$%>", "<%=$$b$$%>"]
274
+ data.usrc_list.should == ["{{$a$}}", "{{$$b$$}}"]
275
+
276
+ s.set_encode_proc(/\{\{/) do |scanner|
277
+ end
278
+ src = "{{a"
279
+ assert_data(src, [], [], [], [], [], [], "{{a", "{{a", s)
280
+ encoded, data = s.encode(src)
281
+ data.user_list.should == []
282
+ data.usrc_list.should == []
283
+ end
284
+
285
+ it "#set_encode_proc with arrayed regexp" do
286
+ s = MathML::Util::SimpleLaTeX.new
287
+ src = "{{a}}((b)){{(("
288
+ encoded, data = s.encode(src, /\{\{/, /\(\(/) do |scanner|
289
+ case
290
+ when scanner.scan(/\{\{.*?\}\}/)
291
+ "brace"
292
+ when scanner.scan(/\(\(.*?\)\)/)
293
+ "parenthesis"
294
+ end
295
+ end
296
+ encoded.should == "\001u0\001\001u1\001{{(("
297
+ s.decode(encoded, data).should == "braceparenthesis{{(("
298
+
299
+ s.set_encode_proc(/\{\{/, /\(\(/) do |scanner|
300
+ case
301
+ when scanner.scan(/\{\{.*?\}\}/)
302
+ "brace"
303
+ when scanner.scan(/\(\(.*?\)\)/)
304
+ "parenthesis"
305
+ end
306
+ end
307
+ encoded, data = s.encode(src)
308
+ encoded.should == "\001u0\001\001u1\001{{(("
309
+ s.decode(encoded, data).should == "braceparenthesis{{(("
310
+ end
311
+
312
+ it "#encode accept block" do
313
+ s = MathML::Util::SimpleLaTeX.new
314
+ src = "{{$a$}}{{$$b$$}}{{"
315
+ encoded, data = s.encode(src, /\{\{/) do |scanner|
316
+ if scanner.scan(/\{\{(.*?)\}\}/m)
317
+ "<%=#{scanner[1]}%>"
318
+ end
319
+ end
320
+ data.math_list.should == []
321
+ data.dmath_list.should == []
322
+ data.escape_list.should == []
323
+ encoded.should == "\001u0\001\001u1\001{{"
324
+ s.decode(encoded, data).should == "<%=$a$%><%=$$b$$%>{{"
325
+ end
326
+
327
+ it "#encode should accept block with #set_encode_proc" do
328
+ s = MathML::Util::SimpleLaTeX.new
329
+ src = "{{$a$}}{{$$b$$}}{{"
330
+ s.set_encode_proc(/\{\{/) do |scanner|
331
+ if scanner.scan(/\{\{(.*?)\}\}/m)
332
+ "<%=#{scanner[1]}%>"
333
+ end
334
+ end
335
+ encoded, data = s.encode(src, /\{\{/) do |scanner|
336
+ if scanner.scan(/\{\{(.*?)\}\}/m)
337
+ "<$=#{scanner[1]}$>"
338
+ end
339
+ end
340
+ data.math_list.should == []
341
+ data.dmath_list.should == []
342
+ data.escape_list.should == []
343
+ encoded.should == "\001u0\001\001u1\001{{"
344
+ s.decode(encoded, data).should == "<$=$a$$><$=$$b$$$>{{"
345
+ end
346
+
347
+ it "#unencode" do
348
+ src = "$\na\n$\n$$\nb\n$$"
349
+ s = MathML::Util::SimpleLaTeX.new
350
+ encoded, data = s.encode(src)
351
+ s.unencode(encoded, data).should == "$<br />\na<br />\n$\n$$<br />\nb<br />\n$$"
352
+
353
+ s = MathML::Util::SimpleLaTeX.new(:delimiter=>%[$])
354
+ e, d = s.encode("$a$")
355
+ s.unencode(e, d).should == "$a$"
356
+ end
357
+
358
+ it "#set_rescue_proc" do
359
+ src = '$a\test$ $$b\dummy$$'
360
+ s = MathML::Util::SimpleLaTeX.new
361
+ encoded, data = s.encode(src)
362
+ data.math_list[0].should == "<br />\nUndefined command.<br />\n<code>a<strong>\\test</strong></code><br />"
363
+ data.dmath_list[0].should == "<br />\nUndefined command.<br />\n<code>b<strong>\\dummy</strong></code><br />"
364
+
365
+ s.set_rescue_proc do |e|
366
+ e
367
+ end
368
+ encoded, data = s.encode(src)
369
+ data.math_list[0].should be_kind_of(MathML::LaTeX::ParseError)
370
+ data.math_list[0].done.should == "a"
371
+ data.dmath_list[0].should be_kind_of(MathML::LaTeX::ParseError)
372
+ data.dmath_list[0].done.should == "b"
373
+ end
374
+
375
+ it "#decode with block" do
376
+ s = MathML::Util::SimpleLaTeX.new
377
+ encoded, data = s.encode('$a$$b$$$c$$$$d$$\e\\\\')
378
+ r = s.decode(encoded, data) do |item, opt|
379
+ case opt[:type]
380
+ when :dmath
381
+ item.attributes[:display].should == "block"
382
+ i = strip_math(item.to_s)
383
+ when :math
384
+ item.attributes[:display].should == "inline"
385
+ i = strip_math(item.to_s)
386
+ else
387
+ i = item
388
+ end
389
+ r = "t#{opt[:type]}i#{opt[:index]}s#{opt[:src]}#{i}"
390
+ end
391
+ r.should == "tmathi0s$a$<mi>a</mi>tmathi1s$b$<mi>b</mi>tdmathi0s$$c$$<mi>c</mi>tdmathi1s$$d$$<mi>d</mi>tescapei0s\\eetescapei1s\\\\\\"
392
+
393
+ r = s.decode(encoded, data) do |item, opt|
394
+ nil
395
+ end
396
+ r.should == s.decode(encoded, data)
397
+
398
+ s.set_encode_proc(/\{\{/) do |scanner|
399
+ "<%=#{scanner[1]}%>" if scanner.scan(/\{\{(.*?)\}\}/m)
400
+ end
401
+ encoded, data = s.encode("{{a}}{{")
402
+ r = s.decode(encoded, data) do |item, opt|
403
+ item.should == "<%=a%>"
404
+ opt[:type].should == :user
405
+ opt[:index].should == 0
406
+ opt[:src].should == "{{a}}"
407
+ nil
408
+ end
409
+ r.should == "<%=a%>{{"
410
+
411
+ s.set_decode_proc do |item, opt|
412
+ "dummy"
413
+ end
414
+ s.decode(encoded, data).should == "dummy{{"
415
+ r = s.decode(encoded, data) do |item, opt|
416
+ nil
417
+ end
418
+ r.should == "<%=a%>{{"
419
+ end
420
+
421
+ it "#set_decode_proc" do
422
+ s = MathML::Util::SimpleLaTeX.new
423
+ src = '$a$$b$$$c$$$$d$$\e\\\\'
424
+ encoded, data = s.encode(src)
425
+ original_decoded = s.decode(encoded, data)
426
+ s.set_decode_proc do |item, opt|
427
+ case opt[:type]
428
+ when :dmath
429
+ item.attributes[:display].should == "block"
430
+ i = strip_math(item.to_s)
431
+ when :math
432
+ item.attributes[:display].should == "inline"
433
+ i = strip_math(item.to_s)
434
+ else
435
+ i = item
436
+ end
437
+ r = "t#{opt[:type]}i#{opt[:index]}s#{opt[:src]}#{i}"
438
+ end
439
+ encoded, data = s.encode(src)
440
+ r = s.decode(encoded, data)
441
+ r.should == "tmathi0s$a$<mi>a</mi>tmathi1s$b$<mi>b</mi>tdmathi0s$$c$$<mi>c</mi>tdmathi1s$$d$$<mi>d</mi>tescapei0s\\eetescapei1s\\\\\\"
442
+
443
+ s.reset_decode_proc
444
+ s.decode(encoded, data).should == original_decoded
445
+ end
446
+
447
+ it "#unencode with block" do
448
+ s = MathML::Util::SimpleLaTeX.new
449
+ src = '$a$$b$$$c$$$$d$$\e\\\\'
450
+ encoded, data = s.encode(src)
451
+ r = s.unencode(encoded, data) do |item, opt|
452
+ r = "t#{opt[:type]}i#{opt[:index]}#{item.to_s}"
453
+ end
454
+ r.should == "tmathi0$a$tmathi1$b$tdmathi0$$c$$tdmathi1$$d$$tescapei0\\etescapei1\\\\"
455
+
456
+ r = s.unencode(encoded, data) do |item, opt|
457
+ nil
458
+ end
459
+ r.should == s.unencode(encoded, data)
460
+
461
+ s.set_encode_proc(/\{\{/) do |scanner|
462
+ "<%=#{scanner[1]}%>" if scanner.scan(/\{\{(.*?)\}\}/m)
463
+ end
464
+ encoded, data = s.encode("{{a}}{{")
465
+ r = s.unencode(encoded, data) do |item, opt|
466
+ item.should == "{{a}}"
467
+ opt[:type].should == :user
468
+ opt[:index].should == 0
469
+ nil
470
+ end
471
+ r.should == "{{a}}{{"
472
+ end
473
+
474
+ it "#set_unencode_proc" do
475
+ s = MathML::Util::SimpleLaTeX.new
476
+ src = '$a$$b$$$c$$$$d$$\e\\\\'
477
+ encoded, data = s.encode(src)
478
+ original_unencoded = s.unencode(encoded, data)
479
+
480
+ s.set_unencode_proc do |item, opt|
481
+ r = "t#{opt[:type]}i#{opt[:index]}#{item.to_s}"
482
+ end
483
+ r = s.unencode(encoded, data)
484
+ r.should == "tmathi0$a$tmathi1$b$tdmathi0$$c$$tdmathi1$$d$$tescapei0\\etescapei1\\\\"
485
+
486
+ s.set_unencode_proc do |item, opt|
487
+ nil
488
+ end
489
+ s.unencode(encoded, data).should == original_unencoded
490
+
491
+ s.set_encode_proc(/\{\{/) do |scanner|
492
+ "<%=#{scanner[1]}%>" if scanner.scan(/\{\{(.*?)\}\}/m)
493
+ end
494
+ encoded, data = s.encode("{{a}}{{")
495
+ s.set_unencode_proc do |item, opt|
496
+ item.should == "{{a}}"
497
+ opt[:type].should == :user
498
+ opt[:index].should == 0
499
+ nil
500
+ end
501
+ r = s.unencode(encoded, data)
502
+ r.should == "{{a}}{{"
503
+ end
504
+
505
+ it "#reset_unencode_proc" do
506
+ s = MathML::Util::SimpleLaTeX.new
507
+ s.set_unencode_proc do |item, opt|
508
+ "dummy"
509
+ end
510
+ encoded, data = s.encode("$a$ $$b$$")
511
+ s.unencode(encoded, data).should == "dummy dummy"
512
+
513
+ s.reset_unencode_proc
514
+ s.unencode(encoded, data).should == "$a$ $$b$$"
515
+ end
516
+
517
+ it "#unencode without escaping" do
518
+ s = MathML::Util::SimpleLaTeX.new
519
+ src = %[$<>&'"\n$ $$<>&"'\n$$]
520
+ encoded, data = s.encode(src)
521
+ s.unencode(encoded, data).should == "$&lt;&gt;&amp;&apos;&quot;<br />\n$ $$&lt;&gt;&amp;&quot;&apos;<br />\n$$"
522
+ s.unencode(encoded, data, true).should == src
523
+ end
524
+
525
+ it "#decode without parsed" do
526
+ s = MathML::Util::SimpleLaTeX.new
527
+ src = '$a$$$b$$\a'
528
+ encoded, data = s.encode(src)
529
+ s.decode(encoded, data, true).should == "$a$$$b$$a"
530
+ s.decode(encoded, data, true) do |item, opt|
531
+ case opt[:type]
532
+ when :math
533
+ item.should == "$a$"
534
+ when :dmath
535
+ item.should == "$$b$$"
536
+ when :escape
537
+ item.should == "a"
538
+ end
539
+ end
540
+
541
+ encoded, data = s.encode("$<\n$ $$<\n$$")
542
+ s.decode(encoded, data, true).should == "$&lt;<br />\n$ $$&lt;<br />\n$$"
543
+ end
544
+
545
+ it "#decode_partial" do
546
+ s = MathML::Util::SimpleLaTeX.new
547
+ encoded, data = s.encode("$a$$b$")
548
+ simplify_math(s.decode_partial(:math, encoded, data)).should == simplify_math("<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>a</mi></math><math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>")
549
+
550
+ s.set_encode_proc(/\\</) do |scanner|
551
+ if scanner.scan(/\\<(.)(.*?)\1>/)
552
+ scanner[2]
553
+ end
554
+ end
555
+ src='$a$$$b$$\c\<.$d$.>'
556
+ encoded, data = s.encode(src)
557
+ simplify_math(s.decode_partial(:math, encoded, data)).should == simplify_math("<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>a</mi></math>\001d0\001\001e0\001\001u0\001")
558
+ simplify_math(s.decode_partial(:dmath, encoded, data)).should == simplify_math("\001m0\001<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>\001e0\001\001u0\001")
559
+ simplify_math(s.decode_partial(:escape, encoded, data)).should == simplify_math("\001m0\001\001d0\001c\001u0\001")
560
+ simplify_math(s.decode_partial(:user, encoded, data)).should == simplify_math("\001m0\001\001d0\001\001e0\001$d$")
561
+
562
+ r = s.decode_partial(:math, encoded, data) do |item, opt|
563
+ opt[:type].should == :math
564
+ opt[:src].should == "$a$"
565
+ simplify_math(item.to_s).should == simplify_math("<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>a</mi></math>")
566
+ item
567
+ end
568
+ simplify_math(r).should == simplify_math("<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>a</mi></math>\001d0\001\001e0\001\001u0\001")
569
+
570
+ r = s.decode_partial(:dmath, encoded, data) do |item, opt|
571
+ opt[:type].should == :dmath
572
+ opt[:src].should == "$$b$$"
573
+ simplify_math(item.to_s).should == simplify_math("<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>")
574
+ item
575
+ end
576
+ simplify_math(r).should == simplify_math("\001m0\001<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mi>b</mi></math>\001e0\001\001u0\001")
577
+
578
+ r = s.decode_partial(:escape, encoded, data) do |item, opt|
579
+ opt[:type].should == :escape
580
+ opt[:src].should == "\\c"
581
+ item.should == "c"
582
+ item
583
+ end
584
+ r.should == "\001m0\001\001d0\001c\001u0\001"
585
+
586
+ r = s.decode_partial(:user, encoded, data) do |item, opt|
587
+ opt[:type].should == :user
588
+ opt[:src].should == "\\<.$d$.>"
589
+ item.should == "$d$"
590
+ item
591
+ end
592
+ r.should == "\001m0\001\001d0\001\001e0\001$d$"
593
+
594
+ s = MathML::Util::SimpleLaTeX.new
595
+ encoded, data = s.encode("\\a")
596
+ s.decode_partial(:escape, encoded, data).should == "a"
597
+ r = s.decode_partial(:escape, encoded, data) do |item, opt|
598
+ end
599
+ r.should == "\001e0\001"
600
+
601
+ s = MathML::Util::SimpleLaTeX.new(:delimiter=>%[$])
602
+ encoded, data = s.encode("$a$")
603
+ s.decode_partial(:math, encoded, data).should =~ /^<math.*<\/math>/m
604
+ end
605
+
606
+ it "should keep regexp order" do
607
+ s = MathML::Util::SimpleLaTeX.new
608
+ s.set_encode_proc(/\$/) do |sc|
609
+ if sc.scan(/\$(.*)\z/)
610
+ sc[1]+"is rest"
611
+ end
612
+ end
613
+
614
+ encoded, data = s.encode("$a$$b")
615
+ encoded.should == "\001m0\001\001u0\001"
616
+ end
617
+
618
+ it "parse eqnarray" do
619
+ s = MathML::Util::SimpleLaTeX.new
620
+ src = <<'EOT'
621
+ test
622
+ \begin
623
+ {eqnarray}
624
+ a&=&b\\
625
+ c&=&d
626
+ \end
627
+ {eqnarray}
628
+ end
629
+ EOT
630
+ encoded, data = s.encode(src, MathML::Util::EQNARRAY_RE) do |scanner|
631
+ if scanner.scan(MathML::Util::EQNARRAY_RE)
632
+ s.parse_eqnarray(scanner[1])
633
+ end
634
+ end
635
+ encoded.should == "test\n\001u0\001\nend\n"
636
+ simplify_math(s.decode(encoded, data)).should == simplify_math("test\n<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'><mtable><mtr><mtd><mi>a</mi></mtd><mtd><mo>=</mo></mtd><mtd><mi>b</mi></mtd></mtr><mtr><mtd><mi>c</mi></mtd><mtd><mo>=</mo></mtd><mtd><mi>d</mi></mtd></mtr></mtable></math>\nend\n")
637
+
638
+ encoded, data = s.encode('\begin{eqnarray}a\end{eqnarray}', MathML::Util::EQNARRAY_RE) do |scanner|
639
+ s.parse_eqnarray(scanner[1]) if scanner.scan(MathML::Util::EQNARRAY_RE)
640
+ end
641
+ s.decode(encoded, data).should == "<br />\nNeed more column.<br />\n<code>\\begin{eqnarray}a<strong>\\end{eqnarray}</strong></code><br />"
642
+ end
643
+
644
+ it "should parse single command" do
645
+ s = MathML::Util::SimpleLaTeX.new
646
+ encoded, data = s.encode(%q[\alpha\|\<\>\&\"\'\test], MathML::Util::SINGLE_COMMAND_RE) do |scanner|
647
+ if scanner.scan(MathML::Util::SINGLE_COMMAND_RE)
648
+ s.parse_single_command(scanner.matched)
649
+ end
650
+ end
651
+ encoded.should == "\001u0\001\001e0\001\001e1\001\001e2\001\001e3\001\001e4\001\001e5\001\001u1\001"
652
+ simplify_math(s.decode(encoded, data)).should == simplify_math("<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>&alpha;</mi></math>|&lt;&gt;&amp;&quot;&apos;test")
653
+ encoded, data = s.encode('\alpha test', MathML::Util::SINGLE_COMMAND_RE) do |scanner|
654
+ if scanner.scan(MathML::Util::SINGLE_COMMAND_RE)
655
+ s.parse_single_command(scanner.matched)
656
+ end
657
+ end
658
+ encoded.should == "\001u0\001test"
659
+ simplify_math(s.decode(encoded, data)).should == simplify_math("<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>&alpha;</mi></math>test")
660
+
661
+ encoded, data = s.encode('\alpha test', MathML::Util::SINGLE_COMMAND_RE) do |scanner|
662
+ if scanner.scan(MathML::Util::SINGLE_COMMAND_RE)
663
+ s.parse_single_command(scanner.matched)
664
+ end
665
+ end
666
+ encoded.should == "\001u0\001 test"
667
+ simplify_math(s.decode(encoded, data)).should == simplify_math("<math display='inline' xmlns='http://www.w3.org/1998/Math/MathML'><mi>&alpha;</mi></math> test")
668
+
669
+ encoded, data = s.encode("\\alpha\ntest", MathML::Util::SINGLE_COMMAND_RE) do |scanner|
670
+ if scanner.scan(MathML::Util::SINGLE_COMMAND_RE)
671
+ s.parse_single_command(scanner.matched)
672
+ end
673
+ end
674
+ encoded.should == "\001u0\001\ntest"
675
+ end
676
+
677
+ it "#encode can be called twice or more times" do
678
+ s = MathML::Util::SimpleLaTeX.new
679
+ encoded, data = s.encode('$a$')
680
+ encoded, data = s.encode('$b$', data)
681
+ encoded.should == "\001m1\001"
682
+ data.msrc_list.should == ["$a$", '$b$']
683
+ data.math_list.size.should == 2
684
+ strip_math(data.math_list[0].to_s).should == "<mi>a</mi>"
685
+ strip_math(data.math_list[1].to_s).should == "<mi>b</mi>"
686
+
687
+ encoded, data = s.encode('a', data, /a/) do |sc|
688
+ sc.scan(/a/)
689
+ end
690
+ encoded.should == "\001u0\001"
691
+ data.msrc_list.should == ["$a$", '$b$']
692
+ data.usrc_list.should == ["a"]
693
+
694
+ encoded, data = s.encode('a', nil, /a/) do |s|
695
+ s.scan(/a/)
696
+ end
697
+ encoded.should == "\001u0\001"
698
+ data.usrc_list.should == ["a"]
699
+ end
700
+ end