mathemagical 0.0.1

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