marker 0.1.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/LICENSE +674 -0
- data/README +98 -0
- data/bin/marker +59 -0
- data/lib/marker/common.rb +40 -0
- data/lib/marker/headings.rb +79 -0
- data/lib/marker/language.treetop +679 -0
- data/lib/marker/links.rb +153 -0
- data/lib/marker/lists.rb +188 -0
- data/lib/marker/markup.rb +81 -0
- data/lib/marker/templates.rb +105 -0
- data/lib/marker/text.rb +96 -0
- data/lib/marker/verbatim.rb +48 -0
- data/lib/marker.rb +80 -0
- metadata +77 -0
data/lib/marker/links.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009 Ryan Blue.
|
3
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
4
|
+
# See the LICENSE file for further information on the GPL.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'marker/common'
|
8
|
+
|
9
|
+
module Marker #:nodoc:
|
10
|
+
class InternalLink < ParseNode
|
11
|
+
def to_html( options = {} )
|
12
|
+
"<a href='#{path(options)}'>#{label(:html, options)}</a>"
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s( options = {} )
|
16
|
+
f = options[:footnotes]
|
17
|
+
if f
|
18
|
+
l = label(:text, options)
|
19
|
+
n = f.add( path(options), l )
|
20
|
+
"#{l} [#{n}]"
|
21
|
+
else
|
22
|
+
"#{label(:text, options)} [#{path}]"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def path( options = {} )
|
27
|
+
p = options[:link_base] || ''
|
28
|
+
p.chomp! '/'
|
29
|
+
p += '/' + target
|
30
|
+
end
|
31
|
+
|
32
|
+
def label( format, options = {} )
|
33
|
+
if l
|
34
|
+
case format
|
35
|
+
when :html
|
36
|
+
l.to_html(options)
|
37
|
+
else
|
38
|
+
l.to_s(options)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
if a
|
42
|
+
# an arg delimiter was present, but without a label
|
43
|
+
# sanitize: remove trailing parenthetical remarks
|
44
|
+
target.gsub(/\s*\([^)]*\)$/, '')
|
45
|
+
else
|
46
|
+
target
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def target
|
52
|
+
if t
|
53
|
+
t.text_value
|
54
|
+
else
|
55
|
+
''
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#-- defaults ++
|
60
|
+
def t #:nodoc:
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def a #:nodoc:
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def l #:nodoc:
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class ExternalLink < ParseNode
|
74
|
+
def to_html( options = {} )
|
75
|
+
if l
|
76
|
+
"<a href='#{target}'>#{label(:html, options)}</a>"
|
77
|
+
else
|
78
|
+
f = options[:footnotes]
|
79
|
+
if f
|
80
|
+
n = f.add( target )
|
81
|
+
"<a href='#{target}'>[#{n}]</a>"
|
82
|
+
else
|
83
|
+
"<a href='#{target}'></a>"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_s( options = {} )
|
89
|
+
f = options[:footnotes]
|
90
|
+
if l
|
91
|
+
if f
|
92
|
+
n = f.add( target, label(:text, options) )
|
93
|
+
"#{label(:text, options)} [#{n}]"
|
94
|
+
else
|
95
|
+
"#{label(:text, options)} [#{target}]"
|
96
|
+
end
|
97
|
+
else
|
98
|
+
if f
|
99
|
+
n = f.add( target )
|
100
|
+
"[#{n}]"
|
101
|
+
else
|
102
|
+
target
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def label( format, options = {} )
|
108
|
+
if l
|
109
|
+
case format
|
110
|
+
when :html
|
111
|
+
l.to_html(options)
|
112
|
+
else
|
113
|
+
l.to_s(options)
|
114
|
+
end
|
115
|
+
else
|
116
|
+
''
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def target
|
121
|
+
if t
|
122
|
+
t.text_value
|
123
|
+
else
|
124
|
+
''
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
#-- defaults ++
|
129
|
+
def t #:nodoc:
|
130
|
+
nil
|
131
|
+
end
|
132
|
+
|
133
|
+
def l #:nodoc:
|
134
|
+
nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
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
|
+
def to_html( options = {} )
|
143
|
+
text_value
|
144
|
+
end
|
145
|
+
|
146
|
+
def to_s( options = {} )
|
147
|
+
text_value
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class Protocol < ParseNode
|
152
|
+
end
|
153
|
+
end
|
data/lib/marker/lists.rb
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009 Ryan Blue.
|
3
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
4
|
+
# See the LICENSE file for further information on the GPL.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'marker/common'
|
8
|
+
|
9
|
+
module Marker #:nodoc:
|
10
|
+
# used to collect list lines into lists structured hierarchically, like in HTML
|
11
|
+
class ListBuilder
|
12
|
+
attr_reader :tag, :contents, :attrs
|
13
|
+
|
14
|
+
def initialize( contents, tag, attrs = {} )
|
15
|
+
@contents = [contents].flatten
|
16
|
+
@tag = tag
|
17
|
+
@attrs = attrs
|
18
|
+
end
|
19
|
+
|
20
|
+
# returns true if the l has the same tag
|
21
|
+
def ===( l )
|
22
|
+
( l.is_a? self.class and tag == l.tag )
|
23
|
+
end
|
24
|
+
|
25
|
+
def <<( l )
|
26
|
+
last = contents.last
|
27
|
+
|
28
|
+
if last and last === l
|
29
|
+
last += l
|
30
|
+
else
|
31
|
+
contents << l
|
32
|
+
end
|
33
|
+
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def +( l )
|
38
|
+
l.contents.each { |i| self << i } if self === l
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_html( options = {} )
|
44
|
+
if tag
|
45
|
+
"<#{tag}" +
|
46
|
+
( attrs.any?? ' ' : '' ) +
|
47
|
+
attrs.map { |k, v|
|
48
|
+
"#{k}='#{v}'"
|
49
|
+
}.join(' ') +
|
50
|
+
">" +
|
51
|
+
contents.map { |i|
|
52
|
+
i.to_html(options)
|
53
|
+
}.join +
|
54
|
+
"</#{tag}>"
|
55
|
+
else
|
56
|
+
contents.map { |i|
|
57
|
+
i.to_html(options)
|
58
|
+
}.join
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_s( options = {} )
|
63
|
+
strs = []
|
64
|
+
contents.each_with_index { |i, ind|
|
65
|
+
strs << i.to_s( options.merge(
|
66
|
+
:indent => ( options[:indent] || 0 ) + ( tag ? 1 : 0 ),
|
67
|
+
:num => ind + 1
|
68
|
+
) )
|
69
|
+
}
|
70
|
+
strs.join("\n")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class List < RecursiveList
|
75
|
+
def to_html( options = {} )
|
76
|
+
l = ListBuilder.new( [], nil )
|
77
|
+
to_a.each do |item|
|
78
|
+
l << item.structure
|
79
|
+
end
|
80
|
+
l.to_html(options)
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_s( options = {} )
|
84
|
+
l = ListBuilder.new( [], nil )
|
85
|
+
to_a.each do |item|
|
86
|
+
l << item.structure
|
87
|
+
end
|
88
|
+
l.to_s(options)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class Bulleted < ParseNode
|
93
|
+
def to_html( options = {} )
|
94
|
+
"<li>#{phrase.to_html(options)}</li>"
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_s( options = {} )
|
98
|
+
indent = (options[:indent] || 0)
|
99
|
+
' ' * (indent > 0 ? indent - 1 : 0) +
|
100
|
+
' * ' + phrase.to_s( options )
|
101
|
+
end
|
102
|
+
|
103
|
+
def structure
|
104
|
+
if phrase
|
105
|
+
ListBuilder.new( self, :ul )
|
106
|
+
else
|
107
|
+
ListBuilder.new( list_item.structure, :ul )
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#-- defaults ++
|
112
|
+
def phrase
|
113
|
+
nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class Numbered < ParseNode
|
118
|
+
def to_html( options = {} )
|
119
|
+
"<li>#{phrase.to_html(options)}</li>"
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_s( options = {} )
|
123
|
+
indent = (options[:indent] || 0)
|
124
|
+
' ' * (indent > 0 ? indent - 1 : 0) +
|
125
|
+
"#{'%2d' % options[:num]}. #{phrase.to_s( options )}"
|
126
|
+
end
|
127
|
+
|
128
|
+
def structure
|
129
|
+
if phrase
|
130
|
+
ListBuilder.new( self, :ol )
|
131
|
+
else
|
132
|
+
ListBuilder.new( list_item.structure, :ol )
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#-- defaults ++
|
137
|
+
def phrase
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class Indented < ParseNode
|
143
|
+
def to_html( options = {} )
|
144
|
+
"<div>#{phrase.to_html(options)}</div>"
|
145
|
+
end
|
146
|
+
|
147
|
+
def to_s( options = {} )
|
148
|
+
indent = (options[:indent] || 0)
|
149
|
+
' ' * (indent > 0 ? indent : 0) +
|
150
|
+
phrase.to_s(options)
|
151
|
+
end
|
152
|
+
|
153
|
+
def structure
|
154
|
+
if phrase
|
155
|
+
ListBuilder.new( self, :div, :class => 'indent' )
|
156
|
+
else
|
157
|
+
ListBuilder.new( list_item.structure, :div, :class => 'indent' )
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
#-- defaults ++
|
162
|
+
def phrase
|
163
|
+
nil
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class Definition < ParseNode
|
168
|
+
def to_html( options = {} )
|
169
|
+
"<dt>#{term.to_html(options)}</dt>" +
|
170
|
+
( definition ? "<dd>#{definition.to_html(options)}</dd>" : "" )
|
171
|
+
end
|
172
|
+
|
173
|
+
def to_s( options = {} )
|
174
|
+
indent = (options[:indent] || 0)
|
175
|
+
' ' * (indent > 0 ? indent - 1: 0) +
|
176
|
+
"#{term.to_s(options)} :: #{definition.to_s(options)}"
|
177
|
+
end
|
178
|
+
|
179
|
+
def structure
|
180
|
+
ListBuilder.new( self, :dl )
|
181
|
+
end
|
182
|
+
|
183
|
+
#-- defaults ++
|
184
|
+
def definition
|
185
|
+
nil
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009 Ryan Blue.
|
3
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
4
|
+
# See the LICENSE file for further information on the GPL.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'marker/common'
|
8
|
+
|
9
|
+
module Marker #:nodoc:
|
10
|
+
class Markup < RecursiveList
|
11
|
+
def to_html( options = {} )
|
12
|
+
options = make_options( options )
|
13
|
+
|
14
|
+
[
|
15
|
+
to_a.map{ |b|
|
16
|
+
b.to_html(options)
|
17
|
+
}, options[:footnotes].to_html( options )
|
18
|
+
].flatten.join("\n")
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s( options = {} )
|
22
|
+
options = make_options( options )
|
23
|
+
|
24
|
+
[
|
25
|
+
to_a.map{ |b|
|
26
|
+
b.to_s(options)
|
27
|
+
}, options[:footnotes].to_s( options )
|
28
|
+
].flatten.join("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
def make_options( user_options )
|
32
|
+
o = Marker.render_options.dup
|
33
|
+
o.merge!( :link_base => Marker.link_base )
|
34
|
+
o.merge!( :footnotes => Footnotes.new ) unless user_options[:nofootnotes]
|
35
|
+
o.merge!( user_options )
|
36
|
+
o
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Footnotes
|
41
|
+
def notes
|
42
|
+
@notes ||= []
|
43
|
+
end
|
44
|
+
|
45
|
+
def add( *args )
|
46
|
+
notes << args
|
47
|
+
notes.size
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_html( options = {} )
|
51
|
+
return "" unless notes.any?
|
52
|
+
|
53
|
+
"<ol>" +
|
54
|
+
notes.map { |n|
|
55
|
+
target = n.shift
|
56
|
+
if n.any?
|
57
|
+
"<li><a href='#{target}'>#{n.join(' ')}</a></li>"
|
58
|
+
else
|
59
|
+
"<li><a href='#{target}'>#{target}</a></li>"
|
60
|
+
end
|
61
|
+
}.join +
|
62
|
+
"</ol>"
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s( options = {} )
|
66
|
+
return "" unless notes.any?
|
67
|
+
|
68
|
+
s = "\n"
|
69
|
+
notes.each_with_index{ |n, i|
|
70
|
+
target = n.shift
|
71
|
+
if n.any?
|
72
|
+
s << "#{'%2d' % (i + 1)}. #{n.join(' ')}: #{target}\n"
|
73
|
+
else
|
74
|
+
s << "#{'%2d' % (i + 1)}. #{target}\n"
|
75
|
+
end
|
76
|
+
}
|
77
|
+
|
78
|
+
s
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009 Ryan Blue.
|
3
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
4
|
+
# See the LICENSE file for further information on the GPL.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'marker/common'
|
8
|
+
|
9
|
+
module Marker #:nodoc:
|
10
|
+
class Template < ParseNode
|
11
|
+
def to_html( options = {} )
|
12
|
+
render( :html, options )
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s( options = {} )
|
16
|
+
render( :text, options )
|
17
|
+
end
|
18
|
+
|
19
|
+
def render( format, options = {} )
|
20
|
+
Marker.templates.send( target, format, *arg_list( format, options ) )
|
21
|
+
end
|
22
|
+
|
23
|
+
def target
|
24
|
+
# sanitize the string to get a method name
|
25
|
+
t.text_value.gsub(/\s/, '_').to_sym
|
26
|
+
end
|
27
|
+
|
28
|
+
def arg_list( format, options )
|
29
|
+
( args ? args.to_arg_list( format, options ) : [[], {}] )
|
30
|
+
end
|
31
|
+
|
32
|
+
#-- defaults ++
|
33
|
+
def t #:nodoc:
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def args #:nodoc:
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Arguments < RecursiveList
|
43
|
+
def to_arg_list( format, options = {} )
|
44
|
+
pos_params = []
|
45
|
+
named_params = {}
|
46
|
+
|
47
|
+
case format
|
48
|
+
when :html
|
49
|
+
to_a.each do |a|
|
50
|
+
next unless a
|
51
|
+
if a.name
|
52
|
+
named_params[a.name.to_html( options )] = a.val.to_html( options )
|
53
|
+
else
|
54
|
+
pos_params << a.val.to_html( options )
|
55
|
+
end
|
56
|
+
end
|
57
|
+
else
|
58
|
+
to_a.each do |a|
|
59
|
+
next unless a
|
60
|
+
if a.name
|
61
|
+
named_params[a.name.to_s( options )] = a.val.to_s( options )
|
62
|
+
else
|
63
|
+
pos_params << a.val.to_s( options )
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
[pos_params, named_params]
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_html( options = {} )
|
72
|
+
to_a.map { |a|
|
73
|
+
a ? a.to_html(options) : ''
|
74
|
+
}.join(', ')
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_s( options = {} )
|
78
|
+
to_a.map { |a|
|
79
|
+
a ? a.to_s(options) : ''
|
80
|
+
}.join(', ')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class Argument < ParseNode
|
85
|
+
def to_html( options = {} )
|
86
|
+
to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_s( options = {} )
|
90
|
+
( name ? "'#{name}' => '#{val}'" : "'#{val}'" )
|
91
|
+
end
|
92
|
+
|
93
|
+
#-- defaults ++
|
94
|
+
def name #:nodoc:
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# A set of basic templates for rendering
|
100
|
+
module DefaultTemplates
|
101
|
+
def self.method_missing( sym, *args )
|
102
|
+
"render:#{sym}( #{args.map(&:inspect).join(', ')} )"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/marker/text.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009 Ryan Blue.
|
3
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
4
|
+
# See the LICENSE file for further information on the GPL.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'marker/common'
|
8
|
+
|
9
|
+
module Marker #:nodoc:
|
10
|
+
class Paragraph < RecursiveList
|
11
|
+
def to_html( options = {} )
|
12
|
+
'<p>' +
|
13
|
+
to_a.map { |p|
|
14
|
+
p.to_html(options)
|
15
|
+
}.join(' ') +
|
16
|
+
'</p>'
|
17
|
+
end
|
18
|
+
|
19
|
+
# TODO: add wordwrap
|
20
|
+
def to_s( options = {} )
|
21
|
+
to_a.map { |p|
|
22
|
+
p.to_s(options)
|
23
|
+
}.join(' ')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Phrase < RecursiveList
|
28
|
+
def to_html( options = {} )
|
29
|
+
s = h.to_html(options)
|
30
|
+
s << ' ' if space?
|
31
|
+
s << r.to_html(options) if r
|
32
|
+
s
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s( options = {} )
|
36
|
+
s = h.to_s(options)
|
37
|
+
s << ' ' if space?
|
38
|
+
s << r.to_s(options) if r
|
39
|
+
s
|
40
|
+
end
|
41
|
+
|
42
|
+
# returns true if there was white space after the first "word"
|
43
|
+
def space?
|
44
|
+
(ws and ws.present?) or (aws and aws.present?)
|
45
|
+
end
|
46
|
+
|
47
|
+
#-- defaults ++
|
48
|
+
def ws
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def aws
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Word < ParseNode
|
58
|
+
def to_html( options = {} )
|
59
|
+
text_value
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_s( options = {} )
|
63
|
+
text_value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Delimiter < ParseNode
|
68
|
+
def to_html( options = {} )
|
69
|
+
text_value
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_s( options = {} )
|
73
|
+
text_value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Bold < ParseNode
|
78
|
+
def to_html( options = {} )
|
79
|
+
"<b>#{bold_enclosed_text.to_html(options)}</b>"
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_s( options = {} )
|
83
|
+
"*#{bold_enclosed_text.to_s(options)}*"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Italic < ParseNode
|
88
|
+
def to_html( options = {} )
|
89
|
+
"<i>#{italic_enclosed_text.to_html(options)}</i>"
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_s( options = {} )
|
93
|
+
"/#{italic_enclosed_text.to_s(options)}/"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009 Ryan Blue.
|
3
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
4
|
+
# See the LICENSE file for further information on the GPL.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'marker/common'
|
8
|
+
|
9
|
+
module Marker #:nodoc:
|
10
|
+
class VerbatimArea < RecursiveList
|
11
|
+
def to_html( options = {} )
|
12
|
+
"<pre>\n" +
|
13
|
+
to_a.map { |l|
|
14
|
+
l.to_html(options)
|
15
|
+
}.join("\n") +
|
16
|
+
"\n</pre>"
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s( options = {} )
|
20
|
+
"-- \n" +
|
21
|
+
to_a.map { |l|
|
22
|
+
l.to_s(options)
|
23
|
+
}.join("\n") +
|
24
|
+
"\n-- "
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Verbatim < ParseNode
|
29
|
+
def to_html( options = {} )
|
30
|
+
v.text_value
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s( options = {} )
|
34
|
+
v.text_value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class HorizRule < ParseNode
|
39
|
+
def to_html( options = {} )
|
40
|
+
"<hr />"
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s( options = {} )
|
44
|
+
width = options[:width] || 80
|
45
|
+
"-" * width
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|