marker 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/marker/language.treetop +39 -15
- data/lib/marker/links.rb +19 -5
- data/lib/marker/templates.rb +10 -4
- data/lib/marker/text.rb +17 -0
- data/lib/marker/verbatim.rb +0 -11
- data/test/formatting_test.rb +98 -0
- data/test/headings_test.rb +77 -0
- data/test/links_test.rb +109 -0
- data/test/lists_test.rb +73 -0
- data/test/templates_test.rb +52 -0
- data/test/test_helper.rb +2 -0
- data/test/verbatim_test.rb +20 -0
- metadata +10 -4
data/lib/marker/language.treetop
CHANGED
@@ -183,7 +183,9 @@ module Marker
|
|
183
183
|
# graph
|
184
184
|
# MediaWiki renders (newlines removed): <hr /><p>a para-</p><p>graph</p>
|
185
185
|
# this renders (newlines removed): <hr /><p>a para-graph</p>
|
186
|
-
"----" "-"* ws
|
186
|
+
"----" "-"* ws t:unsafe_text <HorizRule>
|
187
|
+
/
|
188
|
+
"----" "-"* <HorizRule>
|
187
189
|
end
|
188
190
|
|
189
191
|
##### combination rules
|
@@ -195,6 +197,20 @@ module Marker
|
|
195
197
|
!line h:phrase "" <Paragraph>
|
196
198
|
end
|
197
199
|
|
200
|
+
# a block of text that does not require a !line check
|
201
|
+
#
|
202
|
+
# for situations where text may follow structures that are normally on a
|
203
|
+
# single line---e.g., horizontal rules--- the text should be handled like a
|
204
|
+
# paragraph on a new line, but using the text rule will cause errors when
|
205
|
+
# the text starts like a special line: cases like this: "---- ----".
|
206
|
+
# Because it follows a structure without a new line, it is safe to assume
|
207
|
+
# the text is a phrase.
|
208
|
+
rule unsafe_text
|
209
|
+
h:phrase ws rnl r:text <Paragraph>
|
210
|
+
/
|
211
|
+
h:phrase "" <Paragraph>
|
212
|
+
end
|
213
|
+
|
198
214
|
# a phrase of words without newlines
|
199
215
|
rule phrase
|
200
216
|
h:word ws r:phrase <Phrase>
|
@@ -312,6 +328,7 @@ module Marker
|
|
312
328
|
# [[ link target | link label ]]
|
313
329
|
# * can contain white space
|
314
330
|
# * cannot contain new lines
|
331
|
+
#-- TODO: handle [[ url | label ]] and variants ++
|
315
332
|
rule internal_link
|
316
333
|
internal_link_start ws t:plain_text ws a:arg_delimiter ws l:internal_link_enclosed_text ws internal_link_end <InternalLink>
|
317
334
|
/
|
@@ -333,8 +350,6 @@ module Marker
|
|
333
350
|
/
|
334
351
|
template
|
335
352
|
/
|
336
|
-
url
|
337
|
-
/
|
338
353
|
plain_word
|
339
354
|
/
|
340
355
|
bold_toggle
|
@@ -366,15 +381,24 @@ module Marker
|
|
366
381
|
# renders differently from MediaWiki:
|
367
382
|
# [ external [[internal]] ]
|
368
383
|
# MediaWiki: <a href="external"></a><a href="internal">internal</a>
|
369
|
-
#
|
384
|
+
# Marker: <a href="external">[[internal]]</a>
|
385
|
+
#
|
386
|
+
# also use this rule to match bad internal link syntax [[ url | label ]]
|
387
|
+
# because the rendering rules are the same
|
370
388
|
rule external_link
|
371
|
-
external_link_start ws t:url rws l:external_link_enclosed_text ws external_link_end <ExternalLink>
|
372
|
-
/
|
373
|
-
external_link_start ws t:url ws external_link_end <ExternalLink>
|
374
|
-
/
|
389
|
+
# external_link_start ws t:url rws l:external_link_enclosed_text ws external_link_end <ExternalLink>
|
390
|
+
# /
|
391
|
+
# external_link_start ws t:url ws external_link_end <ExternalLink>
|
392
|
+
# /
|
375
393
|
external_link_start ws t:implicit_url rws l:external_link_enclosed_text ws external_link_end <ExternalLink>
|
376
394
|
/
|
377
395
|
external_link_start ws t:implicit_url ws external_link_end <ExternalLink>
|
396
|
+
/
|
397
|
+
internal_link_start ws t:implicit_url ws arg_delimiter ws l:internal_link_enclosed_text ws internal_link_end <ExternalLink>
|
398
|
+
/
|
399
|
+
internal_link_start ws t:implicit_url rws l:internal_link_enclosed_text ws internal_link_end <ExternalLink>
|
400
|
+
/
|
401
|
+
internal_link_start ws t:implicit_url ws internal_link_end <ExternalLink>
|
378
402
|
end
|
379
403
|
|
380
404
|
rule external_link_enclosed_text
|
@@ -425,12 +449,6 @@ module Marker
|
|
425
449
|
h:arg aws arg_delimiter aws r:arg_list <Arguments>
|
426
450
|
/
|
427
451
|
h:arg "" <Arguments>
|
428
|
-
/
|
429
|
-
aws "" <Arguments> {
|
430
|
-
def h
|
431
|
-
nil
|
432
|
-
end
|
433
|
-
}
|
434
452
|
end
|
435
453
|
|
436
454
|
# a plain (positional) argument or a named (name=text) argument
|
@@ -438,6 +456,8 @@ module Marker
|
|
438
456
|
name:plain_text aws heading_toggle aws val:arg_list_enclosed_text <Argument>
|
439
457
|
/
|
440
458
|
val:arg_list_enclosed_text "" <Argument>
|
459
|
+
/
|
460
|
+
"" "" <Argument>
|
441
461
|
end
|
442
462
|
|
443
463
|
rule arg_list_enclosed_text
|
@@ -650,12 +670,16 @@ module Marker
|
|
650
670
|
[A-Fa-f0-9]
|
651
671
|
end
|
652
672
|
|
673
|
+
#-- TODO: Handle windows newlines (\r\n) ++
|
674
|
+
|
653
675
|
# required new lines
|
676
|
+
# just one!
|
654
677
|
rule rnl
|
655
|
-
"\n"
|
678
|
+
"\n"
|
656
679
|
end
|
657
680
|
|
658
681
|
# new lines
|
682
|
+
#-- TODO: should this be broken into exactly one and any number rules? ++
|
659
683
|
rule nl
|
660
684
|
"\n"*
|
661
685
|
end
|
data/lib/marker/links.rb
CHANGED
@@ -80,7 +80,7 @@ module Marker #:nodoc:
|
|
80
80
|
n = f.add( target )
|
81
81
|
"<a href='#{target}'>[#{n}]</a>"
|
82
82
|
else
|
83
|
-
"<a href='#{target}'
|
83
|
+
"<a href='#{target}'>#{target}</a>"
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -136,14 +136,28 @@ module Marker #:nodoc:
|
|
136
136
|
end
|
137
137
|
|
138
138
|
class URL < ParseNode
|
139
|
-
# TODO: these should output links just like "[url]". The link tags
|
140
|
-
# shouldn't call these methods, these are called when the URL is not in a
|
141
|
-
# link. The link templates should grab the URL themselves.
|
142
139
|
def to_html( options = {} )
|
143
|
-
|
140
|
+
f = options[:footnotes]
|
141
|
+
if f
|
142
|
+
n = f.add( bare_url )
|
143
|
+
"<a href='#{bare_url}'>[#{n}]</a>"
|
144
|
+
else
|
145
|
+
"<a href='#{bare_url}'>#{bare_url}</a>"
|
146
|
+
end
|
144
147
|
end
|
145
148
|
|
146
149
|
def to_s( options = {} )
|
150
|
+
f = options[:footnotes]
|
151
|
+
if f
|
152
|
+
n = f.add( bare_url )
|
153
|
+
"[#{n}]"
|
154
|
+
else
|
155
|
+
bare_url
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# returns just the URL that was matched
|
160
|
+
def bare_url
|
147
161
|
text_value
|
148
162
|
end
|
149
163
|
end
|
data/lib/marker/templates.rb
CHANGED
@@ -48,19 +48,21 @@ module Marker #:nodoc:
|
|
48
48
|
when :html
|
49
49
|
to_a.each do |a|
|
50
50
|
next unless a
|
51
|
+
value = ( a.val ? a.val.to_html(options) : "" )
|
51
52
|
if a.name
|
52
|
-
named_params[a.name.
|
53
|
+
named_params[a.name.to_s(options)] = value
|
53
54
|
else
|
54
|
-
pos_params <<
|
55
|
+
pos_params << value
|
55
56
|
end
|
56
57
|
end
|
57
58
|
else
|
58
59
|
to_a.each do |a|
|
59
60
|
next unless a
|
61
|
+
value = ( a.val ? a.val.to_s(options) : "" )
|
60
62
|
if a.name
|
61
|
-
named_params[a.name.to_s(
|
63
|
+
named_params[a.name.to_s(options)] = value
|
62
64
|
else
|
63
|
-
pos_params <<
|
65
|
+
pos_params << value
|
64
66
|
end
|
65
67
|
end
|
66
68
|
end
|
@@ -94,6 +96,10 @@ module Marker #:nodoc:
|
|
94
96
|
def name #:nodoc:
|
95
97
|
nil
|
96
98
|
end
|
99
|
+
|
100
|
+
def val
|
101
|
+
nil
|
102
|
+
end
|
97
103
|
end
|
98
104
|
|
99
105
|
# A set of basic templates for rendering
|
data/lib/marker/text.rb
CHANGED
@@ -74,6 +74,23 @@ module Marker #:nodoc:
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
+
class HorizRule < ParseNode
|
78
|
+
def to_html( options = {} )
|
79
|
+
"<hr />" +
|
80
|
+
( t ? "\n#{t.to_html(options)}" : "" )
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_s( options = {} )
|
84
|
+
width = options[:width] || 80
|
85
|
+
"-" * width +
|
86
|
+
( t ? "\n#{t.to_s(options)}" : "" )
|
87
|
+
end
|
88
|
+
|
89
|
+
def t
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
77
94
|
class Bold < ParseNode
|
78
95
|
def to_html( options = {} )
|
79
96
|
"<b>#{bold_enclosed_text.to_html(options)}</b>"
|
data/lib/marker/verbatim.rb
CHANGED
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require 'marker'
|
3
|
+
|
4
|
+
class FormattingTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_bold_formatting
|
7
|
+
text = "'''bold'''"
|
8
|
+
markup = Marker.parse text
|
9
|
+
|
10
|
+
assert_match("<p><b>bold</b></p>", markup.to_html)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_italic_formatting
|
14
|
+
text = "''italic''"
|
15
|
+
markup = Marker.parse text
|
16
|
+
|
17
|
+
assert_match("<p><i>italic</i></p>", markup.to_html)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_bold_italic_formatting
|
21
|
+
# starting and finishing bold-italic
|
22
|
+
text = "'''''bold & italic'''''"
|
23
|
+
markup = Marker.parse text
|
24
|
+
assert_match("<p><b><i>bold & italic</i></b></p>", markup.to_html)
|
25
|
+
|
26
|
+
# starting italic, finishing bold-italic
|
27
|
+
text = "''italic'''bold & italic'''''"
|
28
|
+
markup = Marker.parse text
|
29
|
+
assert_match("<p><i>italic<b>bold & italic</b></i></p>", markup.to_html)
|
30
|
+
|
31
|
+
# starting bold, finishing bold-italic
|
32
|
+
text = "'''bold''bold & italic'''''"
|
33
|
+
markup = Marker.parse text
|
34
|
+
assert_match("<p><b>bold<i>bold & italic</i></b></p>", markup.to_html)
|
35
|
+
|
36
|
+
# starting bold-italic, finishing bold
|
37
|
+
text = "'''''bold & italic''bold'''"
|
38
|
+
markup = Marker.parse text
|
39
|
+
assert_match("<p><b><i>bold & italic</i>bold</b></p>", markup.to_html)
|
40
|
+
|
41
|
+
# starting bold-italic, finishing italic
|
42
|
+
#
|
43
|
+
# known issue: this doesn't work as "expected" due to treetop's
|
44
|
+
# short-circuiting (PEG); note that the opposite (bold outside italic)
|
45
|
+
# works fine
|
46
|
+
#
|
47
|
+
# TODO: maybe catch this case with a special grammar rule?
|
48
|
+
#
|
49
|
+
# doesn't work:
|
50
|
+
text = "'''''word'''word''"
|
51
|
+
markup = Marker.parse text
|
52
|
+
assert_match("<p>'''<i>word</i>'word''</p>", markup.to_html)
|
53
|
+
# works fine if given a space to be more clear:
|
54
|
+
text = "'' '''bold & italic'''italic''"
|
55
|
+
markup = Marker.parse text
|
56
|
+
assert_match("<p><i><b>bold & italic</b>italic</i></p>", markup.to_html)
|
57
|
+
|
58
|
+
# improper nesting
|
59
|
+
#
|
60
|
+
# marker will not catch improper nesting:
|
61
|
+
# * MediaWiki: <p><i>one<b>two</b></i><b>three</b></p>
|
62
|
+
# * Marker: <p><i>one</i>'two<i>three</i>'</p>
|
63
|
+
text = "''one'''two''three'''"
|
64
|
+
markup = Marker.parse text
|
65
|
+
assert_match("<p><i>one</i>'two<i>three</i>'</p>", markup.to_html)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_paragraphs
|
69
|
+
text = "paragraph 1\n\nparagraph 2\n\nparagraph 3"
|
70
|
+
markup = Marker.parse text
|
71
|
+
|
72
|
+
assert_match("<p>paragraph 1</p>\n\n<p>paragraph 2</p>\n\n<p>paragraph 3</p>", markup.to_html)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_newlines_in_paragraphs
|
76
|
+
# text lines separated by only one newline
|
77
|
+
# this matches how MediaWiki renders
|
78
|
+
text = "word1\nword2\nword3"
|
79
|
+
markup = Marker.parse text
|
80
|
+
|
81
|
+
assert_match("<p>word1 word2 word3</p>", markup.to_html)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_horizontal_rule
|
85
|
+
text = "----"
|
86
|
+
markup = Marker.parse text
|
87
|
+
|
88
|
+
assert_match("<hr />\n", markup.to_html)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_invalid_horizontal_rule
|
92
|
+
text = "---- ----"
|
93
|
+
markup = Marker.parse text
|
94
|
+
|
95
|
+
assert_match("<hr />\n<p>----</p>", markup.to_html)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require 'marker'
|
3
|
+
|
4
|
+
class HeadingTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_level_one
|
7
|
+
text = "= Level 1 ="
|
8
|
+
markup = Marker.parse text
|
9
|
+
|
10
|
+
assert_match("<h1>Level 1</h1>", markup.to_html)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_level_two
|
14
|
+
text = "== Level 2 =="
|
15
|
+
markup = Marker.parse text
|
16
|
+
|
17
|
+
assert_match("<h2>Level 2</h2>", markup.to_html)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_level_three
|
21
|
+
text = "=== Level 3 ==="
|
22
|
+
markup = Marker.parse text
|
23
|
+
|
24
|
+
assert_match("<h3>Level 3</h3>", markup.to_html)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_level_four
|
28
|
+
text = "==== Level 4 ===="
|
29
|
+
markup = Marker.parse text
|
30
|
+
|
31
|
+
assert_match("<h4>Level 4</h4>", markup.to_html)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_level_five
|
35
|
+
text = "===== Level 5 ====="
|
36
|
+
markup = Marker.parse text
|
37
|
+
|
38
|
+
assert_match("<h5>Level 5</h5>", markup.to_html)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_level_six
|
42
|
+
text = "====== Level 6 ======"
|
43
|
+
markup = Marker.parse text
|
44
|
+
|
45
|
+
assert_match("<h6>Level 6</h6>", markup.to_html)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_unbalanced_delimiters
|
49
|
+
# this behavior should match MediaWiki
|
50
|
+
text = "=== Level 2 =="
|
51
|
+
markup = Marker.parse text
|
52
|
+
assert_match("<h2>= Level 2</h2>", markup.to_html)
|
53
|
+
|
54
|
+
text = "== Level 2 ==="
|
55
|
+
markup = Marker.parse text
|
56
|
+
assert_match("<h2>Level 2 =</h2>", markup.to_html)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_containing_equals
|
60
|
+
text = "== Level = 2 =="
|
61
|
+
markup = Marker.parse text
|
62
|
+
|
63
|
+
assert_match("<h2>Level = 2</h2>", markup.to_html)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_trailing_text
|
67
|
+
# headings must be alone on a line or else are treated as text; this
|
68
|
+
# behavior matches MediaWiki
|
69
|
+
#
|
70
|
+
# should this be changed to work like horizontal rules?
|
71
|
+
text = "== Level 2 == trailing text"
|
72
|
+
markup = Marker.parse text
|
73
|
+
|
74
|
+
assert_match("<p>== Level 2 == trailing text</p>", markup.to_html)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/test/links_test.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require 'marker'
|
3
|
+
|
4
|
+
class LinkTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_internal_link_with_alias
|
7
|
+
text = "[[example_page|Example page]]"
|
8
|
+
markup = Marker.parse text
|
9
|
+
|
10
|
+
assert_match("<a href='/example_page'>Example page</a>", markup.to_html)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_bare_internal_link
|
14
|
+
text = "[[Example page]]"
|
15
|
+
markup = Marker.parse text
|
16
|
+
|
17
|
+
assert_match("<a href='/Example page'>Example page</a>", markup.to_html)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_internal_link_with_sanitization
|
21
|
+
# parens aren't normally sanitized
|
22
|
+
text = "[[Example page (disambiguation)]]"
|
23
|
+
markup = Marker.parse text
|
24
|
+
assert_match("<a href='/Example page (disambiguation)'>Example page (disambiguation)</a>", markup.to_html)
|
25
|
+
|
26
|
+
# with a blank alias, parens are sanitized from the alias
|
27
|
+
text = "[[Example page (disambiguation)|]]"
|
28
|
+
markup = Marker.parse text
|
29
|
+
assert_match("<a href='/Example page (disambiguation)'>Example page</a>", markup.to_html)
|
30
|
+
|
31
|
+
# no effect without parens
|
32
|
+
text = "[[Example page|]]"
|
33
|
+
markup = Marker.parse text
|
34
|
+
assert_match("<a href='/Example page'>Example page</a>", markup.to_html)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_internal_with_url
|
38
|
+
text = "[[http://www.example.com]]"
|
39
|
+
markup = Marker.parse text
|
40
|
+
assert_match("<p><a href='http://www.example.com'>[1]</a></p>\n<ol><li><a href='http://www.example.com'>http://www.example.com</a></li></ol>", markup.to_html)
|
41
|
+
|
42
|
+
text = "[[http://www.example.com|Example page]]"
|
43
|
+
markup = Marker.parse text
|
44
|
+
assert_match("<a href='http://www.example.com'>Example page</a>", markup.to_html)
|
45
|
+
|
46
|
+
text = "[[http://www.example.com Example page]]"
|
47
|
+
markup = Marker.parse text
|
48
|
+
assert_match("<a href='http://www.example.com'>Example page</a>", markup.to_html)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_external_link_with_alias
|
52
|
+
text = "[http://www.example.com Example link]"
|
53
|
+
markup = Marker.parse text
|
54
|
+
|
55
|
+
assert_match("<a href='http://www.example.com'>Example link</a>", markup.to_html)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_bare_external_link
|
59
|
+
text = "[http://www.example.com]"
|
60
|
+
markup = Marker.parse text
|
61
|
+
|
62
|
+
assert_match("<p><a href='http://www.example.com'>[1]</a></p>\n<ol><li><a href='http://www.example.com'>http://www.example.com</a></li></ol>", markup.to_html)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_nested_links
|
66
|
+
# only the outside link works
|
67
|
+
text = "[http://www.example.com [[ Nested Internal ]]]"
|
68
|
+
markup = Marker.parse text
|
69
|
+
assert_match("<p><a href='http://www.example.com'>[[ Nested Internal ]]</a></p>", markup.to_html)
|
70
|
+
|
71
|
+
text = "[[Internal | [http://www.example.com Nested] ]]"
|
72
|
+
markup = Marker.parse text
|
73
|
+
assert_match("<p><a href='/Internal'>[http://www.example.com Nested]</a></p>", markup.to_html)
|
74
|
+
|
75
|
+
text = "[[Internal | [http://www.example.com Nested]]]"
|
76
|
+
markup = Marker.parse text
|
77
|
+
assert_match("<p><a href='/Internal'>[http://www.example.com Nested</a>]</p>", markup.to_html)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_implicit_urls
|
81
|
+
# implicit urls are url-safe strings used in external links. e.g., apt: or itunes: urls
|
82
|
+
# alone, they render as text:
|
83
|
+
text = "apt:ruby1.8"
|
84
|
+
markup = Marker.parse text
|
85
|
+
assert_match("<p>apt:ruby1.8</p>", markup.to_html)
|
86
|
+
|
87
|
+
# placed in a url context, they render as urls:
|
88
|
+
text = "[apt:ruby1.8 Install Ruby!]"
|
89
|
+
markup = Marker.parse text
|
90
|
+
assert_match("<a href='apt:ruby1.8'>Install Ruby!</a>", markup.to_html)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_bare_url
|
94
|
+
text = "http://www.example.com"
|
95
|
+
markup = Marker.parse text
|
96
|
+
|
97
|
+
assert_match("<p><a href='http://www.example.com'>[1]</a></p>\n<ol><li><a href='http://www.example.com'>http://www.example.com</a></li></ol>", markup.to_html)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_multiple_footnotes
|
101
|
+
text = "http://www.example.com [http://www.example.com]"
|
102
|
+
markup = Marker.parse text
|
103
|
+
|
104
|
+
# TODO: should this collect identical links into one footnote?
|
105
|
+
assert_match("<p><a href='http://www.example.com'>[1]</a> <a href='http://www.example.com'>[2]</a></p>\n" +
|
106
|
+
"<ol><li><a href='http://www.example.com'>http://www.example.com</a></li><li><a href='http://www.example.com'>http://www.example.com</a></li></ol>", markup.to_html)
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
data/test/lists_test.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require 'marker'
|
3
|
+
|
4
|
+
class ListTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_bulleted_list
|
7
|
+
text = "* List item 1\n* List item 2"
|
8
|
+
markup = Marker.parse text
|
9
|
+
|
10
|
+
assert_match("<ul><li>List item 1</li><li>List item 2</li></ul>", markup.to_html)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_nested_bulleted_list
|
14
|
+
text = "* List item 1\n** List item 2\n* List item 3"
|
15
|
+
markup = Marker.parse text
|
16
|
+
|
17
|
+
assert_match("<ul><li>List item 1</li><ul><li>List item 2</li></ul><li>List item 3</li></ul>", markup.to_html)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_numbered_list
|
21
|
+
text = "# List item 1\n# List item 2"
|
22
|
+
markup = Marker.parse text
|
23
|
+
|
24
|
+
assert_match("<ol><li>List item 1</li><li>List item 2</li></ol>", markup.to_html)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_nested_numbered_list
|
28
|
+
text = "# List item 1\n## List item 2\n# List item 3"
|
29
|
+
markup = Marker.parse text
|
30
|
+
|
31
|
+
assert_match("<ol><li>List item 1</li><ol><li>List item 2</li></ol><li>List item 3</li></ol>", markup.to_html)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_definition_list
|
35
|
+
text = "; term : definition"
|
36
|
+
markup = Marker.parse text
|
37
|
+
|
38
|
+
assert_match("<dl><dt>term</dt><dd>definition</dd></dl>", markup.to_html)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_nested_definition_list
|
42
|
+
# definition lists can't be nested, so it should return the markup as normal text
|
43
|
+
text = "; term 1 : ; term 2 : definition"
|
44
|
+
markup = Marker.parse text
|
45
|
+
|
46
|
+
assert_match("<dl><dt>term 1</dt><dd>; term 2 : definition</dd></dl>", markup.to_html)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_indented_list
|
50
|
+
# MediaWiki renders intented lists as definition lists without terms.
|
51
|
+
# Marker uses <div> tags instead
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_nested_intented_list
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_mixed_list
|
58
|
+
text = "# List item 1\n* List item 2\n# List item 3\n; List item 4 : definition\n: List item 5\n* List item 6"
|
59
|
+
markup = Marker.parse text
|
60
|
+
|
61
|
+
assert_match("<ol><li>List item 1</li></ol><ul><li>List item 2</li></ul><ol><li>List item 3</li></ol><dl><dt>List item 4</dt>" +
|
62
|
+
"<dd>definition</dd></dl><div class='indent'><div>List item 5</div></div><ul><li>List item 6</li></ul>", markup.to_html)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_nested_mixed_list
|
66
|
+
text = "# List item 1\n#* List item 2\n# List item 3\n## List item 4\n#; List item 5 : definition\n#:List item 6"
|
67
|
+
markup = Marker.parse text
|
68
|
+
|
69
|
+
assert_match("<ol><li>List item 1</li><ul><li>List item 2</li></ul><li>List item 3</li><ol><li>List item 4</li></ol>" +
|
70
|
+
"<dl><dt>List item 5</dt><dd>definition</dd></dl><div class='indent'><div>List item 6</div></div></ol>", markup.to_html)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require 'marker'
|
3
|
+
|
4
|
+
class TemplatesTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_basic_template
|
7
|
+
text = "{{ template }}"
|
8
|
+
markup = Marker.parse text
|
9
|
+
|
10
|
+
assert_match("<p>render:template( :html, [], {} )</p>", markup.to_html)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_positional_args
|
14
|
+
text = "{{ template | one | two | three }}"
|
15
|
+
markup = Marker.parse text
|
16
|
+
|
17
|
+
assert_match("<p>render:template( :html, [\"one\", \"two\", \"three\"], {} )</p>", markup.to_html)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_named_args
|
21
|
+
text = "{{ template | one=1 | two = 2 }}"
|
22
|
+
markup = Marker.parse text
|
23
|
+
|
24
|
+
# might want to fix this assertion, the hash could come out in any order
|
25
|
+
assert_match("<p>render:template( :html, [], {\"two\"=>\"2\", \"one\"=>\"1\"} )</p>", markup.to_html)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_mixed_args
|
29
|
+
text = "{{ template | one | two = 2 | three }}"
|
30
|
+
markup = Marker.parse text
|
31
|
+
|
32
|
+
assert_match("<p>render:template( :html, [\"one\", \"three\"], {\"two\"=>\"2\"} )</p>", markup.to_html)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_empty_args
|
36
|
+
text = "{{ template | }}"
|
37
|
+
markup = Marker.parse text
|
38
|
+
assert_match("<p>render:template( :html, [\"\"], {} )</p>", markup.to_html)
|
39
|
+
|
40
|
+
text = "{{ template | | }}"
|
41
|
+
markup = Marker.parse text
|
42
|
+
assert_match("<p>render:template( :html, [\"\", \"\"], {} )</p>", markup.to_html)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_rendered_args
|
46
|
+
text = "{{ template | [http://www.example.com Example] }}"
|
47
|
+
markup = Marker.parse text
|
48
|
+
|
49
|
+
assert_match("<p>render:template( :html, [\"<a href='http://www.example.com'>Example</a>\"], {} )</p>", markup.to_html)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require 'marker'
|
3
|
+
|
4
|
+
class VerbatimTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_preformatted_text
|
7
|
+
text = " some source code"
|
8
|
+
markup = Marker.parse text
|
9
|
+
|
10
|
+
assert_match("<pre>\nsome source code\n</pre>", markup.to_html)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_multiline_preformatted_text
|
14
|
+
text = " some source code\n some more source code"
|
15
|
+
markup = Marker.parse text
|
16
|
+
|
17
|
+
assert_match("<pre>\nsome source code\nsome more source code\n</pre>", markup.to_html)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Blue
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-18 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -73,5 +73,11 @@ rubygems_version: 1.3.5
|
|
73
73
|
signing_key:
|
74
74
|
specification_version: 3
|
75
75
|
summary: A markup parser that outputs html and text. Syntax is similar to MediaWiki.
|
76
|
-
test_files:
|
77
|
-
|
76
|
+
test_files:
|
77
|
+
- test/templates_test.rb
|
78
|
+
- test/verbatim_test.rb
|
79
|
+
- test/headings_test.rb
|
80
|
+
- test/formatting_test.rb
|
81
|
+
- test/test_helper.rb
|
82
|
+
- test/links_test.rb
|
83
|
+
- test/lists_test.rb
|