Class | RDoc::Markup::LineCollection |
In: |
markup/fragments.rb
|
Parent: | Object |
Collect groups of lines together. Each group will end up containing a flow of text.
# File markup/fragments.rb, line 172 172: def accept(am, visitor) 173: visitor.start_accepting 174: 175: @fragments.each do |fragment| 176: case fragment 177: when Verbatim 178: visitor.accept_verbatim(am, fragment) 179: when Rule 180: visitor.accept_rule(am, fragment) 181: when ListStart 182: visitor.accept_list_start(am, fragment) 183: when ListEnd 184: visitor.accept_list_end(am, fragment) 185: when ListItem 186: visitor.accept_list_item(am, fragment) 187: when BlankLine 188: visitor.accept_blank_line(am, fragment) 189: when Heading 190: visitor.accept_heading(am, fragment) 191: when Paragraph 192: visitor.accept_paragraph(am, fragment) 193: end 194: end 195: 196: visitor.end_accepting 197: end
Inserts start/ends between list entries at the same level that have different element types
# File markup/fragments.rb, line 284 284: def add_list_breaks 285: res = @fragments 286: 287: @fragments = [] 288: list_stack = [] 289: 290: res.each do |fragment| 291: case fragment 292: when ListStart 293: list_stack.push fragment 294: when ListEnd 295: start = list_stack.pop 296: fragment.type = start.type 297: when ListItem 298: l = list_stack.last 299: if fragment.type != l.type 300: @fragments << ListEnd.new(l.level, l.type) 301: start = ListStart.new(l.level, fragment.param, fragment.type) 302: @fragments << start 303: list_stack.pop 304: list_stack.push start 305: end 306: else 307: ; 308: end 309: @fragments << fragment 310: end 311: end
List nesting is implicit given the level of indentation. Make it explicit, just to make life a tad easier for the output processors
# File markup/fragments.rb, line 246 246: def add_list_start_and_ends 247: level = 0 248: res = [] 249: type_stack = [] 250: 251: @fragments.each do |fragment| 252: # $stderr.puts "#{level} : #{fragment.class.name} : #{fragment.level}" 253: new_level = fragment.level 254: while (level < new_level) 255: level += 1 256: type = fragment.type 257: res << ListStart.new(level, fragment.param, type) if type 258: type_stack.push type 259: # $stderr.puts "Start: #{level}" 260: end 261: 262: while level > new_level 263: type = type_stack.pop 264: res << ListEnd.new(level, type) if type 265: level -= 1 266: # $stderr.puts "End: #{level}, #{type}" 267: end 268: 269: res << fragment 270: level = fragment.level 271: end 272: level.downto(1) do |i| 273: type = type_stack.pop 274: res << ListEnd.new(i, type) if type 275: end 276: 277: @fragments = res 278: end
If you have:
normal paragraph text. this is code and more code
You‘ll end up with the fragments Paragraph, BlankLine, Verbatim, BlankLine, Verbatim, BlankLine, etc.
The BlankLine in the middle of the verbatim chunk needs to be changed to a real verbatim newline, and the two verbatim blocks merged
# File markup/fragments.rb, line 215 215: def change_verbatim_blank_lines 216: frag_block = nil 217: blank_count = 0 218: @fragments.each_with_index do |frag, i| 219: if frag_block.nil? 220: frag_block = frag if Verbatim === frag 221: else 222: case frag 223: when Verbatim 224: blank_count.times { frag_block.add_text("\n") } 225: blank_count = 0 226: frag_block.add_text(frag.txt) 227: @fragments[i] = nil # remove out current fragment 228: when BlankLine 229: if frag_block 230: blank_count += 1 231: @fragments[i] = nil 232: end 233: else 234: frag_block = nil 235: blank_count = 0 236: end 237: end 238: end 239: @fragments.compact! 240: end
Factory for different fragment types
# File markup/fragments.rb, line 154 154: def fragment_for(*args) 155: Fragment.for(*args) 156: end
Tidy up at the end
# File markup/fragments.rb, line 161 161: def normalize 162: change_verbatim_blank_lines 163: add_list_start_and_ends 164: add_list_breaks 165: tidy_blank_lines 166: end
Tidy up the blank lines:
# File markup/fragments.rb, line 318 318: def tidy_blank_lines 319: (@fragments.size - 1).times do |i| 320: if BlankLine === @fragments[i] and ListEnd === @fragments[i+1] then 321: @fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i] 322: end 323: end 324: 325: # remove leading blanks 326: @fragments.each_with_index do |f, i| 327: break unless f.kind_of? BlankLine 328: @fragments[i] = nil 329: end 330: 331: @fragments.compact! 332: end