def parse(f, chap)
roots = []
node_stack = []
filename = chap.path
while line = f.gets
case line
when /\A\#@/
;
when /\A\s*\z/
;
when /\A(={2,})[\[\s\{]/
lev = $1.size
error! filename, f.lineno, "section level too deep: #{lev}" if lev > 5
label = get_label(line)
if node_stack.empty?
dummy_chapter = Chapter.new(label, chap)
node_stack.push dummy_chapter
roots.push dummy_chapter
end
next if label =~ /\A\[\//
sec = Section.new(lev, label.gsub(/\A\{.*?\}\s?/, ""))
until node_stack.last.level < sec.level
node_stack.pop
end
node_stack.last.add_child sec
node_stack.push sec
when /\A=[^=]/
label = get_label(line)
node_stack.clear
new_chapter = Chapter.new(label, chap)
node_stack.push new_chapter
roots.push new_chapter
when %r<\A//\w+(?:\[.*?\])*\{\s*\z>
if node_stack.empty?
error! filename, f.lineno, 'list found before section label'
end
node_stack.last.add_child(list = List.new)
beg = f.lineno
list.add line
while line = f.gets
break if %r<\A//\}> =~ line
list.add line
end
error! filename, beg, 'unterminated list' unless line
when %r<\A//\w>
;
else
next if node_stack.empty?
node_stack.last.add_child(par = Paragraph.new(chap))
par.add line
while line = f.gets
break if /\A\s*\z/ =~ line
par.add line
end
end
end
roots
end