creole 0.3.3

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.
@@ -0,0 +1,6 @@
1
+ Manifest.txt
2
+ README.txt
3
+ Rakefile
4
+ lib/creole.rb
5
+ test/test_creole.rb
6
+ test/testcases.rb
@@ -0,0 +1,28 @@
1
+ = Creole
2
+
3
+ * http://creole.rubyforge.org/
4
+ * http://rubyforge.org/projects/creole/
5
+
6
+ == DESCRIPTION:
7
+
8
+ Creole is a Creole-to-HTML converter for Creole, the lightwight markup
9
+ language (http://wikicreole.org/).
10
+
11
+ == SYNOPSIS:
12
+
13
+ gem 'creole'
14
+ require 'creole'
15
+ html = Creole.creolize( ... )
16
+
17
+ == BUGS:
18
+
19
+ If you found a bug, please report it at the Creole project's tracker
20
+ on RubyForge:
21
+
22
+ http://rubyforge.org/tracker/?group_id=6344
23
+
24
+ == LICENSE:
25
+
26
+ RDoc is Copyright (c) 2008 Lars Christensen. It is free software, and
27
+ may be redistributed under the terms specified in the README file of
28
+ the Ruby distribution.
@@ -0,0 +1,11 @@
1
+ require 'hoe'
2
+
3
+ $:.unshift 'lib'
4
+ require 'creole'
5
+
6
+ Hoe.spec "creole" do |creole|
7
+ version = Creole::VERSION
8
+ developer 'Lars Christensen', 'larsch@belunktum.dk'
9
+ developer 'Daniel Mendler', 'mail@daniel-mendler.de'
10
+ end
11
+
@@ -0,0 +1,372 @@
1
+ require 'cgi'
2
+ require 'uri'
3
+
4
+ # :main: Creole
5
+
6
+ # The Creole parses and translates Creole formatted text into
7
+ # XHTML. Creole is a lightwight markup syntax similar to what many
8
+ # WikiWikiWebs use. Example syntax:
9
+ #
10
+ # = Heading 1 =
11
+ # == Heading 2 ==
12
+ # === Heading 3 ===
13
+ # **Bold text**
14
+ # //Italic text//
15
+ # [[Links]]
16
+ # |=Table|=Heading|
17
+ # |Table |Cells |
18
+ # {{image.png}}
19
+ #
20
+ # The simplest interface is Creole.creolize. The default handling of
21
+ # links allow explicit local links using the [[link]] syntax. External
22
+ # links will only be allowed if specified using http(s) and ftp(s)
23
+ # schemes. If special link handling is needed, such as inter-wiki or
24
+ # hierachical local links, you must inherit Creole::CreoleParser and
25
+ # override make_local_link.
26
+ #
27
+ # You can customize the created anchor/image markup by overriding
28
+ # make_*_anchor/make_image.
29
+
30
+ module Creole
31
+
32
+ VERSION = '0.3.3'
33
+
34
+ # CreoleParseError is raised when the Creole parser encounters
35
+ # something unexpected. This is generally now thrown unless there is
36
+ # a bug in the parser.
37
+ class CreoleParseError < Exception; end
38
+
39
+ # Convert the argument in Creole format to HTML and return the
40
+ # result. Example:
41
+ #
42
+ # Creole.creolize("**Hello //World//**")
43
+ # #=> "<p><strong>Hello <em>World</em></strong></p>"
44
+ #
45
+ # This is an alias for calling CreoleParser#parse:
46
+ # CreoleParser.new.parse(creole)
47
+ def self.creolize(creole)
48
+ CreoleParser.new.parse(creole)
49
+ end
50
+
51
+ # Main Creole parser class. Call CreoleParser#parse to parse Creole
52
+ # formatted text.
53
+ #
54
+ # This class is not reentrant. A separate instance is needed for
55
+ # each thread that needs to convert Creole to HTML.
56
+ #
57
+ # Inherit this to provide custom handling of links. The overrideable
58
+ # methods are: make_local_link
59
+ class CreoleParser
60
+
61
+ # Create a new CreoleParser instance.
62
+ def initialize
63
+ @base = nil
64
+ @allowed_schemes = [ 'http', 'https', 'ftp', 'ftps' ]
65
+ @uri_scheme_re = @allowed_schemes.join('|')
66
+ end
67
+
68
+ # Parse and convert the argument in Creole text to HTML and return
69
+ # the result. The resulting HTML does not contain <html> and
70
+ # <body> tags.
71
+ #
72
+ # Example:
73
+ #
74
+ # parser = CreoleParser.new
75
+ # parser.parse("**Hello //World//**")
76
+ # #=> "<p><strong>Hello <em>World</em></strong></p>"
77
+ def parse(string)
78
+ @out = ""
79
+ @strong = false
80
+ @p = false
81
+ @stack = []
82
+ parse_block(string)
83
+ return @out
84
+ end
85
+
86
+ # Escape any characters with special meaning in HTML using HTML
87
+ # entities.
88
+ private
89
+ def escape_html(string)
90
+ CGI::escapeHTML(string)
91
+ end
92
+
93
+ # Escape any characters with special meaning in URLs using URL
94
+ # encoding.
95
+ private
96
+ def escape_url(string)
97
+ CGI::escape(string)
98
+ end
99
+
100
+ private
101
+
102
+ def start_tag(tag)
103
+ @stack.push(tag)
104
+ @out << '<' << tag << '>'
105
+ end
106
+
107
+ def end_tag
108
+ @out << '</' << @stack.pop << '>'
109
+ end
110
+
111
+ def toggle_tag(tag, match)
112
+ if @stack.include?(tag)
113
+ if @stack.last == tag
114
+ end_tag
115
+ else
116
+ @out << escape_html(match)
117
+ end
118
+ else
119
+ start_tag(tag)
120
+ end
121
+ end
122
+
123
+ def end_paragraph
124
+ end_tag while !@stack.empty?
125
+ @p = false
126
+ end
127
+
128
+ def start_paragraph
129
+ if @p
130
+ @out << ' ' if @out[-1,1] != ' '
131
+ else
132
+ end_paragraph
133
+ start_tag('p')
134
+ @p = true
135
+ end
136
+ end
137
+
138
+ # Create anchor markup for direct links. This
139
+ # method can be overridden to generate custom
140
+ # markup, for example to add html additional attributes.
141
+ private
142
+ def make_direct_anchor(uri, text)
143
+ '<a href="' << escape_html(uri) << '">' << escape_html(text) << '</a>'
144
+ end
145
+
146
+ # Create anchor markup for explicit links. This
147
+ # method can be overridden to generate custom
148
+ # markup, for example to add html additional attributes.
149
+ private
150
+ def make_explicit_anchor(uri, text)
151
+ '<a href="' << escape_html(uri) << '">' << escape_html(text) << '</a>'
152
+ end
153
+
154
+ # Translate an explicit local link to a desired URL that is
155
+ # properly URL-escaped. The default behaviour is to convert local
156
+ # links directly, escaping any characters that have special
157
+ # meaning in URLs. Relative URLs in local links are not handled.
158
+ #
159
+ # Examples:
160
+ #
161
+ # make_local_link("LocalLink") #=> "LocalLink"
162
+ # make_local_link("/Foo/Bar") #=> "%2FFoo%2FBar"
163
+ #
164
+ # Must ensure that the result is properly URL-escaped. The caller
165
+ # will handle HTML escaping as necessary. HTML links will not be
166
+ # inserted if the function returns nil.
167
+ #
168
+ # Example custom behaviour:
169
+ #
170
+ # make_local_link("LocalLink") #=> "/LocalLink"
171
+ # make_local_link("Wikipedia:Bread") #=> "http://en.wikipedia.org/wiki/Bread"
172
+ private
173
+ def make_local_link(link) #:doc:
174
+ escape_url(link)
175
+ end
176
+
177
+ # Sanatize a direct url (e.g. http://wikipedia.org/). The default
178
+ # behaviour returns the original link as-is.
179
+ #
180
+ # Must ensure that the result is properly URL-escaped. The caller
181
+ # will handle HTML escaping as necessary. Links will not be
182
+ # converted to HTML links if the function returns link.
183
+ #
184
+ # Custom versions of this function in inherited classes can
185
+ # implement specific link handling behaviour, such as redirection
186
+ # to intermediate pages (for example, for notifing the user that
187
+ # he is leaving the site).
188
+ private
189
+ def make_direct_link(url) #:doc:
190
+ return url
191
+ end
192
+
193
+ # Sanatize and prefix image URLs. When images are encountered in
194
+ # Creole text, this function is called to obtain the actual URL of
195
+ # the image. The default behaviour is to return the image link
196
+ # as-is. No image tags are inserted if the function returns nil.
197
+ #
198
+ # Custom version of the method can be used to sanatize URLs
199
+ # (e.g. remove query-parts), inhibit off-site images, or add a
200
+ # base URL, for example:
201
+ #
202
+ # def make_image_link(url)
203
+ # URI.join("http://mywiki.org/images/", url)
204
+ # end
205
+ private
206
+ def make_image_link(url) #:doc:
207
+ return url
208
+ end
209
+
210
+ # Create image markup. This
211
+ # method can be overridden to generate custom
212
+ # markup, for example to add html additional attributes or
213
+ # to put divs around the imgs.
214
+ private
215
+ def make_image(uri, alt)
216
+ if alt
217
+ '<img src="' << escape_html(uri) << '" alt="' << escape_html(alt) << '"/>'
218
+ else
219
+ '<img src="' << escape_html(uri) << '"/>'
220
+ end
221
+ end
222
+
223
+ private
224
+ def make_explicit_link(link)
225
+ begin
226
+ uri = URI.parse(link)
227
+ return uri.to_s if uri.scheme && @allowed_schemes.include?(uri.scheme)
228
+ rescue URI::InvalidURIError
229
+ end
230
+ return make_local_link(link)
231
+ end
232
+
233
+ def parse_inline(str)
234
+ until str.empty?
235
+ case str
236
+ when /\A(\~)?((https?|ftps?):\/\/\S+?)(?=([,.?!:;"'\)])?(\s|$))/
237
+ if $1
238
+ @out << escape_html($2)
239
+ else
240
+ if uri = make_direct_link($2)
241
+ @out << make_direct_anchor(uri, $2)
242
+ else
243
+ @out << escape_html($&)
244
+ end
245
+ end
246
+ when /\A\[\[\s*([^|]*?)\s*(\|\s*(.*?))?\s*\]\]/m
247
+ link = $1
248
+ if uri = make_explicit_link(link)
249
+ @out << make_explicit_anchor(uri, $3 || link)
250
+ else
251
+ @out << escape_html($&)
252
+ end
253
+ when /\A\{\{\{(.*)\}\}\}/
254
+ @out << '<tt>' << escape_html($1) << '</tt>'
255
+ when /\A\{\{\s*(.*?)\s*(\|\s*(.*?)\s*)?\}\}/
256
+ if uri = make_image_link($1)
257
+ @out << make_image(uri, $3)
258
+ else
259
+ @out << escape_html($&)
260
+ end
261
+ when /\A~([^\s])/
262
+ @out << escape_html($1)
263
+ when /\A\w+/
264
+ @out << $&
265
+ when /\A\s+/
266
+ @out << ' ' if @out[-1,1] != ' '
267
+ when /\A\*\*/
268
+ toggle_tag 'strong', $&
269
+ when /\A\/\//
270
+ toggle_tag 'em', $&
271
+ when /\A\\\\/
272
+ @out << '<br/>'
273
+ when /./
274
+ @out << escape_html($&)
275
+ else
276
+ raise CreoleParseError, "Parse error at #{str[0,30].inspect}"
277
+ end
278
+ str = $'
279
+ end
280
+ end
281
+
282
+ def parse_table_row(str)
283
+ @out << '<tr>'
284
+ str.scan(/\s*\|(=)?\s*((\[\[.*?\]\]|\{\{.*?\}\}|[^|~]|~.)*)(?=\||$)/) do
285
+ if !$2.empty? || !$'.empty?
286
+ @out << ($1 ? '<th>' : '<td>')
287
+ parse_inline($2) if $2
288
+ end_tag while @stack.last != 'table'
289
+ @out << ($1 ? '</th>' : '</td>')
290
+ end
291
+ end
292
+ @out << '</tr>'
293
+ end
294
+
295
+ def make_nowikiblock(input)
296
+ input.gsub(/^ (?=\}\}\})/, '')
297
+ end
298
+
299
+ def ulol?(x); x == 'ul' || x == 'ol'; end
300
+
301
+ def parse_block(str)
302
+ until str.empty?
303
+ case str
304
+ when /\A\{\{\{\r?\n(.*?)\r?\n\}\}\}/m
305
+ end_paragraph
306
+ nowikiblock = make_nowikiblock($1)
307
+ @out << '<pre>' << escape_html(nowikiblock) << '</pre>'
308
+ when /\A\s*-{4,}\s*$/
309
+ end_paragraph
310
+ @out << '<hr/>'
311
+ when /\A\s*(={1,6})\s*(.*?)\s*=*\s*$(\r?\n)?/
312
+ end_paragraph
313
+ level = $1.size
314
+ @out << "<h#{level}>" << escape_html($2) << "</h#{level}>"
315
+ when /\A[ \t]*\|.*$(\r?\n)?/
316
+ if !@stack.include?('table')
317
+ end_paragraph
318
+ start_tag('table')
319
+ end
320
+ parse_table_row($&)
321
+ when /\A\s*$(\r?\n)?/
322
+ end_paragraph
323
+ when /\A(\s*([*#]+)\s*(.*?))$(\r?\n)?/
324
+ line, bullet, item = $1, $2, $3
325
+ tag = (bullet[0,1] == '*' ? 'ul' : 'ol')
326
+ if bullet[0,1] == '#' || bullet.size != 2 || @stack.find {|x| ulol?(x) }
327
+ count = @stack.select { |x| ulol?(x) }.size
328
+
329
+ while !@stack.empty? && count > bullet.size
330
+ count -= 1 if ulol?(@stack.last)
331
+ end_tag
332
+ end
333
+
334
+ end_tag while !@stack.empty? && @stack.last != 'li'
335
+
336
+ if @stack.last == 'li' && count == bullet.size
337
+ end_tag
338
+ if @stack.last != tag
339
+ end_tag
340
+ count -= 1
341
+ end
342
+ end
343
+
344
+ while count < bullet.size
345
+ start_tag tag
346
+ count += 1
347
+ start_tag 'li' if count < bullet.size
348
+ end
349
+
350
+ @p = true
351
+ start_tag('li')
352
+ parse_inline(item)
353
+ else
354
+ start_paragraph
355
+ parse_inline(line)
356
+ end
357
+ when /\A([ \t]*\S+.*?)$(\r?\n)?/
358
+ start_paragraph
359
+ parse_inline($1)
360
+ else
361
+ raise CreoleParseError, "Parse error at #{str[0,30].inspect}"
362
+ end
363
+ #p [$&, $']
364
+ str = $'
365
+ end
366
+ end_paragraph
367
+ return @out
368
+ end
369
+
370
+ end # class CreoleParser
371
+
372
+ end # module Creole
@@ -0,0 +1,15 @@
1
+ require 'test/unit'
2
+ require 'creole'
3
+ require 'cgi'
4
+ require 'testcases'
5
+
6
+ $strict = false
7
+
8
+ class TestC < Test::Unit::TestCase
9
+ include TestCases
10
+
11
+ def tc(html, creole)
12
+ output = Creole.creolize(creole)
13
+ assert html === output, "Parsing: #{creole.inspect}\nExpected: #{html.inspect}\n Was: #{output.inspect}"
14
+ end
15
+ end
@@ -0,0 +1,631 @@
1
+ require 'cgi'
2
+
3
+ # Test cases for the creole converter. These are included into the
4
+ # unittests, but is implemented as a separated module to be able to
5
+ # import them into demo wikis.
6
+ #
7
+ # Each test case should simply call the 'tc' method with the expected
8
+ # HTML and input Creole formatted text as arguments. The expected HTML
9
+ # should contain minimal amount of whitespace (only the absolutely
10
+ # required).
11
+
12
+ module TestCases
13
+ def escape_html(html)
14
+ CGI::escapeHTML(html)
15
+ end
16
+
17
+ def test_bold
18
+ # Creole1.0: Bold can be used inside paragraphs
19
+ tc "<p>This <strong>is</strong> bold</p>", "This **is** bold"
20
+ tc "<p>This <strong>is</strong> bold and <strong>bold</strong>ish</p>", "This **is** bold and **bold**ish"
21
+
22
+ # Creole1.0: Bold can be used inside list items
23
+ tc "<ul><li>This is <strong>bold</strong></li></ul>", "* This is **bold**"
24
+
25
+ # Creole1.0: Bold can be used inside table cells
26
+ tc("<table><tr><td>This is <strong>bold</strong></td></tr></table>",
27
+ "|This is **bold**|")
28
+
29
+ # Creole1.0: Links can appear inside bold text:
30
+ tc("<p>A bold link: <strong><a href=\"http://wikicreole.org/\">http://wikicreole.org/</a> nice!</strong></p>",
31
+ "A bold link: **http://wikicreole.org/ nice!**")
32
+
33
+ # Creole1.0: Bold will end at the end of paragraph
34
+ tc "<p>This <strong>is bold</strong></p>", "This **is bold"
35
+
36
+ # Creole1.0: Bold will end at the end of list items
37
+ tc("<ul><li>Item <strong>bold</strong></li><li>Item normal</li></ul>",
38
+ "* Item **bold\n* Item normal")
39
+
40
+ # Creole1.0: Bold will end at the end of table cells
41
+ tc("<table><tr><td>Item <strong>bold</strong></td><td>Another <strong>bold</strong></td></tr></table>",
42
+ "|Item **bold|Another **bold")
43
+
44
+ # Creole1.0: Bold should not cross paragraphs
45
+ tc("<p>This <strong>is</strong></p><p>bold<strong> maybe</strong></p>",
46
+ "This **is\n\nbold** maybe")
47
+
48
+ # Creole1.0-Implied: Bold should be able to cross lines
49
+ tc "<p>This <strong>is bold</strong></p>", "This **is\nbold**"
50
+ end
51
+
52
+ def test_italic
53
+ # Creole1.0: Italic can be used inside paragraphs
54
+ tc("<p>This <em>is</em> italic</p>",
55
+ "This //is// italic")
56
+ tc("<p>This <em>is</em> italic and <em>italic</em>ish</p>",
57
+ "This //is// italic and //italic//ish")
58
+
59
+ # Creole1.0: Italic can be used inside list items
60
+ tc "<ul><li>This is <em>italic</em></li></ul>", "* This is //italic//"
61
+
62
+ # Creole1.0: Italic can be used inside table cells
63
+ tc("<table><tr><td>This is <em>italic</em></td></tr></table>",
64
+ "|This is //italic//|")
65
+
66
+ # Creole1.0: Links can appear inside italic text:
67
+ tc("<p>A italic link: <em><a href=\"http://wikicreole.org/\">http://wikicreole.org/</a> nice!</em></p>",
68
+ "A italic link: //http://wikicreole.org/ nice!//")
69
+
70
+ # Creole1.0: Italic will end at the end of paragraph
71
+ tc "<p>This <em>is italic</em></p>", "This //is italic"
72
+
73
+ # Creole1.0: Italic will end at the end of list items
74
+ tc("<ul><li>Item <em>italic</em></li><li>Item normal</li></ul>",
75
+ "* Item //italic\n* Item normal")
76
+
77
+ # Creole1.0: Italic will end at the end of table cells
78
+ tc("<table><tr><td>Item <em>italic</em></td><td>Another <em>italic</em></td></tr></table>",
79
+ "|Item //italic|Another //italic")
80
+
81
+ # Creole1.0: Italic should not cross paragraphs
82
+ tc("<p>This <em>is</em></p><p>italic<em> maybe</em></p>",
83
+ "This //is\n\nitalic// maybe")
84
+
85
+ # Creole1.0-Implied: Italic should be able to cross lines
86
+ tc "<p>This <em>is italic</em></p>", "This //is\nitalic//"
87
+ end
88
+
89
+ def test_bold_italics
90
+ # Creole1.0: By example
91
+ tc "<p><strong><em>bold italics</em></strong></p>", "**//bold italics//**"
92
+
93
+ # Creole1.0: By example
94
+ tc "<p><em><strong>bold italics</strong></em></p>", "//**bold italics**//"
95
+
96
+ # Creole1.0: By example
97
+ tc "<p><em>This is <strong>also</strong> good.</em></p>", "//This is **also** good.//"
98
+ end
99
+
100
+ def test_headings
101
+ # Creole1.0: Only three differed sized levels of heading are required.
102
+ tc "<h1>Heading 1</h1>", "= Heading 1 ="
103
+ tc "<h2>Heading 2</h2>", "== Heading 2 =="
104
+ tc "<h3>Heading 3</h3>", "=== Heading 3 ==="
105
+ unless $strict
106
+ tc "<h4>Heading 4</h4>", "==== Heading 4 ===="
107
+ tc "<h5>Heading 5</h5>", "===== Heading 5 ====="
108
+ tc "<h6>Heading 6</h6>", "====== Heading 6 ======"
109
+ end
110
+
111
+ # Creole1.0: Closing (right-side) equal signs are optional
112
+ tc "<h1>Heading 1</h1>", "=Heading 1"
113
+ tc "<h2>Heading 2</h2>", "== Heading 2"
114
+ tc "<h3>Heading 3</h3>", " === Heading 3"
115
+
116
+ # Creole1.0: Closing (right-side) equal signs don't need to be balanced and don't impact the kind of heading generated
117
+ tc "<h1>Heading 1</h1>", "=Heading 1 ==="
118
+ tc "<h2>Heading 2</h2>", "== Heading 2 ="
119
+ tc "<h3>Heading 3</h3>", " === Heading 3 ==========="
120
+
121
+ # Creole1.0: Whitespace is allowed before the left-side equal signs.
122
+ tc "<h1>Heading 1</h1>", " \t= Heading 1 ="
123
+ tc "<h2>Heading 2</h2>", " \t== Heading 2 =="
124
+
125
+ # Creole1.0: Only white-space characters are permitted after the closing equal signs.
126
+ tc "<h1>Heading 1</h1>", " = Heading 1 = "
127
+ tc "<h2>Heading 2</h2>", " == Heading 2 == \t "
128
+
129
+ # !!Creole1.0 doesn't specify if text after closing equal signs
130
+ # !!becomes part of the heading or invalidates the entire heading.
131
+ # tc "<p> == Heading 2 == foo</p>", " == Heading 2 == foo"
132
+ unless $strict
133
+ tc "<h2>Heading 2 == foo</h2>", " == Heading 2 == foo"
134
+ end
135
+
136
+ # Creole1.0-Implied: Line must start with equal sign
137
+ tc "<p>foo = Heading 1 =</p>", "foo = Heading 1 ="
138
+ end
139
+
140
+ def test_links
141
+ # Creole1.0: Links
142
+ tc "<p><a href=\"link\">link</a></p>", "[[link]]"
143
+
144
+ # Creole1.0: Links can appear in paragraphs (i.e. inline item)
145
+ tc "<p>Hello, <a href=\"world\">world</a></p>", "Hello, [[world]]"
146
+
147
+ # Creole1.0: Named links
148
+ tc "<p><a href=\"MyBigPage\">Go to my page</a></p>", "[[MyBigPage|Go to my page]]"
149
+
150
+ # Creole1.0: URLs
151
+ tc "<p><a href=\"http://www.wikicreole.org/\">http://www.wikicreole.org/</a></p>", "[[http://www.wikicreole.org/]]"
152
+
153
+ # Creole1.0: Free-standing URL's should be turned into links
154
+ tc "<p><a href=\"http://www.wikicreole.org/\">http://www.wikicreole.org/</a></p>", "http://www.wikicreole.org/"
155
+
156
+ # Creole1.0: Single punctuation characters at the end of URLs
157
+ # should not be considered a part of the URL.
158
+ [',','.','?','!',':',';','\'','"'].each { |punct|
159
+ esc_punct = escape_html(punct)
160
+ tc "<p><a href=\"http://www.wikicreole.org/\">http://www.wikicreole.org/</a>#{esc_punct}</p>", "http://www.wikicreole.org/#{punct}"
161
+ }
162
+ # Creole1.0: Nameds URLs (by example)
163
+ tc("<p><a href=\"http://www.wikicreole.org/\">Visit the WikiCreole website</a></p>",
164
+ "[[http://www.wikicreole.org/|Visit the WikiCreole website]]")
165
+
166
+ unless $strict
167
+ # Parsing markup within a link is optional
168
+ tc "<p><a href=\"Weird+Stuff\">**Weird** //Stuff//</a></p>", "[[Weird Stuff|**Weird** //Stuff//]]"
169
+ end
170
+
171
+ # Inside bold
172
+ tc "<p><strong><a href=\"link\">link</a></strong></p>", "**[[link]]**"
173
+
174
+ # Whitespace inside [[ ]] should be ignored
175
+ tc("<p><a href=\"link\">link</a></p>", "[[ link ]]")
176
+ tc("<p><a href=\"link+me\">link me</a></p>", "[[ link me ]]")
177
+ tc("<p><a href=\"http://dot.com/\">dot.com</a></p>", "[[ http://dot.com/ \t| \t dot.com ]]")
178
+ tc("<p><a href=\"http://dot.com/\">dot.com</a></p>", "[[ http://dot.com/ | dot.com ]]")
179
+ end
180
+
181
+ def test_paragraph
182
+ # Creole1.0: One or more blank lines end paragraphs.
183
+ tc "<p>This is my text.</p><p>This is more text.</p>", "This is\nmy text.\n\nThis is\nmore text."
184
+ tc "<p>This is my text.</p><p>This is more text.</p>", "This is\nmy text.\n\n\nThis is\nmore text."
185
+ tc "<p>This is my text.</p><p>This is more text.</p>", "This is\nmy text.\n\n\n\nThis is\nmore text."
186
+
187
+ # Creole1.0: A list end paragraphs too.
188
+ tc "<p>Hello</p><ul><li>Item</li></ul>", "Hello\n* Item\n"
189
+
190
+ # Creole1.0: A table end paragraphs too.
191
+ tc "<p>Hello</p><table><tr><td>Cell</td></tr></table>", "Hello\n|Cell|"
192
+
193
+ # Creole1.0: A nowiki end paragraphs too.
194
+ tc "<p>Hello</p><pre>nowiki</pre>", "Hello\n{{{\nnowiki\n}}}\n"
195
+
196
+ unless $strict
197
+ # A heading ends a paragraph (not specced)
198
+ tc "<p>Hello</p><h1>Heading</h1>", "Hello\n= Heading =\n"
199
+ end
200
+ end
201
+
202
+ def test_linebreak
203
+ # Creole1.0: \\ (wiki-style) for line breaks.
204
+ tc "<p>This is the first line,<br/>and this is the second.</p>", "This is the first line,\\\\and this is the second."
205
+ end
206
+
207
+ def test_unordered_lists
208
+ # Creole1.0: List items begin with a * at the beginning of a line.
209
+ # Creole1.0: An item ends at the next *
210
+ tc "<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>", "* Item 1\n *Item 2\n *\t\tItem 3\n"
211
+
212
+ # Creole1.0: Whitespace is optional before and after the *.
213
+ tc("<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>",
214
+ " * Item 1\n*Item 2\n \t*\t\tItem 3\n")
215
+
216
+ # Creole1.0: A space is required if if the list element starts with bold text.
217
+ tc("<ul><li><ul><li><ul><li>Item 1</li></ul></li></ul></li></ul>", "***Item 1")
218
+ tc("<ul><li><strong>Item 1</strong></li></ul>", "* **Item 1")
219
+
220
+ # Creole1.0: An item ends at blank line
221
+ tc("<ul><li>Item</li></ul><p>Par</p>", "* Item\n\nPar\n")
222
+
223
+ # Creole1.0: An item ends at a heading
224
+ tc("<ul><li>Item</li></ul><h1>Heading</h1>", "* Item\n= Heading =\n")
225
+
226
+ # Creole1.0: An item ends at a table
227
+ tc("<ul><li>Item</li></ul><table><tr><td>Cell</td></tr></table>", "* Item\n|Cell|\n")
228
+
229
+ # Creole1.0: An item ends at a nowiki block
230
+ tc("<ul><li>Item</li></ul><pre>Code</pre>", "* Item\n{{{\nCode\n}}}\n")
231
+
232
+ # Creole1.0: An item can span multiple lines
233
+ tc("<ul><li>The quick brown fox jumps over lazy dog.</li><li>Humpty Dumpty sat on a wall.</li></ul>",
234
+ "* The quick\nbrown fox\n\tjumps over\nlazy dog.\n*Humpty Dumpty\nsat\t\non a wall.")
235
+
236
+ # Creole1.0: An item can contain line breaks
237
+ tc("<ul><li>The quick brown<br/>fox jumps over lazy dog.</li></ul>",
238
+ "* The quick brown\\\\fox jumps over lazy dog.")
239
+
240
+ # Creole1.0: Nested
241
+ tc "<ul><li>Item 1<ul><li>Item 2</li></ul></li><li>Item 3</li></ul>", "* Item 1\n **Item 2\n *\t\tItem 3\n"
242
+
243
+ # Creole1.0: Nested up to 5 levels
244
+ tc("<ul><li>Item 1<ul><li>Item 2<ul><li>Item 3<ul><li>Item 4<ul><li>Item 5</li></ul></li></ul></li></ul></li></ul></li></ul>",
245
+ "*Item 1\n**Item 2\n***Item 3\n****Item 4\n*****Item 5\n")
246
+
247
+ # Creole1.0: ** immediatly following a list element will be treated as a nested unordered element.
248
+ tc("<ul><li>Hello, World!<ul><li>Not bold</li></ul></li></ul>",
249
+ "*Hello,\nWorld!\n**Not bold\n")
250
+
251
+ # Creole1.0: ** immediatly following a list element will be treated as a nested unordered element.
252
+ tc("<ol><li>Hello, World!<ul><li>Not bold</li></ul></li></ol>",
253
+ "#Hello,\nWorld!\n**Not bold\n")
254
+
255
+ # Creole1.0: [...] otherwise it will be treated as the beginning of bold text.
256
+ tc("<ul><li>Hello, World!</li></ul><p><strong>Not bold</strong></p>",
257
+ "*Hello,\nWorld!\n\n**Not bold\n")
258
+ end
259
+
260
+ def test_ordered_lists
261
+ # Creole1.0: List items begin with a * at the beginning of a line.
262
+ # Creole1.0: An item ends at the next *
263
+ tc "<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>", "# Item 1\n #Item 2\n #\t\tItem 3\n"
264
+
265
+ # Creole1.0: Whitespace is optional before and after the #.
266
+ tc("<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>",
267
+ " # Item 1\n#Item 2\n \t#\t\tItem 3\n")
268
+
269
+ # Creole1.0: A space is required if if the list element starts with bold text.
270
+ tc("<ol><li><ol><li><ol><li>Item 1</li></ol></li></ol></li></ol>", "###Item 1")
271
+ tc("<ol><li><strong>Item 1</strong></li></ol>", "# **Item 1")
272
+
273
+ # Creole1.0: An item ends at blank line
274
+ tc("<ol><li>Item</li></ol><p>Par</p>", "# Item\n\nPar\n")
275
+
276
+ # Creole1.0: An item ends at a heading
277
+ tc("<ol><li>Item</li></ol><h1>Heading</h1>", "# Item\n= Heading =\n")
278
+
279
+ # Creole1.0: An item ends at a table
280
+ tc("<ol><li>Item</li></ol><table><tr><td>Cell</td></tr></table>", "# Item\n|Cell|\n")
281
+
282
+ # Creole1.0: An item ends at a nowiki block
283
+ tc("<ol><li>Item</li></ol><pre>Code</pre>", "# Item\n{{{\nCode\n}}}\n")
284
+
285
+ # Creole1.0: An item can span multiple lines
286
+ tc("<ol><li>The quick brown fox jumps over lazy dog.</li><li>Humpty Dumpty sat on a wall.</li></ol>",
287
+ "# The quick\nbrown fox\n\tjumps over\nlazy dog.\n#Humpty Dumpty\nsat\t\non a wall.")
288
+
289
+ # Creole1.0: An item can contain line breaks
290
+ tc("<ol><li>The quick brown<br/>fox jumps over lazy dog.</li></ol>",
291
+ "# The quick brown\\\\fox jumps over lazy dog.")
292
+
293
+ # Creole1.0: Nested
294
+ tc "<ol><li>Item 1<ol><li>Item 2</li></ol></li><li>Item 3</li></ol>", "# Item 1\n ##Item 2\n #\t\tItem 3\n"
295
+
296
+ # Creole1.0: Nested up to 5 levels
297
+ tc("<ol><li>Item 1<ol><li>Item 2<ol><li>Item 3<ol><li>Item 4<ol><li>Item 5</li></ol></li></ol></li></ol></li></ol></li></ol>",
298
+ "#Item 1\n##Item 2\n###Item 3\n####Item 4\n#####Item 5\n")
299
+
300
+ # Creole1.0_Infered: The two-bullet rule only applies to **.
301
+ tc("<ol><li><ol><li>Item</li></ol></li></ol>", "##Item")
302
+ end
303
+
304
+ def test_ordered_lists2
305
+ tc "<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>", "# Item 1\n #Item 2\n #\t\tItem 3\n"
306
+ # Nested
307
+ tc "<ol><li>Item 1<ol><li>Item 2</li></ol></li><li>Item 3</li></ol>", "# Item 1\n ##Item 2\n #\t\tItem 3\n"
308
+ # Multiline
309
+ tc "<ol><li>Item 1 on multiple lines</li></ol>", "# Item 1\non multiple lines"
310
+ end
311
+
312
+ def test_ambiguity_mixed_lists
313
+ # ol following ul
314
+ tc("<ul><li>uitem</li></ul><ol><li>oitem</li></ol>", "*uitem\n#oitem\n")
315
+
316
+ # ul following ol
317
+ tc("<ol><li>uitem</li></ol><ul><li>oitem</li></ul>", "#uitem\n*oitem\n")
318
+
319
+ # 2ol following ul
320
+ tc("<ul><li>uitem<ol><li>oitem</li></ol></li></ul>", "*uitem\n##oitem\n")
321
+
322
+ # 2ul following ol
323
+ tc("<ol><li>uitem<ul><li>oitem</li></ul></li></ol>", "#uitem\n**oitem\n")
324
+
325
+ # 3ol following 3ul
326
+ tc("<ul><li><ul><li><ul><li>uitem</li></ul><ol><li>oitem</li></ol></li></ul></li></ul>", "***uitem\n###oitem\n")
327
+
328
+ # 2ul following 2ol
329
+ tc("<ol><li><ol><li>uitem</li></ol><ul><li>oitem</li></ul></li></ol>", "##uitem\n**oitem\n")
330
+
331
+ # ol following 2ol
332
+ tc("<ol><li><ol><li>oitem1</li></ol></li><li>oitem2</li></ol>", "##oitem1\n#oitem2\n")
333
+ # ul following 2ol
334
+ tc("<ol><li><ol><li>oitem1</li></ol></li></ol><ul><li>oitem2</li></ul>", "##oitem1\n*oitem2\n")
335
+ end
336
+
337
+ def test_ambiguity_italics_and_url
338
+ # Uncommon URL schemes should not be parsed as URLs
339
+ tc("<p>This is what can go wrong:<em>this should be an italic text</em>.</p>",
340
+ "This is what can go wrong://this should be an italic text//.")
341
+
342
+ # A link inside italic text
343
+ tc("<p>How about <em>a link, like <a href=\"http://example.org\">http://example.org</a>, in italic</em> text?</p>",
344
+ "How about //a link, like http://example.org, in italic// text?")
345
+
346
+ # Another test from Creole Wiki
347
+ tc("<p>Formatted fruits, for example:<em>apples</em>, oranges, <strong>pears</strong> ...</p>",
348
+ "Formatted fruits, for example://apples//, oranges, **pears** ...")
349
+
350
+ tc("<p>Blablabala (<a href=\"http://blub.de\">http://blub.de</a>)</p>",
351
+ "Blablabala (http://blub.de)")
352
+ end
353
+
354
+ def test_ambiguity_bold_and_lists
355
+ tc "<p><strong> bold text </strong></p>", "** bold text **"
356
+ tc "<p> <strong> bold text </strong></p>", " ** bold text **"
357
+ end
358
+
359
+ def test_nowiki
360
+ # ... works as block
361
+ tc "<pre>Hello</pre>", "{{{\nHello\n}}}\n"
362
+
363
+ # ... works inline
364
+ tc "<p>Hello <tt>world</tt>.</p>", "Hello {{{world}}}."
365
+
366
+ # Creole1.0: No wiki markup is interpreted inbetween
367
+ tc "<pre>**Hello**</pre>", "{{{\n**Hello**\n}}}\n"
368
+
369
+ # Creole1.0: Leading whitespaces are not permitted
370
+ tc("<p> {{{ Hello }}}</p>", " {{{\nHello\n}}}")
371
+ tc("<p>{{{ Hello }}}</p>", "{{{\nHello\n }}}")
372
+
373
+ # Assumed: Should preserve whitespace
374
+ tc("<pre> \t Hello, \t \n \t World \t </pre>",
375
+ "{{{\n \t Hello, \t \n \t World \t \n}}}\n")
376
+
377
+ # In preformatted blocks ... one leading space is removed
378
+ tc("<pre>nowikiblock\n}}}</pre>", "{{{\nnowikiblock\n }}}\n}}}\n")
379
+
380
+ # In inline nowiki, any trailing closing brace is included in the span
381
+ tc("<p>this is <tt>nowiki}</tt></p>", "this is {{{nowiki}}}}")
382
+ tc("<p>this is <tt>nowiki}}</tt></p>", "this is {{{nowiki}}}}}")
383
+ tc("<p>this is <tt>nowiki}}}</tt></p>", "this is {{{nowiki}}}}}}")
384
+ tc("<p>this is <tt>nowiki}}}}</tt></p>", "this is {{{nowiki}}}}}}}")
385
+ end
386
+
387
+ def test_html_escaping
388
+ # Special HTML chars should be escaped
389
+ tc("<p>&lt;b&gt;not bold&lt;/b&gt;</p>", "<b>not bold</b>")
390
+
391
+ # Image tags should be escape
392
+ tc("<p><img src=\"image.jpg\" alt=\"&quot;tag&quot;\"/></p>", "{{image.jpg|\"tag\"}}")
393
+
394
+ # Malicious links should not be converted.
395
+ tc("<p><a href=\"javascript%3Aalert%28%22Boo%21%22%29\">Click</a></p>", "[[javascript:alert(\"Boo!\")|Click]]")
396
+ end
397
+
398
+ def test_escape
399
+ tc "<p>** Not Bold **</p>", "~** Not Bold ~**"
400
+ tc "<p>// Not Italic //</p>", "~// Not Italic ~//"
401
+ tc "<p>* Not Bullet</p>", "~* Not Bullet"
402
+ # Following char is not a blank (space or line feed)
403
+ tc "<p>Hello ~ world</p>", "Hello ~ world\n"
404
+ tc "<p>Hello ~ world</p>", "Hello ~\nworld\n"
405
+ # Not escaping inside URLs (Creole1.0 not clear on this)
406
+ tc "<p><a href=\"http://example.org/~user/\">http://example.org/~user/</a></p>", "http://example.org/~user/"
407
+
408
+ # Escaping links
409
+ tc "<p>http://www.wikicreole.org/</p>", "~http://www.wikicreole.org/"
410
+ end
411
+
412
+ def test_horizontal_rule
413
+ # Creole: Four hyphens make a horizontal rule
414
+ tc "<hr/>", "----"
415
+
416
+ # Creole1.0: Whitespace around them is allowed
417
+ tc "<hr/>", " ----"
418
+ tc "<hr/>", "---- "
419
+ tc "<hr/>", " ---- "
420
+ tc "<hr/>", " \t ---- \t "
421
+
422
+ # Creole1.0: Nothing else than hyphens and whitespace is "allowed"
423
+ tc "<p>foo ----</p>", "foo ----\n"
424
+ tc "<p>---- foo</p>", "---- foo\n"
425
+
426
+ # Creole1.0: [...] no whitespace is allowed between them
427
+ tc "<p> -- -- </p>", " -- -- "
428
+ tc "<p> -- -- </p>", " --\t-- "
429
+ end
430
+
431
+ def test_table
432
+ tc "<table><tr><td>Hello, World!</td></tr></table>", "|Hello, World!|"
433
+ # Multiple columns
434
+ tc "<table><tr><td>c1</td><td>c2</td><td>c3</td></tr></table>", "|c1|c2|c3|"
435
+ # Multiple rows
436
+ tc "<table><tr><td>c11</td><td>c12</td></tr><tr><td>c21</td><td>c22</td></tr></table>", "|c11|c12|\n|c21|c22|\n"
437
+ # End pipe is optional
438
+ tc "<table><tr><td>c1</td><td>c2</td><td>c3</td></tr></table>", "|c1|c2|c3"
439
+ # Empty cells
440
+ tc "<table><tr><td>c1</td><td></td><td>c3</td></tr></table>", "|c1||c3"
441
+ # Escaping cell separator
442
+ tc "<table><tr><td>c1|c2</td><td>c3</td></tr></table>", "|c1~|c2|c3"
443
+ # Escape in last cell + empty cell
444
+ tc "<table><tr><td>c1</td><td>c2|</td></tr></table>", "|c1|c2~|"
445
+ tc "<table><tr><td>c1</td><td>c2|</td></tr></table>", "|c1|c2~||"
446
+ tc "<table><tr><td>c1</td><td>c2|</td><td></td></tr></table>", "|c1|c2~|||"
447
+ # Equal sign after pipe make a header
448
+ tc "<table><tr><th>Header</th></tr></table>", "|=Header|"
449
+
450
+ tc "<table><tr><td>c1</td><td><a href=\"Link\">Link text</a></td><td><img src=\"Image\" alt=\"Image text\"/></td></tr></table>", "|c1|[[Link|Link text]]|{{Image|Image text}}|"
451
+ end
452
+
453
+ def test_following_table
454
+ # table followed by heading
455
+ tc("<table><tr><td>table</td></tr></table><h1>heading</h1>", "|table|\n=heading=\n")
456
+ tc("<table><tr><td>table</td></tr></table><h1>heading</h1>", "|table|\n\n=heading=\n")
457
+ # table followed by paragraph
458
+ tc("<table><tr><td>table</td></tr></table><p>par</p>", "|table|\npar\n")
459
+ tc("<table><tr><td>table</td></tr></table><p>par</p>", "|table|\n\npar\n")
460
+ # table followed by unordered list
461
+ tc("<table><tr><td>table</td></tr></table><ul><li>item</li></ul>", "|table|\n*item\n")
462
+ tc("<table><tr><td>table</td></tr></table><ul><li>item</li></ul>", "|table|\n\n*item\n")
463
+ # table followed by ordered list
464
+ tc("<table><tr><td>table</td></tr></table><ol><li>item</li></ol>", "|table|\n#item\n")
465
+ tc("<table><tr><td>table</td></tr></table><ol><li>item</li></ol>", "|table|\n\n#item\n")
466
+ # table followed by horizontal rule
467
+ tc("<table><tr><td>table</td></tr></table><hr/>", "|table|\n----\n")
468
+ tc("<table><tr><td>table</td></tr></table><hr/>", "|table|\n\n----\n")
469
+ # table followed by nowiki block
470
+ tc("<table><tr><td>table</td></tr></table><pre>pre</pre>", "|table|\n{{{\npre\n}}}\n")
471
+ tc("<table><tr><td>table</td></tr></table><pre>pre</pre>", "|table|\n\n{{{\npre\n}}}\n")
472
+ # table followed by table
473
+ tc("<table><tr><td>table</td></tr><tr><td>table</td></tr></table>", "|table|\n|table|\n")
474
+ tc("<table><tr><td>table</td></tr></table><table><tr><td>table</td></tr></table>", "|table|\n\n|table|\n")
475
+ end
476
+
477
+ def test_following_heading
478
+ # heading
479
+ tc("<h1>heading1</h1><h1>heading2</h1>", "=heading1=\n=heading2\n")
480
+ tc("<h1>heading1</h1><h1>heading2</h1>", "=heading1=\n\n=heading2\n")
481
+ # paragraph
482
+ tc("<h1>heading</h1><p>par</p>", "=heading=\npar\n")
483
+ tc("<h1>heading</h1><p>par</p>", "=heading=\n\npar\n")
484
+ # unordered list
485
+ tc("<h1>heading</h1><ul><li>item</li></ul>", "=heading=\n*item\n")
486
+ tc("<h1>heading</h1><ul><li>item</li></ul>", "=heading=\n\n*item\n")
487
+ # ordered list
488
+ tc("<h1>heading</h1><ol><li>item</li></ol>", "=heading=\n#item\n")
489
+ tc("<h1>heading</h1><ol><li>item</li></ol>", "=heading=\n\n#item\n")
490
+ # horizontal rule
491
+ tc("<h1>heading</h1><hr/>", "=heading=\n----\n")
492
+ tc("<h1>heading</h1><hr/>", "=heading=\n\n----\n")
493
+ # nowiki block
494
+ tc("<h1>heading</h1><pre>nowiki</pre>", "=heading=\n{{{\nnowiki\n}}}\n")
495
+ tc("<h1>heading</h1><pre>nowiki</pre>", "=heading=\n\n{{{\nnowiki\n}}}\n")
496
+ # table
497
+ tc("<h1>heading</h1><table><tr><td>table</td></tr></table>", "=heading=\n|table|\n")
498
+ tc("<h1>heading</h1><table><tr><td>table</td></tr></table>", "=heading=\n\n|table|\n")
499
+ end
500
+
501
+ def test_following_paragraph
502
+ # heading
503
+ tc("<p>par</p><h1>heading</h1>", "par\n=heading=")
504
+ tc("<p>par</p><h1>heading</h1>", "par\n\n=heading=")
505
+ # paragraph
506
+ tc("<p>par par</p>", "par\npar\n")
507
+ tc("<p>par</p><p>par</p>", "par\n\npar\n")
508
+ # unordered
509
+ tc("<p>par</p><ul><li>item</li></ul>", "par\n*item")
510
+ tc("<p>par</p><ul><li>item</li></ul>", "par\n\n*item")
511
+ # ordered
512
+ tc("<p>par</p><ol><li>item</li></ol>", "par\n#item\n")
513
+ tc("<p>par</p><ol><li>item</li></ol>", "par\n\n#item\n")
514
+ # horizontal
515
+ tc("<p>par</p><hr/>", "par\n----\n")
516
+ tc("<p>par</p><hr/>", "par\n\n----\n")
517
+ # nowiki
518
+ tc("<p>par</p><pre>nowiki</pre>", "par\n{{{\nnowiki\n}}}\n")
519
+ tc("<p>par</p><pre>nowiki</pre>", "par\n\n{{{\nnowiki\n}}}\n")
520
+ # table
521
+ tc("<p>par</p><table><tr><td>table</td></tr></table>", "par\n|table|\n")
522
+ tc("<p>par</p><table><tr><td>table</td></tr></table>", "par\n\n|table|\n")
523
+ end
524
+
525
+ def test_following_unordered_list
526
+ # heading
527
+ tc("<ul><li>item</li></ul><h1>heading</h1>", "*item\n=heading=")
528
+ tc("<ul><li>item</li></ul><h1>heading</h1>", "*item\n\n=heading=")
529
+ # paragraph
530
+ tc("<ul><li>item par</li></ul>", "*item\npar\n") # items may span multiple lines
531
+ tc("<ul><li>item</li></ul><p>par</p>", "*item\n\npar\n")
532
+ # unordered
533
+ tc("<ul><li>item</li><li>item</li></ul>", "*item\n*item\n")
534
+ tc("<ul><li>item</li></ul><ul><li>item</li></ul>", "*item\n\n*item\n")
535
+ # ordered
536
+ tc("<ul><li>item</li></ul><ol><li>item</li></ol>", "*item\n#item\n")
537
+ tc("<ul><li>item</li></ul><ol><li>item</li></ol>", "*item\n\n#item\n")
538
+ # horizontal rule
539
+ tc("<ul><li>item</li></ul><hr/>", "*item\n----\n")
540
+ tc("<ul><li>item</li></ul><hr/>", "*item\n\n----\n")
541
+ # nowiki
542
+ tc("<ul><li>item</li></ul><pre>nowiki</pre>", "*item\n{{{\nnowiki\n}}}\n")
543
+ tc("<ul><li>item</li></ul><pre>nowiki</pre>", "*item\n\n{{{\nnowiki\n}}}\n")
544
+ # table
545
+ tc("<ul><li>item</li></ul><table><tr><td>table</td></tr></table>", "*item\n|table|\n")
546
+ tc("<ul><li>item</li></ul><table><tr><td>table</td></tr></table>", "*item\n\n|table|\n")
547
+ end
548
+
549
+ def test_following_ordered_list
550
+ # heading
551
+ tc("<ol><li>item</li></ol><h1>heading</h1>", "#item\n=heading=")
552
+ tc("<ol><li>item</li></ol><h1>heading</h1>", "#item\n\n=heading=")
553
+ # paragraph
554
+ tc("<ol><li>item par</li></ol>", "#item\npar\n") # items may span multiple lines
555
+ tc("<ol><li>item</li></ol><p>par</p>", "#item\n\npar\n")
556
+ # unordered
557
+ tc("<ol><li>item</li></ol><ul><li>item</li></ul>", "#item\n*item\n")
558
+ tc("<ol><li>item</li></ol><ul><li>item</li></ul>", "#item\n\n*item\n")
559
+ # ordered
560
+ tc("<ol><li>item</li><li>item</li></ol>", "#item\n#item\n")
561
+ tc("<ol><li>item</li></ol><ol><li>item</li></ol>", "#item\n\n#item\n")
562
+ # horizontal role
563
+ tc("<ol><li>item</li></ol><hr/>", "#item\n----\n")
564
+ tc("<ol><li>item</li></ol><hr/>", "#item\n\n----\n")
565
+ # nowiki
566
+ tc("<ol><li>item</li></ol><pre>nowiki</pre>", "#item\n{{{\nnowiki\n}}}\n")
567
+ tc("<ol><li>item</li></ol><pre>nowiki</pre>", "#item\n\n{{{\nnowiki\n}}}\n")
568
+ # table
569
+ tc("<ol><li>item</li></ol><table><tr><td>table</td></tr></table>", "#item\n|table|\n")
570
+ tc("<ol><li>item</li></ol><table><tr><td>table</td></tr></table>", "#item\n\n|table|\n")
571
+ end
572
+
573
+ def test_following_horizontal_rule
574
+ # heading
575
+ tc("<hr/><h1>heading</h1>", "----\n=heading=")
576
+ tc("<hr/><h1>heading</h1>", "----\n\n=heading=")
577
+ # paragraph
578
+ tc("<hr/><p>par</p>", "----\npar\n")
579
+ tc("<hr/><p>par</p>", "----\n\npar\n")
580
+ # unordered
581
+ tc("<hr/><ul><li>item</li></ul>", "----\n*item")
582
+ tc("<hr/><ul><li>item</li></ul>", "----\n*item")
583
+ # ordered
584
+ tc("<hr/><ol><li>item</li></ol>", "----\n#item")
585
+ tc("<hr/><ol><li>item</li></ol>", "----\n#item")
586
+ # horizontal
587
+ tc("<hr/><hr/>", "----\n----\n")
588
+ tc("<hr/><hr/>", "----\n\n----\n")
589
+ # nowiki
590
+ tc("<hr/><pre>nowiki</pre>", "----\n{{{\nnowiki\n}}}\n")
591
+ tc("<hr/><pre>nowiki</pre>", "----\n\n{{{\nnowiki\n}}}\n")
592
+ # table
593
+ tc("<hr/><table><tr><td>table</td></tr></table>", "----\n|table|\n")
594
+ tc("<hr/><table><tr><td>table</td></tr></table>", "----\n\n|table|\n")
595
+ end
596
+
597
+ def test_following_nowiki_block
598
+ # heading
599
+ tc("<pre>nowiki</pre><h1>heading</h1>", "{{{\nnowiki\n}}}\n=heading=")
600
+ tc("<pre>nowiki</pre><h1>heading</h1>", "{{{\nnowiki\n}}}\n\n=heading=")
601
+ # paragraph
602
+ tc("<pre>nowiki</pre><p>par</p>", "{{{\nnowiki\n}}}\npar")
603
+ tc("<pre>nowiki</pre><p>par</p>", "{{{\nnowiki\n}}}\n\npar")
604
+ # unordered
605
+ tc("<pre>nowiki</pre><ul><li>item</li></ul>", "{{{\nnowiki\n}}}\n*item\n")
606
+ tc("<pre>nowiki</pre><ul><li>item</li></ul>", "{{{\nnowiki\n}}}\n\n*item\n")
607
+ # ordered
608
+ tc("<pre>nowiki</pre><ol><li>item</li></ol>", "{{{\nnowiki\n}}}\n#item\n")
609
+ tc("<pre>nowiki</pre><ol><li>item</li></ol>", "{{{\nnowiki\n}}}\n\n#item\n")
610
+ # horizontal
611
+ tc("<pre>nowiki</pre><hr/>", "{{{\nnowiki\n}}}\n----\n")
612
+ tc("<pre>nowiki</pre><hr/>", "{{{\nnowiki\n}}}\n\n----\n")
613
+ # nowiki
614
+ tc("<pre>nowiki</pre><pre>nowiki</pre>", "{{{\nnowiki\n}}}\n{{{\nnowiki\n}}}\n")
615
+ tc("<pre>nowiki</pre><pre>nowiki</pre>", "{{{\nnowiki\n}}}\n\n{{{\nnowiki\n}}}\n")
616
+ # table
617
+ tc("<pre>nowiki</pre><table><tr><td>table</td></tr></table>", "{{{\nnowiki\n}}}\n|table|\n")
618
+ tc("<pre>nowiki</pre><table><tr><td>table</td></tr></table>", "{{{\nnowiki\n}}}\n\n|table|\n")
619
+ end
620
+
621
+ def test_image
622
+ tc("<p><img src=\"image.jpg\"/></p>", "{{image.jpg}}")
623
+ tc("<p><img src=\"image.jpg\" alt=\"tag\"/></p>", "{{image.jpg|tag}}")
624
+ tc("<p><img src=\"http://example.org/image.jpg\"/></p>", "{{http://example.org/image.jpg}}")
625
+ end
626
+
627
+ def test_bold_combo
628
+ tc("<p><strong>bold and</strong></p><table><tr><td>table</td></tr></table><p>end<strong></strong></p>",
629
+ "**bold and\n|table|\nend**")
630
+ end
631
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: creole
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.3
5
+ platform: ruby
6
+ authors:
7
+ - Lars Christensen
8
+ - Daniel Mendler
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-02-16 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: hoe
18
+ type: :development
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.8.3
25
+ version:
26
+ description: Creole is a Creole-to-HTML converter for Creole, the lightwight markup language (http://wikicreole.org/).
27
+ email:
28
+ - larsch@belunktum.dk
29
+ - mail@daniel-mendler.de
30
+ executables: []
31
+
32
+ extensions: []
33
+
34
+ extra_rdoc_files:
35
+ - Manifest.txt
36
+ - README.txt
37
+ files:
38
+ - Manifest.txt
39
+ - README.txt
40
+ - Rakefile
41
+ - lib/creole.rb
42
+ - test/test_creole.rb
43
+ - test/testcases.rb
44
+ has_rdoc: true
45
+ homepage: http://github.com/minad/creole
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --main
49
+ - README.txt
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project: creole
67
+ rubygems_version: 1.3.1
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: Creole is a Creole-to-HTML converter for Creole, the lightwight markup language (http://wikicreole.org/).
71
+ test_files:
72
+ - test/test_creole.rb