Imported File#ftype spec from rubyspecs.
[rbx.git] / lib / rdoc / markup / lines.rb
blob069492122f5262415999c51a3f030414fd92ba63
1 class RDoc::Markup
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.
8   class Line
9     INFINITY = 9999
11     LINE_TYPES = [
12       :BLANK,
13       :HEADING,
14       :LIST,
15       :PARAGRAPH,
16       :RULE,
17       :VERBATIM,
18     ]
20     # line type
21     attr_accessor :type
23     # The indentation nesting level
24     attr_accessor :level
26     # The contents
27     attr_accessor :text
29     # A prefix or parameter. For LIST lines, this is
30     # the text that introduced the list item (the label)
31     attr_accessor  :param
33     # A flag. For list lines, this is the type of the list
34     attr_accessor :flag
36     # the number of leading spaces
37     attr_accessor :leading_spaces
39     # true if this line has been deleted from the list of lines
40     attr_accessor :deleted
42     def initialize(text)
43       @text    = text.dup
44       @deleted = false
46       # expand tabs
47       1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)}  && $~ #`
49       # Strip trailing whitespace
50       @text.sub!(/\s+$/, '')
52       # and look for leading whitespace
53       if @text.length > 0
54         @text =~ /^(\s*)/
55         @leading_spaces = $1.length
56       else
57         @leading_spaces = INFINITY
58       end
59     end
61     # Return true if this line is blank
62     def blank?
63       @text.empty?
64     end
66     # stamp a line with a type, a level, a prefix, and a flag
67     def stamp(type, level, param="", flag=nil)
68       @type, @level, @param, @flag = type, level, param, flag
69     end
71     ##
72     # Strip off the leading margin
74     def strip_leading(size)
75       if @text.size > size
76         @text[0,size] = ""
77       else
78         @text = ""
79       end
80     end
82     def to_s
83       "#@type#@level: #@text"
84     end
85   end
87   ##
88   # A container for all the lines.
90   class Lines
92     include Enumerable
94     attr_reader :lines # :nodoc:
96     def initialize(lines)
97       @lines = lines
98       rewind
99     end
101     def empty?
102       @lines.size.zero?
103     end
105     def each
106       @lines.each do |line|
107         yield line unless line.deleted
108       end
109     end
111 #    def [](index)
112 #      @lines[index]
113 #    end
115     def rewind
116       @nextline = 0
117     end
119     def next
120       begin
121         res = @lines[@nextline]
122         @nextline += 1 if @nextline < @lines.size
123       end while res and res.deleted and @nextline < @lines.size
124       res
125     end
127     def unget
128       @nextline -= 1
129     end
131     def delete(a_line)
132       a_line.deleted = true
133     end
135     def normalize
136       margin = @lines.collect{|l| l.leading_spaces}.min
137       margin = 0 if margin == :INFINITY
138       @lines.each {|line| line.strip_leading(margin) } if margin > 0
139     end
141     def as_text
142       @lines.map {|l| l.text}.join("\n")
143     end
145     def line_types
146       @lines.map {|l| l.type }
147     end
149   end