Skip to content

Commit

Permalink
Merge pull request #486 from kmuto/toc-parser
Browse files Browse the repository at this point in the history
review-index: refine TOCParser and TOCPrinter
  • Loading branch information
takahashim committed Feb 13, 2016
2 parents 2ceb3a4 + 484a5c4 commit aa968cd
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 145 deletions.
10 changes: 6 additions & 4 deletions bin/review-index
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ def _main
opts.on('--html', 'output in HTML (deprecated)') {
printer_class = ReVIEW::HTMLTOCPrinter
}
opts.on('--idg', 'output in InDesign XML') {
printer_class = ReVIEW::IDGTOCPrinter
}
opts.on('--help', 'print this message and quit.') {
puts opts.help
exit 0
Expand All @@ -91,7 +88,12 @@ def _main
end

begin
printer_class.new(upper, param).print_book source
printer = printer_class.new(upper, param)
if source.kind_of?(ReVIEW::Book::Part)
printer.print_part source
else
printer.print_book source
end
rescue ReVIEW::Error, Errno::ENOENT => err
raise if $DEBUG
error_exit err.message
Expand Down
60 changes: 9 additions & 51 deletions lib/review/tocparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ def TOCParser.parse(chap)
end
end

def TOCParser.chapter_node(chap)
toc = TOCParser.parse(chap)
unless toc.size == 1
$stderr.puts "warning: chapter #{toc.join} contains more than 1 chapter"
end
toc.first
end

def parse(f, chap)
roots = [] ## list of chapters
node_stack = []
Expand Down Expand Up @@ -285,55 +293,5 @@ def yield_section
end

end


module TOCRoot
def level
0
end

def chapter?
false
end

def each_section_with_index
idx = -1
each_section do |node|
yield node, (idx += 1)
end
end

def each_section(&block)
each_chapter do |chap|
yield chap.toc
end
end

def section_size
chapters.size
end

def estimated_lines
chapters.inject(0) {|sum, chap| sum + chap.toc.estimated_lines }
end
end

class Book::Base # reopen
include TOCRoot
end

class Book::Part
include TOCRoot
end

class Book::Chapter # reopen
def toc
@toc ||= TOCParser.parse(self)
unless @toc.size == 1
$stderr.puts "warning: chapter #{@toc.join} contains more than 1 chapter"
end
@toc.first
end
end

end

140 changes: 50 additions & 90 deletions lib/review/tocprinter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
# For details of LGPL, see the file "COPYING".
#

require 'review/htmlutils'
require 'review/htmllayout'
require 'review'

module ReVIEW

Expand All @@ -27,16 +26,31 @@ def initialize(print_upper, param)
@config = param
end

def print_book(book)
book.each_part do |part|
print_part(part)
end
end

def print_part(part)
part.each_chapter do |chap|
print_chapter(chap)
end
end

def print_chapter(chap)
chap_node = TOCParser.chapter_node(chap)
print_node 1, chap_node
print_children chap_node
end

def print?(level)
level <= @print_upper
end
end


class TextTOCPrinter < TOCPrinter
def print_book(book)
print_children book
end

private

Expand Down Expand Up @@ -82,36 +96,34 @@ class HTMLTOCPrinter < TOCPrinter
include HTMLUtils

def print_book(book)
return unless print?(1)
html = ""
puts '<ul class="book-toc">'
book.each_part do |part|
html << h1(part.name) if part.name
part.each_section do |chap|
if chap.number
name = "chap#{chap.number}"
label = "第#{chap.number}#{chap.label}"
html << h2(a_name(escape_html(name), escape_html(label)))
else
label = "#{chap.label}"
html << h2(escape_html(label))
end
return unless print?(2)
if print?(3)
html << chap_sections_to_s(chap)
else
html << chapter_to_s(chap)
end
end
print_part(part)
end
layout_file = File.join(book.basedir, "layouts", "layout.html.erb")
unless File.exist?(layout_file) # backward compatibility
layout_file = File.join(book.basedir, "layouts", "layout.erb")
puts '</ul>'
end

def print_part(part)
puts li(part.name) if part.name
super
end

def print_chapter(chap)
chap_node = TOCParser.chapter_node(chap)
ext = chap.book.config["htmlext"] || ".html"
path = chap.path.sub(/\.re/, ext)
if chap_node.number
name = "chap#{chap_node.number}"
label = "#{chap.number} #{chap.title}"
else
label = chap.title
end
if File.exist?(layout_file)
puts HTMLLayout.new(
{'body' => html, 'title' => "目次"}, layout_file).result
puts li(a_name(path, escape_html(label)))
return unless print?(2)
if print?(3)
puts chap_sections_to_s(chap_node)
else
puts html
puts chapter_to_s(chap_node)
end
end

Expand All @@ -130,30 +142,19 @@ def chap_sections_to_s(chap)
def chapter_to_s(chap)
res = []
chap.each_section do |sec|
res << h3(escape_html(sec.label))
res << li(escape_html(sec.label))
next unless print?(4)
next if sec.section_size == 0
res << "<ul>"
sec.each_section do |node|
res << li(escape_html(node.label))
if sec.section_size > 0
res << "<ul>"
sec.each_section do |node|
res << li(escape_html(node.label))
end
res << "</ul>"
end
res << "</ul>"
end
return res.join("\n")
end

def h1(label)
"<h1>#{label}</h1>"
end

def h2(label)
"<h2>#{label}</h2>"
end

def h3(label)
"<h3>#{label}</h3>"
end

def li(content)
"<li>#{content}</li>"
end
Expand All @@ -164,45 +165,4 @@ def a_name(name, label)

end

class IDGTOCPrinter < TOCPrinter
def print_book(book)
puts %Q(<?xml version="1.0" encoding="UTF-8"?>)
puts %Q(<doc xmlns:aid='http://ns.adobe.com/AdobeInDesign/4.0/'><title aid:pstyle="h0">1 パート1</title><?dtp level="0" section="第1部 パート1"?>) # FIXME: 部タイトルを取るには? & 部ごとに結果を分けるには?
puts %Q(<ul aid:pstyle='ul-partblock'>)
print_children book
puts %Q(</ul></doc>)
end

private

def print_children(node)
return unless print?(node.level + 1)
node.each_section_with_index do |sec, idx|
print_node idx+1, sec
print_children sec
end
end

LABEL_LEN = 54

def print_node(seq, node)
if node.chapter?
printf "<li aid:pstyle='ul-part'>%s</li>\n",
"#{chapnumstr(node.number)}#{node.label}"
else
printf "<li>%-#{LABEL_LEN}s\n",
" #{' ' * (node.level - 1)}#{seq} #{node.label}</li>"
end
end

def chapnumstr(n)
n ? sprintf('第%d章 ', n) : ''
end

def volume_columns(level, volstr)
cols = ["", "", "", nil]
cols[level - 1] = volstr
cols[0, 3]
end
end
end

0 comments on commit aa968cd

Please sign in to comment.