voloko-sdoc 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/rdoc/History.txt +254 -0
  2. data/rdoc/Manifest.txt +126 -0
  3. data/rdoc/README.txt +47 -0
  4. data/rdoc/RI.txt +58 -0
  5. data/rdoc/Rakefile +70 -0
  6. data/rdoc/bin/rdoc +35 -0
  7. data/rdoc/bin/ri +5 -0
  8. data/rdoc/lib/rdoc/alias.rb +54 -0
  9. data/rdoc/lib/rdoc/anon_class.rb +10 -0
  10. data/rdoc/lib/rdoc/any_method.rb +190 -0
  11. data/rdoc/lib/rdoc/attr.rb +79 -0
  12. data/rdoc/lib/rdoc/cache.rb +41 -0
  13. data/rdoc/lib/rdoc/class_module.rb +87 -0
  14. data/rdoc/lib/rdoc/code_object.rb +152 -0
  15. data/rdoc/lib/rdoc/code_objects.rb +23 -0
  16. data/rdoc/lib/rdoc/constant.rb +36 -0
  17. data/rdoc/lib/rdoc/context.rb +712 -0
  18. data/rdoc/lib/rdoc/diagram.rb +340 -0
  19. data/rdoc/lib/rdoc/dot.rb +249 -0
  20. data/rdoc/lib/rdoc/generator/darkfish.rb +455 -0
  21. data/rdoc/lib/rdoc/generator/markup.rb +194 -0
  22. data/rdoc/lib/rdoc/generator/ri.rb +230 -0
  23. data/rdoc/lib/rdoc/generator/template/darkfish/classpage.rhtml +281 -0
  24. data/rdoc/lib/rdoc/generator/template/darkfish/filepage.rhtml +112 -0
  25. data/rdoc/lib/rdoc/generator/template/darkfish/images/brick.png +0 -0
  26. data/rdoc/lib/rdoc/generator/template/darkfish/images/brick_link.png +0 -0
  27. data/rdoc/lib/rdoc/generator/template/darkfish/images/bug.png +0 -0
  28. data/rdoc/lib/rdoc/generator/template/darkfish/images/bullet_black.png +0 -0
  29. data/rdoc/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png +0 -0
  30. data/rdoc/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png +0 -0
  31. data/rdoc/lib/rdoc/generator/template/darkfish/images/date.png +0 -0
  32. data/rdoc/lib/rdoc/generator/template/darkfish/images/find.png +0 -0
  33. data/rdoc/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif +0 -0
  34. data/rdoc/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png +0 -0
  35. data/rdoc/lib/rdoc/generator/template/darkfish/images/package.png +0 -0
  36. data/rdoc/lib/rdoc/generator/template/darkfish/images/page_green.png +0 -0
  37. data/rdoc/lib/rdoc/generator/template/darkfish/images/page_white_text.png +0 -0
  38. data/rdoc/lib/rdoc/generator/template/darkfish/images/page_white_width.png +0 -0
  39. data/rdoc/lib/rdoc/generator/template/darkfish/images/plugin.png +0 -0
  40. data/rdoc/lib/rdoc/generator/template/darkfish/images/ruby.png +0 -0
  41. data/rdoc/lib/rdoc/generator/template/darkfish/images/tag_green.png +0 -0
  42. data/rdoc/lib/rdoc/generator/template/darkfish/images/wrench.png +0 -0
  43. data/rdoc/lib/rdoc/generator/template/darkfish/images/wrench_orange.png +0 -0
  44. data/rdoc/lib/rdoc/generator/template/darkfish/images/zoom.png +0 -0
  45. data/rdoc/lib/rdoc/generator/template/darkfish/index.rhtml +64 -0
  46. data/rdoc/lib/rdoc/generator/template/darkfish/js/darkfish.js +116 -0
  47. data/rdoc/lib/rdoc/generator/template/darkfish/js/jquery.js +32 -0
  48. data/rdoc/lib/rdoc/generator/template/darkfish/js/quicksearch.js +114 -0
  49. data/rdoc/lib/rdoc/generator/template/darkfish/js/thickbox-compressed.js +10 -0
  50. data/rdoc/lib/rdoc/generator/template/darkfish/rdoc.css +696 -0
  51. data/rdoc/lib/rdoc/generator.rb +8 -0
  52. data/rdoc/lib/rdoc/ghost_method.rb +8 -0
  53. data/rdoc/lib/rdoc/include.rb +39 -0
  54. data/rdoc/lib/rdoc/known_classes.rb +68 -0
  55. data/rdoc/lib/rdoc/markup/attribute_manager.rb +311 -0
  56. data/rdoc/lib/rdoc/markup/formatter.rb +25 -0
  57. data/rdoc/lib/rdoc/markup/fragments.rb +377 -0
  58. data/rdoc/lib/rdoc/markup/inline.rb +126 -0
  59. data/rdoc/lib/rdoc/markup/lines.rb +156 -0
  60. data/rdoc/lib/rdoc/markup/preprocess.rb +80 -0
  61. data/rdoc/lib/rdoc/markup/to_flow.rb +211 -0
  62. data/rdoc/lib/rdoc/markup/to_html.rb +406 -0
  63. data/rdoc/lib/rdoc/markup/to_html_crossref.rb +140 -0
  64. data/rdoc/lib/rdoc/markup/to_latex.rb +328 -0
  65. data/rdoc/lib/rdoc/markup/to_test.rb +53 -0
  66. data/rdoc/lib/rdoc/markup/to_texinfo.rb +73 -0
  67. data/rdoc/lib/rdoc/markup.rb +378 -0
  68. data/rdoc/lib/rdoc/meta_method.rb +8 -0
  69. data/rdoc/lib/rdoc/normal_class.rb +18 -0
  70. data/rdoc/lib/rdoc/normal_module.rb +34 -0
  71. data/rdoc/lib/rdoc/options.rb +542 -0
  72. data/rdoc/lib/rdoc/parser/c.rb +678 -0
  73. data/rdoc/lib/rdoc/parser/perl.rb +165 -0
  74. data/rdoc/lib/rdoc/parser/ruby.rb +2904 -0
  75. data/rdoc/lib/rdoc/parser/simple.rb +39 -0
  76. data/rdoc/lib/rdoc/parser.rb +138 -0
  77. data/rdoc/lib/rdoc/rdoc.rb +375 -0
  78. data/rdoc/lib/rdoc/require.rb +32 -0
  79. data/rdoc/lib/rdoc/ri/cache.rb +187 -0
  80. data/rdoc/lib/rdoc/ri/descriptions.rb +156 -0
  81. data/rdoc/lib/rdoc/ri/display.rb +340 -0
  82. data/rdoc/lib/rdoc/ri/driver.rb +828 -0
  83. data/rdoc/lib/rdoc/ri/formatter.rb +654 -0
  84. data/rdoc/lib/rdoc/ri/paths.rb +93 -0
  85. data/rdoc/lib/rdoc/ri/reader.rb +106 -0
  86. data/rdoc/lib/rdoc/ri/util.rb +79 -0
  87. data/rdoc/lib/rdoc/ri/writer.rb +68 -0
  88. data/rdoc/lib/rdoc/ri.rb +8 -0
  89. data/rdoc/lib/rdoc/single_class.rb +8 -0
  90. data/rdoc/lib/rdoc/stats.rb +178 -0
  91. data/rdoc/lib/rdoc/task.rb +276 -0
  92. data/rdoc/lib/rdoc/tokenstream.rb +33 -0
  93. data/rdoc/lib/rdoc/top_level.rb +242 -0
  94. data/rdoc/lib/rdoc.rb +398 -0
  95. metadata +1 -1
@@ -0,0 +1,377 @@
1
+ require 'rdoc/markup'
2
+ require 'rdoc/markup/lines'
3
+
4
+ class RDoc::Markup
5
+
6
+ ##
7
+ # A Fragment is a chunk of text, subclassed as a paragraph, a list
8
+ # entry, or verbatim text.
9
+
10
+ class Fragment
11
+ attr_reader :level, :param, :txt
12
+ attr_accessor :type
13
+
14
+ ##
15
+ # This is a simple factory system that lets us associate fragement
16
+ # types (a string) with a subclass of fragment
17
+
18
+ TYPE_MAP = {}
19
+
20
+ def self.type_name(name)
21
+ TYPE_MAP[name] = self
22
+ end
23
+
24
+ def self.for(line)
25
+ klass = TYPE_MAP[line.type] ||
26
+ raise("Unknown line type: '#{line.type.inspect}:' '#{line.text}'")
27
+ return klass.new(line.level, line.param, line.flag, line.text)
28
+ end
29
+
30
+ def initialize(level, param, type, txt)
31
+ @level = level
32
+ @param = param
33
+ @type = type
34
+ @txt = ""
35
+ add_text(txt) if txt
36
+ end
37
+
38
+ def add_text(txt)
39
+ @txt << " " if @txt.length > 0
40
+ @txt << txt.tr_s("\n ", " ").strip
41
+ end
42
+
43
+ def to_s
44
+ "L#@level: #{self.class.name.split('::')[-1]}\n#@txt"
45
+ end
46
+
47
+ end
48
+
49
+ ##
50
+ # A paragraph is a fragment which gets wrapped to fit. We remove all
51
+ # newlines when we're created, and have them put back on output.
52
+
53
+ class Paragraph < Fragment
54
+ type_name :PARAGRAPH
55
+ end
56
+
57
+ ##
58
+ # An empty line
59
+
60
+ class BlankLine < Paragraph
61
+ type_name :BLANK
62
+ end
63
+
64
+ ##
65
+ # A heading
66
+
67
+ class Heading < Paragraph
68
+ type_name :HEADING
69
+
70
+ ##
71
+ # Level of heading, smaller is more important
72
+
73
+ def head_level
74
+ @param.to_i
75
+ end
76
+
77
+ end
78
+
79
+ ##
80
+ # A List is a fragment with some kind of label
81
+
82
+ class ListBase < Paragraph
83
+ LIST_TYPES = [
84
+ :BULLET,
85
+ :NUMBER,
86
+ :UPPERALPHA,
87
+ :LOWERALPHA,
88
+ :LABELED,
89
+ :NOTE,
90
+ ]
91
+ end
92
+
93
+ ##
94
+ # An item in a list
95
+
96
+ class ListItem < ListBase
97
+ type_name :LIST
98
+
99
+ def to_s # :nodoc:
100
+ text = if [:NOTE, :LABELED].include? type then
101
+ "#{@param}: #{@txt}"
102
+ else
103
+ @txt
104
+ end
105
+
106
+ "L#@level: #{type} #{self.class.name.split('::')[-1]}\n#{text}"
107
+ end
108
+
109
+ end
110
+
111
+ ##
112
+ # Start of a list
113
+
114
+ class ListStart < ListBase
115
+
116
+ ##
117
+ # Creates a ListStart with nesting +level+
118
+
119
+ def initialize(level, param, type)
120
+ super(level, param, type, nil)
121
+ end
122
+ end
123
+
124
+ ##
125
+ # End of a list
126
+
127
+ class ListEnd < ListBase
128
+
129
+ ##
130
+ # Creates a ListEnd with nesting +level+
131
+
132
+ def initialize(level, type)
133
+ super(level, "", type, nil)
134
+ end
135
+ end
136
+
137
+ ##
138
+ # Verbatim code contains lines that don't get wrapped.
139
+
140
+ class Verbatim < Fragment
141
+ type_name :VERBATIM
142
+
143
+ ##
144
+ # Adds +txt+ to this verbatim
145
+
146
+ def add_text(txt)
147
+ @txt << txt.chomp << "\n"
148
+ end
149
+
150
+ end
151
+
152
+ ##
153
+ # A horizontal rule
154
+
155
+ class Rule < Fragment
156
+ type_name :RULE
157
+ end
158
+
159
+ ##
160
+ # Collect groups of lines together. Each group will end up containing a flow
161
+ # of text.
162
+
163
+ class LineCollection
164
+
165
+ ##
166
+ # Creates a new collection of lines
167
+
168
+ def initialize
169
+ @fragments = []
170
+ end
171
+
172
+ ##
173
+ # Adds +fragment+ to the collection
174
+
175
+ def add(fragment)
176
+ @fragments << fragment
177
+ end
178
+
179
+ ##
180
+ # Iterates over the lines in the collection
181
+
182
+ def each(&b)
183
+ @fragments.each(&b)
184
+ end
185
+
186
+ def to_a # :nodoc:
187
+ @fragments.map {|fragment| fragment.to_s}
188
+ end
189
+
190
+ ##
191
+ # Factory for different fragment types
192
+
193
+ def fragment_for(*args)
194
+ Fragment.for(*args)
195
+ end
196
+
197
+ ##
198
+ # Tidy up at the end
199
+
200
+ def normalize
201
+ change_verbatim_blank_lines
202
+ add_list_start_and_ends
203
+ add_list_breaks
204
+ tidy_blank_lines
205
+ end
206
+
207
+ def to_s # :nodoc:
208
+ @fragments.join("\n----\n")
209
+ end
210
+
211
+ def accept(am, visitor)
212
+ visitor.start_accepting
213
+
214
+ @fragments.each do |fragment|
215
+ case fragment
216
+ when Verbatim
217
+ visitor.accept_verbatim(am, fragment)
218
+ when Rule
219
+ visitor.accept_rule(am, fragment)
220
+ when ListStart
221
+ visitor.accept_list_start(am, fragment)
222
+ when ListEnd
223
+ visitor.accept_list_end(am, fragment)
224
+ when ListItem
225
+ visitor.accept_list_item(am, fragment)
226
+ when BlankLine
227
+ visitor.accept_blank_line(am, fragment)
228
+ when Heading
229
+ visitor.accept_heading(am, fragment)
230
+ when Paragraph
231
+ visitor.accept_paragraph(am, fragment)
232
+ end
233
+ end
234
+
235
+ visitor.end_accepting
236
+ end
237
+
238
+ private
239
+
240
+ ##
241
+ # If you have:
242
+ #
243
+ # normal paragraph text.
244
+ #
245
+ # this is code
246
+ #
247
+ # and more code
248
+ #
249
+ # You'll end up with the fragments Paragraph, BlankLine, Verbatim,
250
+ # BlankLine, Verbatim, BlankLine, etc.
251
+ #
252
+ # The BlankLine in the middle of the verbatim chunk needs to be changed to
253
+ # a real verbatim newline, and the two verbatim blocks merged
254
+
255
+ def change_verbatim_blank_lines
256
+ frag_block = nil
257
+ blank_count = 0
258
+ @fragments.each_with_index do |frag, i|
259
+ if frag_block.nil?
260
+ frag_block = frag if Verbatim === frag
261
+ else
262
+ case frag
263
+ when Verbatim
264
+ blank_count.times { frag_block.add_text("\n") }
265
+ blank_count = 0
266
+ frag_block.add_text(frag.txt)
267
+ @fragments[i] = nil # remove out current fragment
268
+ when BlankLine
269
+ if frag_block
270
+ blank_count += 1
271
+ @fragments[i] = nil
272
+ end
273
+ else
274
+ frag_block = nil
275
+ blank_count = 0
276
+ end
277
+ end
278
+ end
279
+ @fragments.compact!
280
+ end
281
+
282
+ ##
283
+ # List nesting is implicit given the level of indentation. Make it
284
+ # explicit, just to make life a tad easier for the output processors
285
+
286
+ def add_list_start_and_ends
287
+ level = 0
288
+ res = []
289
+ type_stack = []
290
+
291
+ @fragments.each do |fragment|
292
+ # $stderr.puts "#{level} : #{fragment.class.name} : #{fragment.level}"
293
+ new_level = fragment.level
294
+ while (level < new_level)
295
+ level += 1
296
+ type = fragment.type
297
+ res << ListStart.new(level, fragment.param, type) if type
298
+ type_stack.push type
299
+ # $stderr.puts "Start: #{level}"
300
+ end
301
+
302
+ while level > new_level
303
+ type = type_stack.pop
304
+ res << ListEnd.new(level, type) if type
305
+ level -= 1
306
+ # $stderr.puts "End: #{level}, #{type}"
307
+ end
308
+
309
+ res << fragment
310
+ level = fragment.level
311
+ end
312
+ level.downto(1) do |i|
313
+ type = type_stack.pop
314
+ res << ListEnd.new(i, type) if type
315
+ end
316
+
317
+ @fragments = res
318
+ end
319
+
320
+ ##
321
+ # Inserts start/ends between list entries at the same level that have
322
+ # different element types
323
+
324
+ def add_list_breaks
325
+ res = @fragments
326
+
327
+ @fragments = []
328
+ list_stack = []
329
+
330
+ res.each do |fragment|
331
+ case fragment
332
+ when ListStart
333
+ list_stack.push fragment
334
+ when ListEnd
335
+ start = list_stack.pop
336
+ fragment.type = start.type
337
+ when ListItem
338
+ l = list_stack.last
339
+ if fragment.type != l.type
340
+ @fragments << ListEnd.new(l.level, l.type)
341
+ start = ListStart.new(l.level, fragment.param, fragment.type)
342
+ @fragments << start
343
+ list_stack.pop
344
+ list_stack.push start
345
+ end
346
+ else
347
+ ;
348
+ end
349
+ @fragments << fragment
350
+ end
351
+ end
352
+
353
+ ##
354
+ # Tidy up the blank lines:
355
+ # * change Blank/ListEnd into ListEnd/Blank
356
+ # * remove blank lines at the front
357
+
358
+ def tidy_blank_lines
359
+ (@fragments.size - 1).times do |i|
360
+ if BlankLine === @fragments[i] and ListEnd === @fragments[i+1] then
361
+ @fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i]
362
+ end
363
+ end
364
+
365
+ # remove leading blanks
366
+ @fragments.each_with_index do |f, i|
367
+ break unless f.kind_of? BlankLine
368
+ @fragments[i] = nil
369
+ end
370
+
371
+ @fragments.compact!
372
+ end
373
+
374
+ end
375
+
376
+ end
377
+
@@ -0,0 +1,126 @@
1
+ require 'rdoc/markup'
2
+
3
+ class RDoc::Markup
4
+
5
+ ##
6
+ # We manage a set of attributes. Each attribute has a symbol name and a bit
7
+ # value.
8
+
9
+ class Attribute
10
+ SPECIAL = 1
11
+
12
+ @@name_to_bitmap = { :_SPECIAL_ => SPECIAL }
13
+ @@next_bitmap = 2
14
+
15
+ def self.bitmap_for(name)
16
+ bitmap = @@name_to_bitmap[name]
17
+ unless bitmap then
18
+ bitmap = @@next_bitmap
19
+ @@next_bitmap <<= 1
20
+ @@name_to_bitmap[name] = bitmap
21
+ end
22
+ bitmap
23
+ end
24
+
25
+ def self.as_string(bitmap)
26
+ return "none" if bitmap.zero?
27
+ res = []
28
+ @@name_to_bitmap.each do |name, bit|
29
+ res << name if (bitmap & bit) != 0
30
+ end
31
+ res.join(",")
32
+ end
33
+
34
+ def self.each_name_of(bitmap)
35
+ @@name_to_bitmap.each do |name, bit|
36
+ next if bit == SPECIAL
37
+ yield name.to_s if (bitmap & bit) != 0
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ AttrChanger = Struct.new :turn_on, :turn_off
44
+
45
+ ##
46
+ # An AttrChanger records a change in attributes. It contains a bitmap of the
47
+ # attributes to turn on, and a bitmap of those to turn off.
48
+
49
+ class AttrChanger
50
+ def to_s # :nodoc:
51
+ "Attr: +#{Attribute.as_string(turn_on)}/-#{Attribute.as_string(turn_on)}"
52
+ end
53
+ end
54
+
55
+ ##
56
+ # An array of attributes which parallels the characters in a string.
57
+
58
+ class AttrSpan
59
+
60
+ ##
61
+ # Creates a new AttrSpan for +length+ characters
62
+
63
+ def initialize(length)
64
+ @attrs = Array.new(length, 0)
65
+ end
66
+
67
+ ##
68
+ # Toggles +bits+ from +start+ to +length+
69
+ def set_attrs(start, length, bits)
70
+ for i in start ... (start+length)
71
+ @attrs[i] |= bits
72
+ end
73
+ end
74
+
75
+ ##
76
+ # Acccesses flags for character +n+
77
+
78
+ def [](n)
79
+ @attrs[n]
80
+ end
81
+
82
+ end
83
+
84
+ ##
85
+ # Hold details of a special sequence
86
+
87
+ class Special
88
+
89
+ ##
90
+ # Special type
91
+
92
+ attr_reader :type
93
+
94
+ ##
95
+ # Special text
96
+
97
+ attr_accessor :text
98
+
99
+ ##
100
+ # Creates a new special sequence of +type+ with +text+
101
+
102
+ def initialize(type, text)
103
+ @type, @text = type, text
104
+ end
105
+
106
+ ##
107
+ # Specials are equal when the have the same text and type
108
+
109
+ def ==(o)
110
+ self.text == o.text && self.type == o.type
111
+ end
112
+
113
+ def inspect # :nodoc:
114
+ "#<RDoc::Markup::Special:0x%x @type=%p, name=%p @text=%p>" % [
115
+ object_id, @type, RDoc::Markup::Attribute.as_string(type), text.dump]
116
+ end
117
+
118
+ def to_s # :nodoc:
119
+ "Special: type=#{type}, name=#{RDoc::Markup::Attribute.as_string type}, text=#{text.dump}"
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+
126
+ require 'rdoc/markup/attribute_manager'
@@ -0,0 +1,156 @@
1
+ class RDoc::Markup
2
+
3
+ ##
4
+ # We store the lines we're working on as objects of class Line. These
5
+ # contain the text of the line, along with a flag indicating the line type,
6
+ # and an indentation level.
7
+
8
+ class Line
9
+
10
+ ##
11
+ # Not really
12
+
13
+ INFINITY = 9999
14
+
15
+ LINE_TYPES = [
16
+ :BLANK,
17
+ :HEADING,
18
+ :LIST,
19
+ :PARAGRAPH,
20
+ :RULE,
21
+ :VERBATIM,
22
+ ]
23
+
24
+ # line type
25
+ attr_accessor :type
26
+
27
+ # The indentation nesting level
28
+ attr_accessor :level
29
+
30
+ # The contents
31
+ attr_accessor :text
32
+
33
+ # A prefix or parameter. For LIST lines, this is
34
+ # the text that introduced the list item (the label)
35
+ attr_accessor :param
36
+
37
+ # A flag. For list lines, this is the type of the list
38
+ attr_accessor :flag
39
+
40
+ # the number of leading spaces
41
+ attr_accessor :leading_spaces
42
+
43
+ # true if this line has been deleted from the list of lines
44
+ attr_accessor :deleted
45
+
46
+ def initialize(text)
47
+ @text = text.dup
48
+ @deleted = false
49
+
50
+ # expand tabs
51
+ 1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)} && $~ #`
52
+
53
+ # Strip trailing whitespace
54
+ @text.sub!(/\s+$/, '')
55
+
56
+ # and look for leading whitespace
57
+ if @text.length > 0
58
+ @text =~ /^(\s*)/
59
+ @leading_spaces = $1.length
60
+ else
61
+ @leading_spaces = INFINITY
62
+ end
63
+ end
64
+
65
+ # Return true if this line is blank
66
+ def blank?
67
+ @text.empty?
68
+ end
69
+
70
+ # stamp a line with a type, a level, a prefix, and a flag
71
+ def stamp(type, level, param="", flag=nil)
72
+ @type, @level, @param, @flag = type, level, param, flag
73
+ end
74
+
75
+ ##
76
+ # Strip off the leading margin
77
+
78
+ def strip_leading(size)
79
+ if @text.size > size
80
+ @text[0,size] = ""
81
+ else
82
+ @text = ""
83
+ end
84
+ end
85
+
86
+ def to_s
87
+ "#@type#@level: #@text"
88
+ end
89
+ end
90
+
91
+ ##
92
+ # A container for all the lines.
93
+
94
+ class Lines
95
+
96
+ include Enumerable
97
+
98
+ attr_reader :lines # :nodoc:
99
+
100
+ def initialize(lines)
101
+ @lines = lines
102
+ rewind
103
+ end
104
+
105
+ def empty?
106
+ @lines.size.zero?
107
+ end
108
+
109
+ def each
110
+ @lines.each do |line|
111
+ yield line unless line.deleted
112
+ end
113
+ end
114
+
115
+ # def [](index)
116
+ # @lines[index]
117
+ # end
118
+
119
+ def rewind
120
+ @nextline = 0
121
+ end
122
+
123
+ def next
124
+ begin
125
+ res = @lines[@nextline]
126
+ @nextline += 1 if @nextline < @lines.size
127
+ end while res and res.deleted and @nextline < @lines.size
128
+ res
129
+ end
130
+
131
+ def unget
132
+ @nextline -= 1
133
+ end
134
+
135
+ def delete(a_line)
136
+ a_line.deleted = true
137
+ end
138
+
139
+ def normalize
140
+ margin = @lines.collect{|l| l.leading_spaces}.min
141
+ margin = 0 if margin == :INFINITY
142
+ @lines.each {|line| line.strip_leading(margin) } if margin > 0
143
+ end
144
+
145
+ def as_text
146
+ @lines.map {|l| l.text}.join("\n")
147
+ end
148
+
149
+ def line_types
150
+ @lines.map {|l| l.type }
151
+ end
152
+
153
+ end
154
+
155
+ end
156
+