marker 0.1.0 → 0.2.0
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/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
|