rdoc 2.5.11 → 3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rdoc might be problematic. Click here for more details.
- data.tar.gz.sig +0 -0
- data/.document +1 -0
- data/History.txt +95 -0
- data/Manifest.txt +13 -4
- data/README.txt +9 -3
- data/Rakefile +1 -1
- data/lib/rdoc.rb +15 -298
- data/lib/rdoc/alias.rb +65 -16
- data/lib/rdoc/any_method.rb +27 -150
- data/lib/rdoc/attr.rb +36 -115
- data/lib/rdoc/class_module.rb +236 -22
- data/lib/rdoc/code_object.rb +76 -31
- data/lib/rdoc/constant.rb +32 -4
- data/lib/rdoc/context.rb +494 -222
- data/lib/rdoc/encoding.rb +79 -0
- data/lib/rdoc/erbio.rb +37 -0
- data/lib/rdoc/gauntlet.rb +9 -5
- data/lib/rdoc/generator.rb +33 -1
- data/lib/rdoc/generator/darkfish.rb +284 -375
- data/lib/rdoc/generator/markup.rb +72 -36
- data/lib/rdoc/generator/ri.rb +4 -4
- data/lib/rdoc/generator/template/darkfish/classpage.rhtml +267 -274
- data/lib/rdoc/generator/template/darkfish/filepage.rhtml +91 -91
- data/lib/rdoc/generator/template/darkfish/index.rhtml +45 -45
- data/lib/rdoc/generator/template/darkfish/rdoc.css +298 -298
- data/lib/rdoc/include.rb +40 -1
- data/lib/rdoc/known_classes.rb +1 -0
- data/lib/rdoc/markup.rb +467 -2
- data/lib/rdoc/markup/attribute_manager.rb +24 -6
- data/lib/rdoc/markup/blank_line.rb +11 -3
- data/lib/rdoc/markup/document.rb +6 -0
- data/lib/rdoc/markup/formatter.rb +10 -0
- data/lib/rdoc/markup/formatter_test_case.rb +339 -3
- data/lib/rdoc/markup/heading.rb +3 -0
- data/lib/rdoc/markup/inline.rb +11 -1
- data/lib/rdoc/markup/list.rb +3 -0
- data/lib/rdoc/markup/list_item.rb +3 -0
- data/lib/rdoc/markup/paragraph.rb +3 -0
- data/lib/rdoc/markup/parser.rb +191 -237
- data/lib/rdoc/markup/{preprocess.rb → pre_process.rb} +50 -29
- data/lib/rdoc/markup/raw.rb +4 -0
- data/lib/rdoc/markup/rule.rb +3 -0
- data/lib/rdoc/markup/text_formatter_test_case.rb +116 -0
- data/lib/rdoc/markup/to_ansi.rb +14 -2
- data/lib/rdoc/markup/to_bs.rb +8 -2
- data/lib/rdoc/markup/to_html.rb +84 -91
- data/lib/rdoc/markup/to_html_crossref.rb +77 -26
- data/lib/rdoc/markup/to_rdoc.rb +94 -49
- data/lib/rdoc/markup/to_test.rb +9 -1
- data/lib/rdoc/markup/verbatim.rb +6 -3
- data/lib/rdoc/method_attr.rb +353 -0
- data/lib/rdoc/normal_class.rb +11 -2
- data/lib/rdoc/normal_module.rb +0 -5
- data/lib/rdoc/options.rb +373 -82
- data/lib/rdoc/parser.rb +59 -23
- data/lib/rdoc/parser/c.rb +224 -86
- data/lib/rdoc/parser/ruby.rb +219 -111
- data/lib/rdoc/parser/ruby_tools.rb +4 -1
- data/lib/rdoc/parser/simple.rb +9 -4
- data/lib/rdoc/rdoc.rb +68 -28
- data/lib/rdoc/require.rb +21 -0
- data/lib/rdoc/ri/driver.rb +20 -10
- data/lib/rdoc/ri/paths.rb +2 -2
- data/lib/rdoc/ri/store.rb +22 -5
- data/lib/rdoc/ruby_lex.rb +11 -12
- data/lib/rdoc/ruby_token.rb +2 -2
- data/lib/rdoc/single_class.rb +2 -1
- data/lib/rdoc/stats.rb +202 -162
- data/lib/rdoc/stats/normal.rb +51 -0
- data/lib/rdoc/stats/quiet.rb +59 -0
- data/lib/rdoc/stats/verbose.rb +45 -0
- data/lib/rdoc/text.rb +133 -4
- data/lib/rdoc/{tokenstream.rb → token_stream.rb} +0 -2
- data/lib/rdoc/top_level.rb +230 -39
- data/test/test_attribute_manager.rb +58 -7
- data/test/test_rdoc_alias.rb +13 -0
- data/test/test_rdoc_any_method.rb +43 -2
- data/test/test_rdoc_attr.rb +15 -8
- data/test/test_rdoc_class_module.rb +133 -0
- data/test/test_rdoc_code_object.rb +62 -5
- data/test/test_rdoc_context.rb +72 -26
- data/test/test_rdoc_encoding.rb +145 -0
- data/test/test_rdoc_generator_darkfish.rb +119 -0
- data/test/test_rdoc_generator_ri.rb +22 -2
- data/test/test_rdoc_include.rb +79 -0
- data/test/test_rdoc_markup_attribute_manager.rb +4 -4
- data/test/test_rdoc_markup_parser.rb +134 -95
- data/test/test_rdoc_markup_pre_process.rb +7 -2
- data/test/test_rdoc_markup_to_ansi.rb +43 -153
- data/test/test_rdoc_markup_to_bs.rb +42 -156
- data/test/test_rdoc_markup_to_html.rb +130 -58
- data/test/test_rdoc_markup_to_html_crossref.rb +10 -10
- data/test/test_rdoc_markup_to_rdoc.rb +40 -151
- data/test/test_rdoc_method_attr.rb +122 -0
- data/test/test_rdoc_normal_class.rb +1 -1
- data/test/test_rdoc_normal_module.rb +6 -1
- data/test/test_rdoc_options.rb +237 -12
- data/test/test_rdoc_parser.rb +3 -22
- data/test/test_rdoc_parser_c.rb +203 -2
- data/test/test_rdoc_parser_ruby.rb +403 -89
- data/test/test_rdoc_parser_simple.rb +25 -1
- data/test/test_rdoc_rdoc.rb +44 -32
- data/test/test_rdoc_ri_driver.rb +29 -24
- data/test/test_rdoc_ri_store.rb +46 -3
- data/test/test_rdoc_task.rb +1 -1
- data/test/test_rdoc_text.rb +102 -8
- data/test/test_rdoc_top_level.rb +13 -4
- data/test/xref_data.rb +8 -0
- data/test/xref_test_case.rb +6 -0
- metadata +29 -19
- metadata.gz.sig +0 -0
- data/lib/rdoc/parser/perl.rb +0 -165
- data/test/test_rdoc_parser_perl.rb +0 -73
data/lib/rdoc/markup/heading.rb
CHANGED
data/lib/rdoc/markup/inline.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rdoc'
|
1
2
|
class RDoc::Markup
|
2
3
|
|
3
4
|
##
|
@@ -14,6 +15,9 @@ class RDoc::Markup
|
|
14
15
|
@@name_to_bitmap = { :_SPECIAL_ => SPECIAL }
|
15
16
|
@@next_bitmap = 2
|
16
17
|
|
18
|
+
##
|
19
|
+
# Returns a unique bit for +name+
|
20
|
+
|
17
21
|
def self.bitmap_for(name)
|
18
22
|
bitmap = @@name_to_bitmap[name]
|
19
23
|
unless bitmap then
|
@@ -24,6 +28,9 @@ class RDoc::Markup
|
|
24
28
|
bitmap
|
25
29
|
end
|
26
30
|
|
31
|
+
##
|
32
|
+
# Returns a string reperesentation of +bitmap+
|
33
|
+
|
27
34
|
def self.as_string(bitmap)
|
28
35
|
return "none" if bitmap.zero?
|
29
36
|
res = []
|
@@ -33,6 +40,9 @@ class RDoc::Markup
|
|
33
40
|
res.join(",")
|
34
41
|
end
|
35
42
|
|
43
|
+
##
|
44
|
+
# yields each attribute name in +bitmap+
|
45
|
+
|
36
46
|
def self.each_name_of(bitmap)
|
37
47
|
@@name_to_bitmap.each do |name, bit|
|
38
48
|
next if bit == SPECIAL
|
@@ -75,7 +85,7 @@ class RDoc::Markup
|
|
75
85
|
end
|
76
86
|
|
77
87
|
##
|
78
|
-
#
|
88
|
+
# Accesses flags for character +n+
|
79
89
|
|
80
90
|
def [](n)
|
81
91
|
@attrs[n]
|
data/lib/rdoc/markup/list.rb
CHANGED
data/lib/rdoc/markup/parser.rb
CHANGED
@@ -52,13 +52,13 @@ class RDoc::Markup::Parser
|
|
52
52
|
attr_reader :tokens
|
53
53
|
|
54
54
|
##
|
55
|
-
#
|
55
|
+
# Parses +str+ into a Document
|
56
56
|
|
57
57
|
def self.parse str
|
58
58
|
parser = new
|
59
|
-
#parser.debug = true
|
60
59
|
parser.tokenize str
|
61
|
-
RDoc::Markup::Document.new
|
60
|
+
doc = RDoc::Markup::Document.new
|
61
|
+
parser.parse doc
|
62
62
|
end
|
63
63
|
|
64
64
|
##
|
@@ -86,6 +86,7 @@ class RDoc::Markup::Parser
|
|
86
86
|
# Builds a Heading of +level+
|
87
87
|
|
88
88
|
def build_heading level
|
89
|
+
_, text, = get # TEXT
|
89
90
|
heading = RDoc::Markup::Heading.new level, text
|
90
91
|
skip :NEWLINE
|
91
92
|
|
@@ -105,38 +106,69 @@ class RDoc::Markup::Parser
|
|
105
106
|
|
106
107
|
case type
|
107
108
|
when :BULLET, :LABEL, :LALPHA, :NOTE, :NUMBER, :UALPHA then
|
108
|
-
list_type = type
|
109
109
|
|
110
|
-
if column < margin then
|
110
|
+
if column < margin || (list.type && list.type != type) then
|
111
111
|
unget
|
112
112
|
break
|
113
113
|
end
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
break
|
118
|
-
end
|
119
|
-
|
120
|
-
list.type = list_type
|
115
|
+
list.type = type
|
116
|
+
peek_type, _, column, = peek_token
|
121
117
|
|
122
118
|
case type
|
123
119
|
when :NOTE, :LABEL then
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
peek_type
|
128
|
-
|
129
|
-
peek_type
|
130
|
-
|
120
|
+
if peek_type == :NEWLINE then
|
121
|
+
# description not on the same line as LABEL/NOTE
|
122
|
+
# skip the trailing newline & any blank lines below
|
123
|
+
while peek_type == :NEWLINE
|
124
|
+
get
|
125
|
+
peek_type, _, column, = peek_token
|
126
|
+
end
|
127
|
+
|
128
|
+
# we may be:
|
129
|
+
# - at end of stream
|
130
|
+
# - at a column < margin:
|
131
|
+
# [text]
|
132
|
+
# blah blah blah
|
133
|
+
# - at the same column, but with a different type of list item
|
134
|
+
# [text]
|
135
|
+
# * blah blah
|
136
|
+
# - at the same column, with the same type of list item
|
137
|
+
# [one]
|
138
|
+
# [two]
|
139
|
+
# In all cases, we have an empty description.
|
140
|
+
# In the last case only, we continue.
|
141
|
+
if peek_type.nil? || column < margin then
|
142
|
+
empty = 1
|
143
|
+
elsif column == margin then
|
144
|
+
case peek_type
|
145
|
+
when type
|
146
|
+
empty = 2 # continue
|
147
|
+
when *LIST_TOKENS
|
148
|
+
empty = 1
|
149
|
+
else
|
150
|
+
empty = 0
|
151
|
+
end
|
152
|
+
else
|
153
|
+
empty = 0
|
154
|
+
end
|
155
|
+
|
156
|
+
if empty > 0 then
|
157
|
+
item = RDoc::Markup::ListItem.new(data)
|
158
|
+
item << RDoc::Markup::BlankLine.new
|
159
|
+
list << item
|
160
|
+
break if empty == 1
|
161
|
+
next
|
162
|
+
end
|
131
163
|
end
|
132
164
|
else
|
133
165
|
data = nil
|
134
|
-
_, indent, = get
|
135
166
|
end
|
136
167
|
|
137
|
-
list_item =
|
168
|
+
list_item = RDoc::Markup::ListItem.new data
|
169
|
+
parse list_item, column
|
170
|
+
list << list_item
|
138
171
|
|
139
|
-
list << list_item if list_item
|
140
172
|
else
|
141
173
|
unget
|
142
174
|
break
|
@@ -150,54 +182,6 @@ class RDoc::Markup::Parser
|
|
150
182
|
list
|
151
183
|
end
|
152
184
|
|
153
|
-
##
|
154
|
-
# Builds a ListItem that is flush to +indent+ with type +item_type+
|
155
|
-
|
156
|
-
def build_list_item indent, item_type = nil
|
157
|
-
p :list_item_start => [indent, item_type] if @debug
|
158
|
-
|
159
|
-
list_item = RDoc::Markup::ListItem.new item_type
|
160
|
-
|
161
|
-
until @tokens.empty? do
|
162
|
-
type, data, column = get
|
163
|
-
|
164
|
-
if column < indent and
|
165
|
-
not type == :NEWLINE and
|
166
|
-
(type != :INDENT or data < indent) then
|
167
|
-
unget
|
168
|
-
break
|
169
|
-
end
|
170
|
-
|
171
|
-
case type
|
172
|
-
when :INDENT then
|
173
|
-
unget
|
174
|
-
list_item.push(*parse(indent))
|
175
|
-
when :TEXT then
|
176
|
-
unget
|
177
|
-
list_item << build_paragraph(indent)
|
178
|
-
when :HEADER then
|
179
|
-
list_item << build_heading(data)
|
180
|
-
when :NEWLINE then
|
181
|
-
list_item << RDoc::Markup::BlankLine.new
|
182
|
-
when *LIST_TOKENS then
|
183
|
-
unget
|
184
|
-
list_item << build_list(column)
|
185
|
-
else
|
186
|
-
raise ParseError, "Unhandled token #{@current_token.inspect}"
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
p :list_item_end => [indent, item_type] if @debug
|
191
|
-
|
192
|
-
return nil if list_item.empty?
|
193
|
-
|
194
|
-
list_item.parts.shift if
|
195
|
-
RDoc::Markup::BlankLine === list_item.parts.first and
|
196
|
-
list_item.length > 1
|
197
|
-
|
198
|
-
list_item
|
199
|
-
end
|
200
|
-
|
201
185
|
##
|
202
186
|
# Builds a Paragraph that is flush to +margin+
|
203
187
|
|
@@ -209,18 +193,7 @@ class RDoc::Markup::Parser
|
|
209
193
|
until @tokens.empty? do
|
210
194
|
type, data, column, = get
|
211
195
|
|
212
|
-
|
213
|
-
when :INDENT then
|
214
|
-
next if data == margin and peek_token[0] == :TEXT
|
215
|
-
|
216
|
-
unget
|
217
|
-
break
|
218
|
-
when :TEXT then
|
219
|
-
if column != margin then
|
220
|
-
unget
|
221
|
-
break
|
222
|
-
end
|
223
|
-
|
196
|
+
if type == :TEXT && column == margin then
|
224
197
|
paragraph << data
|
225
198
|
skip :NEWLINE
|
226
199
|
else
|
@@ -235,67 +208,81 @@ class RDoc::Markup::Parser
|
|
235
208
|
end
|
236
209
|
|
237
210
|
##
|
238
|
-
# Builds a Verbatim that is
|
211
|
+
# Builds a Verbatim that is indented from +margin+.
|
212
|
+
#
|
213
|
+
# The verbatim block is shifted left (the least indented lines start in
|
214
|
+
# column 0). Each part of the verbatim is one line of text, always
|
215
|
+
# terminated by a newline. Blank lines always consist of a single newline
|
216
|
+
# character, and there is never a single newline at the end of the verbatim.
|
239
217
|
|
240
218
|
def build_verbatim margin
|
241
219
|
p :verbatim_begin => margin if @debug
|
242
220
|
verbatim = RDoc::Markup::Verbatim.new
|
243
221
|
|
222
|
+
min_indent = nil
|
223
|
+
generate_leading_spaces = true
|
224
|
+
line = ''
|
225
|
+
|
244
226
|
until @tokens.empty? do
|
245
227
|
type, data, column, = get
|
246
228
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
229
|
+
if type == :NEWLINE then
|
230
|
+
line << data
|
231
|
+
verbatim << line
|
232
|
+
line = ''
|
233
|
+
generate_leading_spaces = true
|
234
|
+
next
|
235
|
+
end
|
253
236
|
|
254
|
-
|
237
|
+
if column <= margin
|
238
|
+
unget
|
239
|
+
break
|
240
|
+
end
|
255
241
|
|
256
|
-
|
257
|
-
|
258
|
-
|
242
|
+
if generate_leading_spaces then
|
243
|
+
indent = column - margin
|
244
|
+
line << ' ' * indent
|
245
|
+
min_indent = indent if min_indent.nil? || indent < min_indent
|
246
|
+
generate_leading_spaces = false
|
247
|
+
end
|
259
248
|
|
249
|
+
case type
|
250
|
+
when :HEADER then
|
251
|
+
line << '=' * data
|
260
252
|
_, _, peek_column, = peek_token
|
261
253
|
peek_column ||= column + data
|
262
|
-
|
254
|
+
indent = peek_column - column - data
|
255
|
+
line << ' ' * indent
|
263
256
|
when :RULE then
|
264
257
|
width = 2 + data
|
265
|
-
|
266
|
-
|
258
|
+
line << '-' * width
|
267
259
|
_, _, peek_column, = peek_token
|
268
|
-
peek_column ||= column +
|
269
|
-
|
260
|
+
peek_column ||= column + width
|
261
|
+
indent = peek_column - column - width
|
262
|
+
line << ' ' * indent
|
270
263
|
when :TEXT then
|
271
|
-
|
272
|
-
|
273
|
-
if column <= margin then
|
274
|
-
unget
|
275
|
-
break
|
276
|
-
end
|
277
|
-
|
264
|
+
line << data
|
265
|
+
else # *LIST_TOKENS
|
278
266
|
list_marker = case type
|
279
|
-
when :BULLET
|
280
|
-
when :LABEL
|
281
|
-
when :
|
282
|
-
|
267
|
+
when :BULLET then data
|
268
|
+
when :LABEL then "[#{data}]"
|
269
|
+
when :NOTE then "#{data}::"
|
270
|
+
else # :LALPHA, :NUMBER, :UALPHA
|
271
|
+
"#{data}."
|
283
272
|
end
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
verbatim << data
|
292
|
-
break unless [:INDENT, :NEWLINE].include? peek_token[0]
|
293
|
-
else
|
294
|
-
unget
|
295
|
-
break
|
273
|
+
line << list_marker
|
274
|
+
peek_type, _, peek_column = peek_token
|
275
|
+
unless peek_type == :NEWLINE then
|
276
|
+
peek_column ||= column + list_marker.length
|
277
|
+
indent = peek_column - column - list_marker.length
|
278
|
+
line << ' ' * indent
|
279
|
+
end
|
296
280
|
end
|
281
|
+
|
297
282
|
end
|
298
283
|
|
284
|
+
verbatim << line << "\n" unless line.empty?
|
285
|
+
verbatim.parts.each { |p| p.slice!(0, min_indent) unless p == "\n" } if min_indent > 0
|
299
286
|
verbatim.normalize
|
300
287
|
|
301
288
|
p :verbatim_end => margin if @debug
|
@@ -313,65 +300,60 @@ class RDoc::Markup::Parser
|
|
313
300
|
end
|
314
301
|
|
315
302
|
##
|
316
|
-
# Parses the tokens into
|
317
|
-
|
318
|
-
|
303
|
+
# Parses the tokens into an array of RDoc::Markup::XXX objects,
|
304
|
+
# and appends them to the passed +parent+ RDoc::Markup::YYY object.
|
305
|
+
#
|
306
|
+
# Exits at the end of the token stream, or when it encounters a token
|
307
|
+
# in a column less than +indent+ (unless it is a NEWLINE).
|
308
|
+
#
|
309
|
+
# Returns +parent+.
|
310
|
+
|
311
|
+
def parse parent, indent = 0
|
319
312
|
p :parse_start => indent if @debug
|
320
313
|
|
321
|
-
document = []
|
322
|
-
|
323
314
|
until @tokens.empty? do
|
324
315
|
type, data, column, = get
|
325
316
|
|
326
|
-
if type
|
317
|
+
if type == :NEWLINE then
|
318
|
+
# trailing newlines are skipped below, so this is a blank line
|
319
|
+
parent << RDoc::Markup::BlankLine.new
|
320
|
+
skip :NEWLINE, false
|
321
|
+
next
|
322
|
+
end
|
323
|
+
|
324
|
+
# indentation change: break or verbattim
|
325
|
+
if column < indent then
|
327
326
|
unget
|
328
327
|
break
|
328
|
+
elsif column > indent then
|
329
|
+
unget
|
330
|
+
parent << build_verbatim(indent)
|
331
|
+
next
|
329
332
|
end
|
330
333
|
|
334
|
+
# indentation is the same
|
331
335
|
case type
|
332
336
|
when :HEADER then
|
333
|
-
|
334
|
-
when :INDENT then
|
335
|
-
if indent > data then
|
336
|
-
unget
|
337
|
-
break
|
338
|
-
elsif indent == data then
|
339
|
-
next
|
340
|
-
end
|
341
|
-
|
342
|
-
unget
|
343
|
-
document << build_verbatim(indent)
|
344
|
-
when :NEWLINE then
|
345
|
-
document << RDoc::Markup::BlankLine.new
|
346
|
-
skip :NEWLINE, false
|
337
|
+
parent << build_heading(data)
|
347
338
|
when :RULE then
|
348
|
-
|
339
|
+
parent << RDoc::Markup::Rule.new(data)
|
349
340
|
skip :NEWLINE
|
350
341
|
when :TEXT then
|
351
342
|
unget
|
352
|
-
|
353
|
-
|
354
|
-
# we're done with this paragraph (indent mismatch)
|
355
|
-
break if peek_token[0] == :TEXT
|
343
|
+
parent << build_paragraph(indent)
|
356
344
|
when *LIST_TOKENS then
|
357
345
|
unget
|
358
|
-
|
359
|
-
list = build_list(indent)
|
360
|
-
|
361
|
-
document << list if list
|
362
|
-
|
363
|
-
# we're done with this list (indent mismatch)
|
364
|
-
break if LIST_TOKENS.include? peek_token.first and indent > 0
|
346
|
+
parent << build_list(indent)
|
365
347
|
else
|
366
348
|
type, data, column, line = @current_token
|
367
|
-
raise ParseError,
|
368
|
-
"Unhandled token #{type} (#{data.inspect}) at #{line}:#{column}"
|
349
|
+
raise ParseError, "Unhandled token #{type} (#{data.inspect}) at #{line}:#{column}"
|
369
350
|
end
|
370
351
|
end
|
371
352
|
|
372
353
|
p :parse_end => indent if @debug
|
373
354
|
|
374
|
-
|
355
|
+
parent
|
356
|
+
|
375
357
|
end
|
376
358
|
|
377
359
|
##
|
@@ -384,63 +366,16 @@ class RDoc::Markup::Parser
|
|
384
366
|
end
|
385
367
|
|
386
368
|
##
|
387
|
-
# Skips
|
369
|
+
# Skips the next token if its type is +token_type+.
|
370
|
+
#
|
371
|
+
# Optionally raises an error if the next token is not of the expected type.
|
388
372
|
|
389
373
|
def skip token_type, error = true
|
390
|
-
type,
|
391
|
-
|
374
|
+
type, = get
|
392
375
|
return unless type # end of stream
|
393
|
-
|
394
376
|
return @current_token if token_type == type
|
395
|
-
|
396
377
|
unget
|
397
|
-
|
398
|
-
raise ParseError, "expected #{token_type} got #{@current_token.inspect}" if
|
399
|
-
error
|
400
|
-
end
|
401
|
-
|
402
|
-
##
|
403
|
-
# Consumes tokens until NEWLINE and turns them back into text
|
404
|
-
|
405
|
-
def text
|
406
|
-
text = ''
|
407
|
-
|
408
|
-
loop do
|
409
|
-
type, data, = get
|
410
|
-
|
411
|
-
text << case type
|
412
|
-
when :BULLET then
|
413
|
-
_, space, = get # SPACE
|
414
|
-
"*#{' ' * (space - 1)}"
|
415
|
-
when :LABEL then
|
416
|
-
_, space, = get # SPACE
|
417
|
-
"[#{data}]#{' ' * (space - data.length - 2)}"
|
418
|
-
when :LALPHA, :NUMBER, :UALPHA then
|
419
|
-
_, space, = get # SPACE
|
420
|
-
"#{data}.#{' ' * (space - 2)}"
|
421
|
-
when :NOTE then
|
422
|
-
_, space = get # SPACE
|
423
|
-
"#{data}::#{' ' * (space - data.length - 2)}"
|
424
|
-
when :TEXT then
|
425
|
-
data
|
426
|
-
when :NEWLINE then
|
427
|
-
unget
|
428
|
-
break
|
429
|
-
when nil then
|
430
|
-
break
|
431
|
-
else
|
432
|
-
raise ParseError, "unhandled token #{@current_token.inspect}"
|
433
|
-
end
|
434
|
-
end
|
435
|
-
|
436
|
-
text
|
437
|
-
end
|
438
|
-
|
439
|
-
##
|
440
|
-
# Calculates the column and line of the current token based on +offset+.
|
441
|
-
|
442
|
-
def token_pos offset
|
443
|
-
[offset - @line_pos, @line]
|
378
|
+
raise ParseError, "expected #{token_type} got #{@current_token.inspect}" if error
|
444
379
|
end
|
445
380
|
|
446
381
|
##
|
@@ -455,51 +390,62 @@ class RDoc::Markup::Parser
|
|
455
390
|
until s.eos? do
|
456
391
|
pos = s.pos
|
457
392
|
|
393
|
+
# leading spaces will be reflected by the column of the next token
|
394
|
+
# the only thing we loose are trailing spaces at the end of the file
|
395
|
+
next if s.scan(/ +/)
|
396
|
+
|
397
|
+
# note: after BULLET, LABEL, etc.,
|
398
|
+
# indent will be the column of the next non-newline token
|
399
|
+
|
458
400
|
@tokens << case
|
401
|
+
# [CR]LF => :NEWLINE
|
459
402
|
when s.scan(/\r?\n/) then
|
460
403
|
token = [:NEWLINE, s.matched, *token_pos(pos)]
|
461
404
|
@line_pos = s.pos
|
462
405
|
@line += 1
|
463
406
|
token
|
464
|
-
|
465
|
-
[:INDENT, s.matched_size, *token_pos(pos)]
|
407
|
+
# === text => :HEADER then :TEXT
|
466
408
|
when s.scan(/(=+)\s*/) then
|
467
409
|
level = s[1].length
|
468
410
|
level = 6 if level > 6
|
469
411
|
@tokens << [:HEADER, level, *token_pos(pos)]
|
470
|
-
|
471
412
|
pos = s.pos
|
472
413
|
s.scan(/.*/)
|
473
|
-
[:TEXT, s.matched, *token_pos(pos)]
|
474
|
-
|
414
|
+
[:TEXT, s.matched.sub(/\r$/, ''), *token_pos(pos)]
|
415
|
+
# --- (at least 3) and nothing else on the line => :RULE
|
416
|
+
when s.scan(/(-{3,}) *$/) then
|
475
417
|
[:RULE, s[1].length - 2, *token_pos(pos)]
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
418
|
+
# * or - followed by white space and text => :BULLET
|
419
|
+
when s.scan(/([*-]) +(\S)/) then
|
420
|
+
s.pos -= s[2].bytesize # unget \S
|
421
|
+
[:BULLET, s[1], *token_pos(pos)]
|
422
|
+
# A. text, a. text, 12. text => :UALPHA, :LALPHA, :NUMBER
|
423
|
+
when s.scan(/([a-z]|\d+)\. +(\S)/i) then
|
424
|
+
# FIXME if tab(s), the column will be wrong
|
425
|
+
# either support tabs everywhere by first expanding them to
|
426
|
+
# spaces, or assume that they will have been replaced
|
427
|
+
# before (and provide a check for that at least in debug
|
428
|
+
# mode)
|
480
429
|
list_label = s[1]
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
@tokens << [list_type, list_label, *token_pos(pos)]
|
494
|
-
[:SPACE, width, *token_pos(pos)]
|
430
|
+
s.pos -= s[2].bytesize # unget \S
|
431
|
+
list_type =
|
432
|
+
case list_label
|
433
|
+
when /[a-z]/ then :LALPHA
|
434
|
+
when /[A-Z]/ then :UALPHA
|
435
|
+
when /\d/ then :NUMBER
|
436
|
+
else
|
437
|
+
raise ParseError, "BUG token #{list_label}"
|
438
|
+
end
|
439
|
+
[list_type, list_label, *token_pos(pos)]
|
440
|
+
# [text] followed by spaces or end of line => :LABEL
|
495
441
|
when s.scan(/\[(.*?)\]( +|$)/) then
|
496
|
-
|
497
|
-
|
442
|
+
[:LABEL, s[1], *token_pos(pos)]
|
443
|
+
# text:: followed by spaces or end of line => :NOTE
|
498
444
|
when s.scan(/(.*?)::( +|$)/) then
|
499
|
-
|
500
|
-
|
445
|
+
[:NOTE, s[1], *token_pos(pos)]
|
446
|
+
# anything else: :TEXT
|
501
447
|
else s.scan(/.*/)
|
502
|
-
[:TEXT, s.matched, *token_pos(pos)]
|
448
|
+
[:TEXT, s.matched.sub(/\r$/, ''), *token_pos(pos)]
|
503
449
|
end
|
504
450
|
end
|
505
451
|
|
@@ -507,9 +453,17 @@ class RDoc::Markup::Parser
|
|
507
453
|
end
|
508
454
|
|
509
455
|
##
|
510
|
-
#
|
456
|
+
# Calculates the column and line of the current token based on +offset+.
|
457
|
+
|
458
|
+
def token_pos offset
|
459
|
+
[offset - @line_pos, @line]
|
460
|
+
end
|
461
|
+
|
462
|
+
##
|
463
|
+
# Returns the current token to the token stream
|
511
464
|
|
512
|
-
def unget
|
465
|
+
def unget
|
466
|
+
token = @current_token
|
513
467
|
p :unget => token if @debug
|
514
468
|
raise Error, 'too many #ungets' if token == @tokens.first
|
515
469
|
@tokens.unshift token if token
|