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

Methods

Public Class methods

[Source]

     # File markup/simple_markup/fragments.rb, line 127
127:     def initialize
128:       @fragments = []
129:     end

Public Instance methods

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # File markup/simple_markup/fragments.rb, line 135
135:     def each(&b)
136:       @fragments.each(&b)
137:     end

Factory for different fragment types

[Source]

     # File markup/simple_markup/fragments.rb, line 145
145:     def fragment_for(*args)
146:       Fragment.for(*args)
147:     end

tidy up at the end

[Source]

     # 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:

  • change Blank/ListEnd into ListEnd/Blank
  • remove blank lines at the front

[Source]

     # 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

For testing

[Source]

     # File markup/simple_markup/fragments.rb, line 140
140:     def to_a
141:       @fragments.map {|fragment| fragment.to_s}
142:     end

[Source]

     # File markup/simple_markup/fragments.rb, line 157
157:     def to_s
158:       @fragments.join("\n----\n")
159:     end

[Validate]