Class | SM::LineCollection |
In: |
markup/simple_markup/fragments.rb
|
Parent: | Object |
Collect groups of lines together. Each group will end up containing a flow of text
# File markup/simple_markup/fragments.rb, line 127 127: def initialize 128: @fragments = [] 129: end
# File markup/simple_markup/fragments.rb, line 161 161: def accept(am, visitor) 162: 163: visitor.start_accepting 164: 165: @fragments.each do |fragment| 166: case fragment 167: when Verbatim 168: visitor.accept_verbatim(am, fragment) 169: when Rule 170: visitor.accept_rule(am, fragment) 171: when ListStart 172: visitor.accept_list_start(am, fragment) 173: when ListEnd 174: visitor.accept_list_end(am, fragment) 175: when ListItem 176: visitor.accept_list_item(am, fragment) 177: when BlankLine 178: visitor.accept_blank_line(am, fragment) 179: when Heading 180: visitor.accept_heading(am, fragment) 181: when Paragraph 182: visitor.accept_paragraph(am, fragment) 183: end 184: end 185: 186: visitor.end_accepting 187: end
# File markup/simple_markup/fragments.rb, line 131 131: def add(fragment) 132: @fragments << fragment 133: end
now insert start/ends between list entries at the same level that have different element types
# File markup/simple_markup/fragments.rb, line 276 276: def add_list_breaks 277: res = @fragments 278: 279: @fragments = [] 280: list_stack = [] 281: 282: res.each do |fragment| 283: case fragment 284: when ListStart 285: list_stack.push fragment 286: when ListEnd 287: start = list_stack.pop 288: fragment.type = start.type 289: when ListItem 290: l = list_stack.last 291: if fragment.type != l.type 292: @fragments << ListEnd.new(l.level, l.type) 293: start = ListStart.new(l.level, fragment.param, fragment.type) 294: @fragments << start 295: list_stack.pop 296: list_stack.push start 297: end 298: else 299: ; 300: end 301: @fragments << fragment 302: end 303: end
List nesting is implicit given the level of Make it explicit, just to make life a tad easier for the output processors
# File markup/simple_markup/fragments.rb, line 239 239: def add_list_start_and_ends 240: level = 0 241: res = [] 242: type_stack = [] 243: 244: @fragments.each do |fragment| 245: # $stderr.puts "#{level} : #{fragment.class.name} : #{fragment.level}" 246: new_level = fragment.level 247: while (level < new_level) 248: level += 1 249: type = fragment.type 250: res << ListStart.new(level, fragment.param, type) if type 251: type_stack.push type 252: # $stderr.puts "Start: #{level}" 253: end 254: 255: while level > new_level 256: type = type_stack.pop 257: res << ListEnd.new(level, type) if type 258: level -= 1 259: # $stderr.puts "End: #{level}, #{type}" 260: end 261: 262: res << fragment 263: level = fragment.level 264: end 265: level.downto(1) do |i| 266: type = type_stack.pop 267: res << ListEnd.new(i, type) if type 268: end 269: 270: @fragments = res 271: 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/simple_markup/fragments.rb, line 208 208: def change_verbatim_blank_lines 209: frag_block = nil 210: blank_count = 0 211: @fragments.each_with_index do |frag, i| 212: if frag_block.nil? 213: frag_block = frag if Verbatim === frag 214: else 215: case frag 216: when Verbatim 217: blank_count.times { frag_block.add_text("\n") } 218: blank_count = 0 219: frag_block.add_text(frag.txt) 220: @fragments[i] = nil # remove out current fragment 221: when BlankLine 222: if frag_block 223: blank_count += 1 224: @fragments[i] = nil 225: end 226: else 227: frag_block = nil 228: blank_count = 0 229: end 230: end 231: end 232: @fragments.compact! 233: end
# File markup/simple_markup/fragments.rb, line 135 135: def each(&b) 136: @fragments.each(&b) 137: end
Factory for different fragment types
# File markup/simple_markup/fragments.rb, line 145 145: def fragment_for(*args) 146: Fragment.for(*args) 147: end
tidy up at the end
# File markup/simple_markup/fragments.rb, line 150 150: def normalize 151: change_verbatim_blank_lines 152: add_list_start_and_ends 153: add_list_breaks 154: tidy_blank_lines 155: end
Finally tidy up the blank lines:
# File markup/simple_markup/fragments.rb, line 309 309: def tidy_blank_lines 310: (@fragments.size - 1).times do |i| 311: if @fragments[i].kind_of?(BlankLine) and 312: @fragments[i+1].kind_of?(ListEnd) 313: @fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i] 314: end 315: end 316: 317: # remove leading blanks 318: @fragments.each_with_index do |f, i| 319: break unless f.kind_of? BlankLine 320: @fragments[i] = nil 321: end 322: 323: @fragments.compact! 324: end