class ReVIEW::TOCParser

Public Class Methods

parse(chap) click to toggle source
# File lib/review/tocparser.rb, line 20
def TOCParser.parse(chap)
  chap.open {|f|
    stream = Preprocessor::Strip.new(f)
    new.parse(stream, chap.id, chap.path, chap).map {|root|
      root.number = chap.number
      root
    }
  }
end

Public Instance Methods

compile_label(line) click to toggle source
# File lib/review/tocparser.rb, line 99
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 108
def error!(filename, lineno, msg)
  raise "#{filename}:#{lineno}: #{msg}"
end
get_label(line) click to toggle source
# File lib/review/tocparser.rb, line 94
def get_label(line)
  line = line.strip.sub(/\A=+\s*/, '')
  compile_label(line)
end
parse(f, id, filename, chap) click to toggle source
# File lib/review/tocparser.rb, line 30
def parse(f, id, filename, chap)
  roots = []
  path = []

  while line = f.gets
    line.sub!(/\A\xEF\xBB\xBF/u, '') # remove BOM
    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
      if path.empty?
        # missing chapter label
        path.push Chapter.new(get_label(line), id, filename, chap.book.page_metric)
        roots.push path.first
      end
      next if get_label(line) =~ /\A\[\// # ex) "[/column]"
      new = Section.new(lev, get_label(line).gsub(/\A\{.*?\}\s?/, ""))
      until path.last.level < new.level
        path.pop
      end
      path.last.add_child new
      path.push new

    when /\A= /
      path.clear
      path.push Chapter.new(get_label(line), id, filename, chap.book.page_metric)
      roots.push path.first

    when %r<\A//\w+(?:\[.*?\])*\{\s*\z>
      if path.empty?
        error! filename, f.lineno, 'list found before section label'
      end
      path.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
      #if path.empty?
      #  error! filename, f.lineno, 'text found before section label'
      #end
      next if path.empty?
      path.last.add_child(par = Paragraph.new(chap.book.page_metric))
      par.add line
      while line = f.gets
        break if /\A\s*\z/ =~ line
        par.add line
      end
    end
  end

  roots
end