wikitext 0.1
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.
- data/ext/ary.h +99 -0
- data/ext/depend +22 -0
- data/ext/extconf.rb +23 -0
- data/ext/parser.c +2174 -0
- data/ext/parser.h +31 -0
- data/ext/str.h +135 -0
- data/ext/token.c +109 -0
- data/ext/token.h +95 -0
- data/ext/wikitext.c +60 -0
- data/ext/wikitext.h +30 -0
- data/ext/wikitext_ragel.c +3354 -0
- data/ext/wikitext_ragel.h +17 -0
- data/spec/autolinking_spec.rb +122 -0
- data/spec/blockquote_spec.rb +570 -0
- data/spec/em_spec.rb +97 -0
- data/spec/encoding_spec.rb +124 -0
- data/spec/entity_spec.rb +40 -0
- data/spec/external_link_spec.rb +289 -0
- data/spec/h1_spec.rb +59 -0
- data/spec/h2_spec.rb +59 -0
- data/spec/h3_spec.rb +59 -0
- data/spec/h4_spec.rb +59 -0
- data/spec/h5_spec.rb +59 -0
- data/spec/h6_spec.rb +59 -0
- data/spec/indentation_spec.rb +70 -0
- data/spec/integration_spec.rb +265 -0
- data/spec/internal_link_spec.rb +445 -0
- data/spec/line_endings_spec.rb +81 -0
- data/spec/link_encoding_spec.rb +132 -0
- data/spec/link_sanitizing_spec.rb +228 -0
- data/spec/nowiki_spec.rb +155 -0
- data/spec/p_spec.rb +44 -0
- data/spec/pre_spec.rb +411 -0
- data/spec/regressions_spec.rb +45 -0
- data/spec/spec_helper.rb +77 -0
- data/spec/strong_em_spec.rb +89 -0
- data/spec/strong_spec.rb +99 -0
- data/spec/tokenizing_spec.rb +190 -0
- data/spec/tt_spec.rb +100 -0
- data/spec/ul_spec.rb +307 -0
- data/spec/wikitext_spec.rb +50 -0
- metadata +93 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
// Copyright 2008 Wincent Colaiuta
|
2
|
+
// This program is free software: you can redistribute it and/or modify
|
3
|
+
// it under the terms of the GNU General Public License as published by
|
4
|
+
// the Free Software Foundation, either version 3 of the License, or
|
5
|
+
// (at your option) any later version.
|
6
|
+
//
|
7
|
+
// This program is distributed in the hope that it will be useful,
|
8
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
// GNU General Public License for more details.
|
11
|
+
//
|
12
|
+
// You should have received a copy of the GNU General Public License
|
13
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
|
+
|
15
|
+
#include "token.h"
|
16
|
+
|
17
|
+
void next_token(token_t *out, token_t *last_token, char *p, char *pe);
|
@@ -0,0 +1,122 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright 2007-2008 Wincent Colaiuta
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
17
|
+
require 'wikitext'
|
18
|
+
|
19
|
+
describe Wikitext::Parser, 'autolinking' do
|
20
|
+
before do
|
21
|
+
@parser = Wikitext::Parser.new
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should default to autolinking on' do
|
25
|
+
@parser.autolink.should == true
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'on' do
|
29
|
+
it 'should convert HTTP URIs into hyperlinks' do
|
30
|
+
uri = 'http://example.com/'
|
31
|
+
@parser.parse(uri).should == %Q{<p><a href="http://example.com/" class="external">http://example.com/</a></p>\n}
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should convert HTTPS URIs into hyperlinks' do
|
35
|
+
uri = 'https://example.com/'
|
36
|
+
@parser.parse(uri).should == %Q{<p><a href="https://example.com/" class="external">https://example.com/</a></p>\n}
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should convert FTP URIs into hyperlinks' do
|
40
|
+
uri = 'ftp://example.com/'
|
41
|
+
@parser.parse(uri).should == %Q{<p><a href="ftp://example.com/" class="external">ftp://example.com/</a></p>\n}
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should convert mailto URIs into hyperlinks' do
|
45
|
+
uri = 'mailto:user@example.com'
|
46
|
+
@parser.parse(uri).should == %Q{<p><a href="mailto:user@example.com" class="external">mailto:user@example.com</a></p>\n}
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should convert SVN URIs into hyperlinks' do
|
50
|
+
uri = 'svn://example.com/'
|
51
|
+
@parser.parse(uri).should == %Q{<p><a href="svn://example.com/" class="external">svn://example.com/</a></p>\n}
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should apple the external_link_class CSS class if set' do
|
55
|
+
uri = 'http://example.com/'
|
56
|
+
@parser.external_link_class = 'bar'
|
57
|
+
@parser.parse(uri).should == %Q{<p><a href="http://example.com/" class="bar">http://example.com/</a></p>\n}
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should apply no CSS if external_link_class is set to nil' do
|
61
|
+
uri = 'http://example.com/'
|
62
|
+
@parser.external_link_class = nil
|
63
|
+
@parser.parse(uri).should == %Q{<p><a href="http://example.com/">http://example.com/</a></p>\n}
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should pass through URIs unchanged inside <nowiki></nowiki> spans' do
|
67
|
+
@parser.parse("<nowiki>http://example.com/</nowiki>").should == "<p>http://example.com/</p>\n"
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should autolink URIs inside <pre></pre> spans' do
|
71
|
+
input = ' http://example.com/'
|
72
|
+
expected = %Q{<pre><a href="http://example.com/" class="external">http://example.com/</a></pre>\n}
|
73
|
+
@parser.parse(input).should == expected
|
74
|
+
@parser.external_link_class = nil
|
75
|
+
expected = %Q{<pre><a href="http://example.com/">http://example.com/</a></pre>\n}
|
76
|
+
@parser.parse(input).should == expected
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should convert emails into hyperlinks' do
|
80
|
+
uri = 'user@example.com'
|
81
|
+
@parser.parse(uri).should == %Q{<p><a href="mailto:user@example.com" class="mailto">user@example.com</a></p>\n}
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should apply the mailto CSS class if set' do
|
85
|
+
uri = 'user@example.com'
|
86
|
+
@parser.mailto_class = 'foo'
|
87
|
+
@parser.parse(uri).should == %Q{<p><a href="mailto:user@example.com" class="foo">user@example.com</a></p>\n}
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should apply no CSS if the mailto class is set to nil' do
|
91
|
+
uri = 'user@example.com'
|
92
|
+
@parser.mailto_class = nil
|
93
|
+
@parser.parse(uri).should == %Q{<p><a href="mailto:user@example.com">user@example.com</a></p>\n}
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should pass through emails unchanged inside <nowiki></nowiki> spans' do
|
97
|
+
@parser.parse("<nowiki>user@example.com</nowiki>").should == "<p>user@example.com</p>\n" # was a crasher
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should pass through emails unchanged inside <pre></pre> blocks' do
|
101
|
+
@parser.parse(" user@example.com").should == "<pre>user@example.com</pre>\n" # was a crasher
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'off' do
|
106
|
+
before do
|
107
|
+
@parser.autolink = false
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should accept "autolink = false"' do
|
111
|
+
@parser.autolink.should == false
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should not convert URIs into hyperlinks' do
|
115
|
+
@parser.parse('http://example.com/').should == "<p>http://example.com/</p>\n"
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should not convert emails into hyperlinks' do
|
119
|
+
@parser.parse('user@example.com').should == "<p>user@example.com</p>\n"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,570 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright 2007-2008 Wincent Colaiuta
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
17
|
+
require 'wikitext'
|
18
|
+
|
19
|
+
describe Wikitext::Parser, 'standard blockquotes (">" in first column)' do
|
20
|
+
before do
|
21
|
+
@parser = Wikitext::Parser.new
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should treat ">" in first column as a blockquote marker' do
|
25
|
+
expected = dedent <<-END
|
26
|
+
<blockquote>
|
27
|
+
<p>foo</p>
|
28
|
+
</blockquote>
|
29
|
+
END
|
30
|
+
@parser.parse('>foo').should == expected
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should accept (and ignore) one optional space after the ">"' do
|
34
|
+
expected = dedent <<-END
|
35
|
+
<blockquote>
|
36
|
+
<p>foo</p>
|
37
|
+
</blockquote>
|
38
|
+
END
|
39
|
+
@parser.parse('> foo').should == expected
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should recognize consecutive ">" as continuance of blockquote section' do
|
43
|
+
expected = dedent <<-END
|
44
|
+
<blockquote>
|
45
|
+
<p>foo bar</p>
|
46
|
+
</blockquote>
|
47
|
+
END
|
48
|
+
@parser.parse("> foo\n> bar").should == expected
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should not give ">" special treatment when not on the far left' do
|
52
|
+
@parser.parse('foo > bar').should == "<p>foo > bar</p>\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should allow nesting of blockquotes' do
|
56
|
+
expected = dedent <<-END
|
57
|
+
<blockquote>
|
58
|
+
<blockquote>
|
59
|
+
<p>foo</p>
|
60
|
+
</blockquote>
|
61
|
+
</blockquote>
|
62
|
+
END
|
63
|
+
@parser.parse('> > foo').should == expected
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should allow opening of a nested blockquote after other content' do
|
67
|
+
expected = dedent <<-END
|
68
|
+
<blockquote>
|
69
|
+
<p>foo</p>
|
70
|
+
<blockquote>
|
71
|
+
<p>bar</p>
|
72
|
+
</blockquote>
|
73
|
+
</blockquote>
|
74
|
+
END
|
75
|
+
@parser.parse("> foo\n> > bar").should == expected
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should allow opening of a nested blockquote before other content' do
|
79
|
+
expected = dedent <<-END
|
80
|
+
<blockquote>
|
81
|
+
<blockquote>
|
82
|
+
<p>foo</p>
|
83
|
+
</blockquote>
|
84
|
+
<p>bar</p>
|
85
|
+
</blockquote>
|
86
|
+
END
|
87
|
+
@parser.parse("> > foo\n> bar").should == expected
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should accept an empty blockquote' do
|
91
|
+
expected = dedent <<-END
|
92
|
+
<blockquote>
|
93
|
+
</blockquote>
|
94
|
+
END
|
95
|
+
@parser.parse('>').should == expected
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should jump out of blockquote mode on seeing a normal line of text' do
|
99
|
+
expected = dedent <<-END
|
100
|
+
<blockquote>
|
101
|
+
<p>foo</p>
|
102
|
+
</blockquote>
|
103
|
+
<p>bar</p>
|
104
|
+
END
|
105
|
+
@parser.parse("> foo\nbar").should == expected
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should allow nesting of h1 blocks' do
|
109
|
+
expected = dedent <<-END
|
110
|
+
<blockquote>
|
111
|
+
<h1>foo</h1>
|
112
|
+
</blockquote>
|
113
|
+
END
|
114
|
+
@parser.parse('> = foo =').should == expected
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should allow nesting of h2 blocks' do
|
118
|
+
expected = dedent <<-END
|
119
|
+
<blockquote>
|
120
|
+
<h2>foo</h2>
|
121
|
+
</blockquote>
|
122
|
+
END
|
123
|
+
@parser.parse('> == foo ==').should == expected
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should allow nesting of h3 blocks' do
|
127
|
+
expected = dedent <<-END
|
128
|
+
<blockquote>
|
129
|
+
<h3>foo</h3>
|
130
|
+
</blockquote>
|
131
|
+
END
|
132
|
+
@parser.parse('> === foo ===').should == expected
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should allow nesting of h4 blocks' do
|
136
|
+
expected = dedent <<-END
|
137
|
+
<blockquote>
|
138
|
+
<h4>foo</h4>
|
139
|
+
</blockquote>
|
140
|
+
END
|
141
|
+
@parser.parse('> ==== foo ====').should == expected
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should allow nesting of h5 blocks' do
|
145
|
+
expected = dedent <<-END
|
146
|
+
<blockquote>
|
147
|
+
<h5>foo</h5>
|
148
|
+
</blockquote>
|
149
|
+
END
|
150
|
+
@parser.parse('> ===== foo =====').should == expected
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should allow nesting of h6 blocks' do
|
154
|
+
expected = dedent <<-END
|
155
|
+
<blockquote>
|
156
|
+
<h6>foo</h6>
|
157
|
+
</blockquote>
|
158
|
+
END
|
159
|
+
@parser.parse('> ====== foo ======').should == expected
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should allow alternating nested paragraphs and pre blocks' do
|
163
|
+
# was a bug
|
164
|
+
input = dedent <<-END
|
165
|
+
> para 1
|
166
|
+
>
|
167
|
+
> pre 1
|
168
|
+
> pre 2
|
169
|
+
>
|
170
|
+
> para 2
|
171
|
+
END
|
172
|
+
expected = dedent <<-END
|
173
|
+
<blockquote>
|
174
|
+
<p>para 1</p>
|
175
|
+
<pre>pre 1
|
176
|
+
pre 2</pre>
|
177
|
+
<p>para 2</p>
|
178
|
+
</blockquote>
|
179
|
+
END
|
180
|
+
@parser.parse(input).should == expected
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should allow nesting of styled spans inside blockquotes' do
|
184
|
+
input = dedent <<-END
|
185
|
+
> link to [[something]], and ''other''
|
186
|
+
> `styled` '''spans'''.
|
187
|
+
END
|
188
|
+
expected = dedent <<-END
|
189
|
+
<blockquote>
|
190
|
+
<p>link to <a href="/wiki/something">something</a>, and <em>other</em> <tt>styled</tt> <strong>spans</strong>.</p>
|
191
|
+
</blockquote>
|
192
|
+
END
|
193
|
+
@parser.parse(input).should == expected
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'should allow complex nestings inside blockquotes' do
|
197
|
+
# was a bug: further reduced in the following example, "should handle TT spans inside blockquotes"
|
198
|
+
input = dedent <<-END
|
199
|
+
code block
|
200
|
+
|
201
|
+
a normal para
|
202
|
+
|
203
|
+
> will nest
|
204
|
+
>
|
205
|
+
> line 1
|
206
|
+
> line 2
|
207
|
+
>
|
208
|
+
> other
|
209
|
+
>
|
210
|
+
> * here
|
211
|
+
> * is
|
212
|
+
> * a
|
213
|
+
> * list
|
214
|
+
>
|
215
|
+
> outer para with ''styled''
|
216
|
+
> `stuff` in it
|
217
|
+
>
|
218
|
+
> > inner
|
219
|
+
> > blockquote
|
220
|
+
> > # inner list
|
221
|
+
> > ## nested list
|
222
|
+
|
223
|
+
follow-up para
|
224
|
+
END
|
225
|
+
expected = dedent <<-END
|
226
|
+
<pre>code block</pre>
|
227
|
+
<p>a normal para</p>
|
228
|
+
<blockquote>
|
229
|
+
<p>will nest</p>
|
230
|
+
<pre>line 1
|
231
|
+
line 2</pre>
|
232
|
+
<p>other</p>
|
233
|
+
<ul>
|
234
|
+
<li>here</li>
|
235
|
+
<li>is</li>
|
236
|
+
<li>a</li>
|
237
|
+
<li>list</li>
|
238
|
+
</ul>
|
239
|
+
<p>outer para with <em>styled</em> <tt>stuff</tt> in it</p>
|
240
|
+
<blockquote>
|
241
|
+
<p>inner blockquote</p>
|
242
|
+
<ol>
|
243
|
+
<li>inner list
|
244
|
+
<ol>
|
245
|
+
<li>nested list</li>
|
246
|
+
</ol>
|
247
|
+
</li>
|
248
|
+
</ol>
|
249
|
+
</blockquote>
|
250
|
+
</blockquote>
|
251
|
+
<p>follow-up para</p>
|
252
|
+
END
|
253
|
+
@parser.parse(input).should == expected
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should handle TT spans inside blockquotes' do
|
257
|
+
# was a bug: this is a minimally reduced test case extracted from the integration tests
|
258
|
+
input = dedent <<-END
|
259
|
+
> some
|
260
|
+
> `styled`
|
261
|
+
END
|
262
|
+
expected = dedent <<-END
|
263
|
+
<blockquote>
|
264
|
+
<p>some <tt>styled</tt></p>
|
265
|
+
</blockquote>
|
266
|
+
END
|
267
|
+
@parser.parse(input).should == expected
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
it 'should handled nested lists which immediately follow paragraphs' do
|
272
|
+
# was a bug: this is a minimally reduced test case extracted from the integration tests
|
273
|
+
input = dedent <<-END
|
274
|
+
> Finally
|
275
|
+
> # Which
|
276
|
+
END
|
277
|
+
expected = dedent <<-END
|
278
|
+
<blockquote>
|
279
|
+
<p>Finally</p>
|
280
|
+
<ol>
|
281
|
+
<li>Which</li>
|
282
|
+
</ol>
|
283
|
+
</blockquote>
|
284
|
+
END
|
285
|
+
@parser.parse(input).should == expected
|
286
|
+
end
|
287
|
+
|
288
|
+
# TODO: tests for nesting other types of blocks
|
289
|
+
end
|
290
|
+
|
291
|
+
describe Wikitext::Parser, 'literal BLOCKQUOTE_START/BLOCKQUOTE_END tags' do
|
292
|
+
before do
|
293
|
+
@parser = Wikitext::Parser.new
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'should accept literal BLOCKQUOTE_START/BLOCKQUOTE_END tags as an alternative to the standard syntax' do
|
297
|
+
input = '<blockquote>hello</blockquote>'
|
298
|
+
expected = dedent <<-END
|
299
|
+
<blockquote>
|
300
|
+
<p>hello</p>
|
301
|
+
</blockquote>
|
302
|
+
END
|
303
|
+
@parser.parse(input).should == expected
|
304
|
+
|
305
|
+
# alternative 1
|
306
|
+
input = dedent <<-END
|
307
|
+
<blockquote>
|
308
|
+
hello
|
309
|
+
</blockquote>
|
310
|
+
END
|
311
|
+
expected = dedent <<-END
|
312
|
+
<blockquote>
|
313
|
+
<p>hello</p>
|
314
|
+
</blockquote>
|
315
|
+
END
|
316
|
+
@parser.parse(input).should == expected
|
317
|
+
|
318
|
+
# alternative 2
|
319
|
+
input = dedent <<-END
|
320
|
+
<blockquote>hello
|
321
|
+
</blockquote>
|
322
|
+
END
|
323
|
+
expected = dedent <<-END
|
324
|
+
<blockquote>
|
325
|
+
<p>hello</p>
|
326
|
+
</blockquote>
|
327
|
+
END
|
328
|
+
@parser.parse(input).should == expected
|
329
|
+
|
330
|
+
# alternative 3
|
331
|
+
input = dedent <<-END
|
332
|
+
<blockquote>
|
333
|
+
hello</blockquote>
|
334
|
+
END
|
335
|
+
expected = dedent <<-END
|
336
|
+
<blockquote>
|
337
|
+
<p>hello</p>
|
338
|
+
</blockquote>
|
339
|
+
END
|
340
|
+
@parser.parse(input).should == expected
|
341
|
+
|
342
|
+
# note what happens if we indent (whitespace gets carried through; it is not identified as a PRE block
|
343
|
+
# in reality you'd never indent when editing wikitext anyway; the idea is to free yourself from details like that
|
344
|
+
input = dedent <<-END
|
345
|
+
<blockquote>
|
346
|
+
hello
|
347
|
+
</blockquote>
|
348
|
+
END
|
349
|
+
expected = dedent <<-END
|
350
|
+
<blockquote>
|
351
|
+
<p> hello</p>
|
352
|
+
</blockquote>
|
353
|
+
END
|
354
|
+
@parser.parse(input).should == expected
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'should merge consecutive lines into a single paragraph' do
|
358
|
+
input = dedent <<-END
|
359
|
+
<blockquote>foo
|
360
|
+
bar
|
361
|
+
baz</blockquote>
|
362
|
+
END
|
363
|
+
expected = dedent <<-END
|
364
|
+
<blockquote>
|
365
|
+
<p>foo bar baz</p>
|
366
|
+
</blockquote>
|
367
|
+
END
|
368
|
+
@parser.parse(input).should == expected
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'should process paragraph breaks' do
|
372
|
+
input = dedent <<-END
|
373
|
+
<blockquote>foo
|
374
|
+
|
375
|
+
baz</blockquote>
|
376
|
+
END
|
377
|
+
expected = dedent <<-END
|
378
|
+
<blockquote>
|
379
|
+
<p>foo</p>
|
380
|
+
<p>baz</p>
|
381
|
+
</blockquote>
|
382
|
+
END
|
383
|
+
@parser.parse(input).should == expected
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'should pass through PRE tokens unaltered' do
|
387
|
+
input = dedent <<-END
|
388
|
+
<blockquote>foo
|
389
|
+
bar</blockquote>
|
390
|
+
END
|
391
|
+
|
392
|
+
# note the extra space: one for the CRLF and another for the PRE token
|
393
|
+
expected = dedent <<-END
|
394
|
+
<blockquote>
|
395
|
+
<p>foo bar</p>
|
396
|
+
</blockquote>
|
397
|
+
END
|
398
|
+
@parser.parse(input).should == expected
|
399
|
+
end
|
400
|
+
|
401
|
+
it 'should terminate open span-level elements on hitting the newline' do
|
402
|
+
# for now just test with EM; potentially add more examples later
|
403
|
+
input = dedent <<-END
|
404
|
+
<blockquote>foo ''bar
|
405
|
+
baz</blockquote>
|
406
|
+
END
|
407
|
+
expected = dedent <<-END
|
408
|
+
<blockquote>
|
409
|
+
<p>foo <em>bar</em> baz</p>
|
410
|
+
</blockquote>
|
411
|
+
END
|
412
|
+
@parser.parse(input).should == expected
|
413
|
+
end
|
414
|
+
|
415
|
+
it 'should pass through BLOCKQUOTE tokens escaped' do
|
416
|
+
input = dedent <<-END
|
417
|
+
<blockquote>foo
|
418
|
+
> bar
|
419
|
+
baz</blockquote>
|
420
|
+
END
|
421
|
+
expected = dedent <<-END
|
422
|
+
<blockquote>
|
423
|
+
<p>foo > bar baz</p>
|
424
|
+
</blockquote>
|
425
|
+
END
|
426
|
+
@parser.parse(input).should == expected
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'should be able to nest single-item unordered lists' do
|
430
|
+
input = '<blockquote>* foo</blockquote>'
|
431
|
+
expected = dedent <<-END
|
432
|
+
<blockquote>
|
433
|
+
<ul>
|
434
|
+
<li>foo</li>
|
435
|
+
</ul>
|
436
|
+
</blockquote>
|
437
|
+
END
|
438
|
+
@parser.parse(input).should == expected
|
439
|
+
end
|
440
|
+
|
441
|
+
it 'should be able to nest multi-item unordered lists' do
|
442
|
+
input = dedent <<-END
|
443
|
+
<blockquote>
|
444
|
+
* foo
|
445
|
+
* bar
|
446
|
+
* baz
|
447
|
+
</blockquote>
|
448
|
+
END
|
449
|
+
expected = dedent <<-END
|
450
|
+
<blockquote>
|
451
|
+
<ul>
|
452
|
+
<li>foo</li>
|
453
|
+
<li>bar</li>
|
454
|
+
<li>baz</li>
|
455
|
+
</ul>
|
456
|
+
</blockquote>
|
457
|
+
END
|
458
|
+
@parser.parse(input).should == expected
|
459
|
+
end
|
460
|
+
|
461
|
+
it 'should be able to nest nested unordered lists' do
|
462
|
+
input = dedent <<-END
|
463
|
+
<blockquote>
|
464
|
+
* foo
|
465
|
+
** bar
|
466
|
+
* baz
|
467
|
+
</blockquote>
|
468
|
+
END
|
469
|
+
expected = dedent <<-END
|
470
|
+
<blockquote>
|
471
|
+
<ul>
|
472
|
+
<li>foo
|
473
|
+
<ul>
|
474
|
+
<li>bar</li>
|
475
|
+
</ul>
|
476
|
+
</li>
|
477
|
+
<li>baz</li>
|
478
|
+
</ul>
|
479
|
+
</blockquote>
|
480
|
+
END
|
481
|
+
@parser.parse(input).should == expected
|
482
|
+
|
483
|
+
# note that the exact placement of the closing tag doesn't matter
|
484
|
+
input = dedent <<-END
|
485
|
+
<blockquote>
|
486
|
+
* foo
|
487
|
+
** bar
|
488
|
+
* baz</blockquote>
|
489
|
+
END
|
490
|
+
@parser.parse(input).should == expected
|
491
|
+
|
492
|
+
# likewise for the opening tag
|
493
|
+
input = dedent <<-END
|
494
|
+
<blockquote>* foo
|
495
|
+
** bar
|
496
|
+
* baz
|
497
|
+
</blockquote>
|
498
|
+
END
|
499
|
+
@parser.parse(input).should == expected
|
500
|
+
end
|
501
|
+
|
502
|
+
it 'should be able to nest blockquotes' do
|
503
|
+
input = dedent <<-END
|
504
|
+
<blockquote>
|
505
|
+
foo
|
506
|
+
<blockquote>
|
507
|
+
bar
|
508
|
+
</blockquote>
|
509
|
+
baz
|
510
|
+
</blockquote>
|
511
|
+
END
|
512
|
+
expected = dedent <<-END
|
513
|
+
<blockquote>
|
514
|
+
<p>foo</p>
|
515
|
+
<blockquote>
|
516
|
+
<p>bar</p>
|
517
|
+
</blockquote>
|
518
|
+
<p>baz</p>
|
519
|
+
</blockquote>
|
520
|
+
END
|
521
|
+
@parser.parse(input).should == expected
|
522
|
+
end
|
523
|
+
|
524
|
+
it 'should be able to nest pre blocks' do
|
525
|
+
input = dedent <<-END
|
526
|
+
<blockquote>
|
527
|
+
outer 1
|
528
|
+
<pre>inner 1
|
529
|
+
inner 2</pre>
|
530
|
+
outer 2
|
531
|
+
</blockquote>
|
532
|
+
END
|
533
|
+
expected = dedent <<-END
|
534
|
+
<blockquote>
|
535
|
+
<p>outer 1</p>
|
536
|
+
<pre>inner 1
|
537
|
+
inner 2</pre>
|
538
|
+
<p>outer 2</p>
|
539
|
+
</blockquote>
|
540
|
+
END
|
541
|
+
@parser.parse(input).should == expected
|
542
|
+
end
|
543
|
+
|
544
|
+
it 'should support nesting of H1 spans' do
|
545
|
+
input = dedent <<-END
|
546
|
+
<blockquote>
|
547
|
+
= foo =
|
548
|
+
bar
|
549
|
+
</blockquote>
|
550
|
+
END
|
551
|
+
|
552
|
+
expected = dedent <<-END
|
553
|
+
<blockquote>
|
554
|
+
<h1>foo</h1>
|
555
|
+
<p>bar</p>
|
556
|
+
</blockquote>
|
557
|
+
END
|
558
|
+
@parser.parse(input).should == expected
|
559
|
+
|
560
|
+
# but note that this won't work
|
561
|
+
# the second "=" is not recognized as an H1_END because the scanner has no lookahead at the token level
|
562
|
+
input = '<blockquote>= foo =</blockquote>'
|
563
|
+
expected = dedent <<-END
|
564
|
+
<blockquote>
|
565
|
+
<h1>foo =</h1>
|
566
|
+
</blockquote>
|
567
|
+
END
|
568
|
+
@parser.parse(input).should == expected
|
569
|
+
end
|
570
|
+
end
|