class ReVIEW::TOCParser
Public Class Methods
chapter_node(chap)
click to toggle source
# File lib/review/tocparser.rb, line 25 def self.chapter_node(chap) toc = self.parse(chap) $stderr.puts "warning: chapter #{toc.join} contains more than 1 chapter" unless toc.size == 1 toc.first end
parse(chap)
click to toggle source
# File lib/review/tocparser.rb, line 17 def self.parse(chap) stream = StringIO.new(chap.content, 'r:BOM|utf-8') new.parse(stream, chap).map do |root| root.number = chap.number root end end
Public Instance Methods
compile_label(line)
click to toggle source
# File lib/review/tocparser.rb, line 106 def compile_label(line) b = ReVIEW::TEXTBuilder.new dummy_book = ReVIEW::Book::Base.load dummy_chapter = ReVIEW::Book::Chapter.new(dummy_book, 1, '-', nil, StringIO.new) dummy_loc = Location.new('', StringIO.new) b.bind(ReVIEW::Compiler.new(b), dummy_chapter, dummy_loc) b.compile_inline(line) end
error!(filename, lineno, msg)
click to toggle source
# File lib/review/tocparser.rb, line 115 def error!(filename, lineno, msg) raise "#{filename}:#{lineno}: #{msg}" end
get_label(line)
click to toggle source
# File lib/review/tocparser.rb, line 101 def get_label(line) line = line.strip.sub(/\A=+\s*/, '') compile_label(line) end
parse(f, chap)
click to toggle source
# File lib/review/tocparser.rb, line 31 def parse(f, chap) roots = [] # list of chapters node_stack = [] filename = chap.path while line = f.gets case line when /\A\#@/ # do nothing next when /\A\s*\z/ # do nothing next when /\A(={2,})[\[\s\{]/ lev = $1.size if lev > 5 error! filename, f.lineno, "section level too deep: #{lev}" end label = get_label(line) if node_stack.empty? # missing chapter label dummy_chapter = Chapter.new(label, chap) node_stack.push dummy_chapter roots.push dummy_chapter end next if label =~ %r{\A\[/} # ex) "[/column]" sec = Section.new(lev, label.gsub(/\A\{.*?\}\s?/, '')) node_stack.pop until node_stack.last.level < sec.level 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} # do nothing next else # if node_stack.empty? # error! filename, f.lineno, 'text found before section label' # end 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