review-peg 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/.rubocop.yml +47 -0
- data/.rubocop_todo.yml +605 -0
- data/.travis.yml +18 -0
- data/COPYING +515 -0
- data/ChangeLog +2449 -0
- data/Dockerfile +22 -0
- data/Gemfile +6 -0
- data/README.rdoc +81 -0
- data/Rakefile +51 -0
- data/bin/review-catalog-converter-peg +129 -0
- data/bin/review-check-peg +169 -0
- data/bin/review-checkdep-peg +63 -0
- data/bin/review-compile-peg +202 -0
- data/bin/review-epubmaker-legacy-peg +1024 -0
- data/bin/review-epubmaker-peg +44 -0
- data/bin/review-index-peg +110 -0
- data/bin/review-init-peg +151 -0
- data/bin/review-pdfmaker-peg +18 -0
- data/bin/review-preproc-peg +131 -0
- data/bin/review-validate-peg +51 -0
- data/bin/review-vol-peg +100 -0
- data/debian/README.Debian +12 -0
- data/debian/README.source +5 -0
- data/debian/changelog +5 -0
- data/debian/compat +1 -0
- data/debian/control +22 -0
- data/debian/copyright +62 -0
- data/debian/docs +6 -0
- data/debian/manpage.1.ex +59 -0
- data/debian/patches/path.diff +91 -0
- data/debian/patches/series +1 -0
- data/debian/review.install +13 -0
- data/debian/review.links +4 -0
- data/debian/rules +13 -0
- data/debian/source/format +1 -0
- data/doc/NEWS.ja.md +350 -0
- data/doc/NEWS.md +354 -0
- data/doc/catalog.ja.md +53 -0
- data/doc/catalog.md +52 -0
- data/doc/format.ja.md +734 -0
- data/doc/format.md +746 -0
- data/doc/format_idg.ja.md +203 -0
- data/doc/quickstart.ja.md +222 -0
- data/doc/quickstart.md +252 -0
- data/doc/ruby-uuid/README +11 -0
- data/doc/ruby-uuid/README.ja +34 -0
- data/doc/sample.css +108 -0
- data/doc/sample.yml +238 -0
- data/lib/epubmaker.rb +24 -0
- data/lib/epubmaker/content.rb +93 -0
- data/lib/epubmaker/epubcommon.rb +424 -0
- data/lib/epubmaker/epubv2.rb +139 -0
- data/lib/epubmaker/epubv3.rb +222 -0
- data/lib/epubmaker/producer.rb +330 -0
- data/lib/lineinput.rb +107 -0
- data/lib/review.rb +3 -0
- data/lib/review/book.rb +43 -0
- data/lib/review/book/base.rb +401 -0
- data/lib/review/book/chapter.rb +100 -0
- data/lib/review/book/compilable.rb +184 -0
- data/lib/review/book/image_finder.rb +71 -0
- data/lib/review/book/index.rb +413 -0
- data/lib/review/book/page_metric.rb +47 -0
- data/lib/review/book/part.rb +54 -0
- data/lib/review/book/volume.rb +67 -0
- data/lib/review/builder.rb +452 -0
- data/lib/review/catalog.rb +52 -0
- data/lib/review/compiler.rb +5183 -0
- data/lib/review/compiler/literals_1_9.kpeg +22 -0
- data/lib/review/compiler/literals_1_9.rb +435 -0
- data/lib/review/configure.rb +64 -0
- data/lib/review/epubbuilder.rb +18 -0
- data/lib/review/epubmaker.rb +480 -0
- data/lib/review/ewbbuilder.rb +381 -0
- data/lib/review/exception.rb +21 -0
- data/lib/review/extentions.rb +4 -0
- data/lib/review/extentions/array.rb +25 -0
- data/lib/review/extentions/object.rb +9 -0
- data/lib/review/extentions/string.rb +33 -0
- data/lib/review/htmlbuilder.rb +1166 -0
- data/lib/review/htmllayout.rb +41 -0
- data/lib/review/htmltoc.rb +45 -0
- data/lib/review/htmlutils.rb +90 -0
- data/lib/review/i18n.rb +96 -0
- data/lib/review/i18n.yml +169 -0
- data/lib/review/idgxmlbuilder.rb +1233 -0
- data/lib/review/inaobuilder.rb +357 -0
- data/lib/review/latexbuilder.rb +941 -0
- data/lib/review/latexindex.rb +35 -0
- data/lib/review/latexutils.rb +95 -0
- data/lib/review/layout.tex.erb +340 -0
- data/lib/review/lineinput.rb +17 -0
- data/lib/review/location.rb +24 -0
- data/lib/review/makerhelper.rb +67 -0
- data/lib/review/markdownbuilder.rb +339 -0
- data/lib/review/node.rb +288 -0
- data/lib/review/pdfmaker.rb +332 -0
- data/lib/review/preprocessor.rb +530 -0
- data/lib/review/review.kpeg +745 -0
- data/lib/review/sec_counter.rb +69 -0
- data/lib/review/template.rb +21 -0
- data/lib/review/textbuilder.rb +17 -0
- data/lib/review/textutils.rb +16 -0
- data/lib/review/tocparser.rb +348 -0
- data/lib/review/tocprinter.rb +205 -0
- data/lib/review/topbuilder.rb +796 -0
- data/lib/review/unfold.rb +138 -0
- data/lib/review/version.rb +3 -0
- data/lib/uuid.rb +312 -0
- data/review.gemspec +32 -0
- data/templates/html/layout-html5.html.erb +17 -0
- data/templates/html/layout-xhtml1.html.erb +20 -0
- data/templates/ncx/epubv2.ncx.erb +11 -0
- data/templates/opf/epubv2.opf.erb +21 -0
- data/templates/opf/epubv3.opf.erb +18 -0
- data/templates/xml/container.xml.erb +6 -0
- data/test/CHAPS +2 -0
- data/test/assets/test.xml.erb +3 -0
- data/test/assets/test_template.tex +255 -0
- data/test/assets/test_template_backmatter.tex +32 -0
- data/test/bib.re +13 -0
- data/test/book_test_helper.rb +35 -0
- data/test/sample-book/README.md +7 -0
- data/test/sample-book/src/Rakefile +58 -0
- data/test/sample-book/src/_cover.html +3 -0
- data/test/sample-book/src/catalog.yml +10 -0
- data/test/sample-book/src/ch01.re +71 -0
- data/test/sample-book/src/ch02.re +3 -0
- data/test/sample-book/src/config.yml +186 -0
- data/test/sample-book/src/images/ch01-imgsample.jpg +0 -0
- data/test/sample-book/src/images/cover.jpg +0 -0
- data/test/sample-book/src/preface.re +15 -0
- data/test/sample-book/src/sty/jumoline.sty +310 -0
- data/test/sample-book/src/sty/reviewmacro.sty +39 -0
- data/test/sample-book/src/style.css +251 -0
- data/test/sample-book/src/vendor/jumoline/README +29 -0
- data/test/sample-book/src/vendor/jumoline/jumoline.dtx +2988 -0
- data/test/sample-book/src/vendor/jumoline/jumoline.ins +6 -0
- data/test/test.re +43 -0
- data/test/test_book.rb +556 -0
- data/test/test_book_chapter.rb +280 -0
- data/test/test_book_part.rb +54 -0
- data/test/test_builder.rb +80 -0
- data/test/test_catalog.rb +119 -0
- data/test/test_catalog_converter_cmd.rb +73 -0
- data/test/test_compiler.rb +92 -0
- data/test/test_configure.rb +50 -0
- data/test/test_epub3maker.rb +529 -0
- data/test/test_epubmaker.rb +569 -0
- data/test/test_epubmaker_cmd.rb +40 -0
- data/test/test_helper.rb +92 -0
- data/test/test_htmlbuilder.rb +1114 -0
- data/test/test_htmltoc.rb +32 -0
- data/test/test_htmlutils.rb +50 -0
- data/test/test_i18n.rb +180 -0
- data/test/test_idgxmlbuilder.rb +608 -0
- data/test/test_image_finder.rb +82 -0
- data/test/test_inaobuilder.rb +245 -0
- data/test/test_index.rb +174 -0
- data/test/test_latexbuilder.rb +732 -0
- data/test/test_lineinput.rb +182 -0
- data/test/test_makerhelper.rb +66 -0
- data/test/test_markdownbuilder.rb +125 -0
- data/test/test_pdfmaker.rb +171 -0
- data/test/test_pdfmaker_cmd.rb +40 -0
- data/test/test_preprocessor.rb +23 -0
- data/test/test_review_ext.rb +31 -0
- data/test/test_template.rb +26 -0
- data/test/test_textutils.rb +32 -0
- data/test/test_topbuilder.rb +291 -0
- data/test/test_uuid.rb +157 -0
- metadata +357 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2008-2014 Minero Aoki, Kenshi Muto, Masayoshi Takahashi,
|
|
4
|
+
# KADO Masanori
|
|
5
|
+
#
|
|
6
|
+
# This program is free software.
|
|
7
|
+
# You can distribute or modify this program under the terms of
|
|
8
|
+
# the GNU LGPL, Lesser General Public License version 2.1.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
module ReVIEW
|
|
12
|
+
|
|
13
|
+
# Secion Counter class
|
|
14
|
+
#
|
|
15
|
+
class SecCounter
|
|
16
|
+
def initialize(n, chapter)
|
|
17
|
+
@chapter = chapter
|
|
18
|
+
reset(n)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def reset(n)
|
|
22
|
+
@counter = Array.new(n, 0)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def inc(level)
|
|
26
|
+
n = level - 2
|
|
27
|
+
if n >= 0
|
|
28
|
+
@counter[n] += 1
|
|
29
|
+
end
|
|
30
|
+
if @counter.size > n
|
|
31
|
+
(n+1 .. @counter.size).each do |i|
|
|
32
|
+
@counter[i] = 0
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def anchor(level)
|
|
38
|
+
str = "#{@chapter.format_number(false)}"
|
|
39
|
+
0.upto(level-2) do |i|
|
|
40
|
+
str << "-#{@counter[i]}"
|
|
41
|
+
end
|
|
42
|
+
str
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def prefix(level, secnolevel)
|
|
46
|
+
return nil if @chapter.number.blank?
|
|
47
|
+
|
|
48
|
+
if level == 1
|
|
49
|
+
if secnolevel >= 1
|
|
50
|
+
if @chapter.is_a? ReVIEW::Book::Part
|
|
51
|
+
num = @chapter.number
|
|
52
|
+
return "#{I18n.t('part', num)}#{I18n.t("chapter_postfix")}"
|
|
53
|
+
else
|
|
54
|
+
return "#{@chapter.format_number}#{I18n.t("chapter_postfix")}"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
if secnolevel >= level
|
|
59
|
+
prefix = @chapter.format_number(false)
|
|
60
|
+
0.upto(level - 2) do |i|
|
|
61
|
+
prefix << ".#{@counter[i]}"
|
|
62
|
+
end
|
|
63
|
+
prefix << I18n.t("chapter_postfix")
|
|
64
|
+
return prefix
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
module ReVIEW
|
|
3
|
+
class Template
|
|
4
|
+
TEMPLATE_DIR = File.join(File.dirname(__FILE__), "../../templates")
|
|
5
|
+
|
|
6
|
+
def self.load(filename, mode = 1)
|
|
7
|
+
self.new(filename, mode)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def initialize(filename = nil, mode = nil)
|
|
11
|
+
if filename
|
|
12
|
+
content = File.read(filename)
|
|
13
|
+
@erb = ERB.new(content, nil, mode)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def result(bind_data = nil)
|
|
18
|
+
@erb.result(bind_data)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# textbuilder.rb
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2010 Kenshi Muto
|
|
4
|
+
#
|
|
5
|
+
# This program is free software.
|
|
6
|
+
# You can distribute or modify this program under the terms of
|
|
7
|
+
# the GNU LGPL, Lesser General Public License version 2.1.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
require 'review/topbuilder'
|
|
11
|
+
|
|
12
|
+
module ReVIEW
|
|
13
|
+
|
|
14
|
+
class TEXTBuilder < TOPBuilder
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end # module ReVIEW
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# $Id: textutils.rb 2192 2005-11-13 11:55:42Z aamine $
|
|
2
|
+
require 'nkf'
|
|
3
|
+
|
|
4
|
+
module ReVIEW
|
|
5
|
+
module TextUtils
|
|
6
|
+
def detab(str, ts = 8)
|
|
7
|
+
add = 0
|
|
8
|
+
len = nil
|
|
9
|
+
str.gsub(/\t/) {
|
|
10
|
+
len = ts - ($`.size + add) % ts
|
|
11
|
+
add += len - 1
|
|
12
|
+
' ' * len
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
#
|
|
2
|
+
# $Id: tocparser.rb 4268 2009-05-27 04:17:08Z kmuto $
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2002-2007 Minero Aoki
|
|
5
|
+
# 2008-2009 Minero Aoki, Kenshi Muto
|
|
6
|
+
#
|
|
7
|
+
# This program is free software.
|
|
8
|
+
# You can distribute or modify this program under the terms of
|
|
9
|
+
# the GNU LGPL, Lesser General Public License version 2.1.
|
|
10
|
+
# For details of the GNU LGPL, see the file "COPYING".
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
require 'review/preprocessor'
|
|
14
|
+
require 'review/book'
|
|
15
|
+
require 'review/textbuilder'
|
|
16
|
+
|
|
17
|
+
module ReVIEW
|
|
18
|
+
|
|
19
|
+
class TOCParser
|
|
20
|
+
def TOCParser.parse(chap)
|
|
21
|
+
chap.open {|f|
|
|
22
|
+
stream = Preprocessor::Strip.new(f)
|
|
23
|
+
new.parse(stream, chap.id, chap.path, chap).map {|root|
|
|
24
|
+
root.number = chap.number
|
|
25
|
+
root
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def parse(f, id, filename, chap)
|
|
31
|
+
roots = []
|
|
32
|
+
path = []
|
|
33
|
+
|
|
34
|
+
while line = f.gets
|
|
35
|
+
line.sub!(/\A\xEF\xBB\xBF/u, '') # remove BOM
|
|
36
|
+
case line
|
|
37
|
+
when /\A\#@/
|
|
38
|
+
;
|
|
39
|
+
when /\A\s*\z/
|
|
40
|
+
;
|
|
41
|
+
when /\A(={2,})[\[\s\{]/
|
|
42
|
+
lev = $1.size
|
|
43
|
+
error! filename, f.lineno, "section level too deep: #{lev}" if lev > 5
|
|
44
|
+
if path.empty?
|
|
45
|
+
# missing chapter label
|
|
46
|
+
path.push Chapter.new(get_label(line), id, filename, chap.book.page_metric)
|
|
47
|
+
roots.push path.first
|
|
48
|
+
end
|
|
49
|
+
next if get_label(line) =~ /\A\[\// # ex) "[/column]"
|
|
50
|
+
new = Section.new(lev, get_label(line).gsub(/\A\{.*?\}\s?/, ""))
|
|
51
|
+
until path.last.level < new.level
|
|
52
|
+
path.pop
|
|
53
|
+
end
|
|
54
|
+
path.last.add_child new
|
|
55
|
+
path.push new
|
|
56
|
+
|
|
57
|
+
when /\A= /
|
|
58
|
+
path.clear
|
|
59
|
+
path.push Chapter.new(get_label(line), id, filename, chap.book.page_metric)
|
|
60
|
+
roots.push path.first
|
|
61
|
+
|
|
62
|
+
when %r<\A//\w+(?:\[.*?\])*\{\s*\z>
|
|
63
|
+
if path.empty?
|
|
64
|
+
error! filename, f.lineno, 'list found before section label'
|
|
65
|
+
end
|
|
66
|
+
path.last.add_child(list = List.new)
|
|
67
|
+
beg = f.lineno
|
|
68
|
+
list.add line
|
|
69
|
+
while line = f.gets
|
|
70
|
+
break if %r<\A//\}> =~ line
|
|
71
|
+
list.add line
|
|
72
|
+
end
|
|
73
|
+
error! filename, beg, 'unterminated list' unless line
|
|
74
|
+
|
|
75
|
+
when %r<\A//\w>
|
|
76
|
+
;
|
|
77
|
+
else
|
|
78
|
+
#if path.empty?
|
|
79
|
+
# error! filename, f.lineno, 'text found before section label'
|
|
80
|
+
#end
|
|
81
|
+
next if path.empty?
|
|
82
|
+
path.last.add_child(par = Paragraph.new(chap.book.page_metric))
|
|
83
|
+
par.add line
|
|
84
|
+
while line = f.gets
|
|
85
|
+
break if /\A\s*\z/ =~ line
|
|
86
|
+
par.add line
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
roots
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def get_label(line)
|
|
95
|
+
line = line.strip.sub(/\A=+\s*/, '')
|
|
96
|
+
compile_label(line)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def compile_label(line)
|
|
100
|
+
b = ReVIEW::TEXTBuilder.new
|
|
101
|
+
dummy_book = ReVIEW::Book::Base.load
|
|
102
|
+
dummy_chapter = ReVIEW::Book::Chapter.new(dummy_book, 1, '-', nil, StringIO.new)
|
|
103
|
+
dummy_loc = Location.new("", StringIO.new)
|
|
104
|
+
b.bind(ReVIEW::Compiler.new(b), dummy_chapter, dummy_loc)
|
|
105
|
+
b.compile_inline(line)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def error!(filename, lineno, msg)
|
|
109
|
+
raise "#{filename}:#{lineno}: #{msg}"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class Node
|
|
114
|
+
|
|
115
|
+
def initialize(children = [])
|
|
116
|
+
@children = children
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
attr_reader :children
|
|
120
|
+
|
|
121
|
+
def add_child(c)
|
|
122
|
+
@children.push c
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def each_node(&block)
|
|
126
|
+
@children.each do |c|
|
|
127
|
+
yield c
|
|
128
|
+
c.each(&block)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def each_child(&block)
|
|
133
|
+
@children.each(&block)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def chapter?
|
|
137
|
+
false
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def each_section(&block)
|
|
141
|
+
@children.each do |n|
|
|
142
|
+
n.yield_section(&block)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def each_section_with_index
|
|
147
|
+
i = 0
|
|
148
|
+
each_section do |n|
|
|
149
|
+
yield n, i
|
|
150
|
+
i += 1
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def n_sections
|
|
155
|
+
cnt = 0
|
|
156
|
+
@children.each do |n|
|
|
157
|
+
n.yield_section { cnt += 1 }
|
|
158
|
+
end
|
|
159
|
+
cnt
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class Section < Node
|
|
166
|
+
|
|
167
|
+
def initialize(level, label, path = nil)
|
|
168
|
+
super()
|
|
169
|
+
@level = level
|
|
170
|
+
@label = label
|
|
171
|
+
@filename = (path ? real_filename(path) : nil)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def real_filename(path)
|
|
175
|
+
if FileTest.symlink?(path)
|
|
176
|
+
File.basename(File.readlink(path))
|
|
177
|
+
else
|
|
178
|
+
File.basename(path)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
private :real_filename
|
|
182
|
+
|
|
183
|
+
attr_reader :level
|
|
184
|
+
attr_reader :label
|
|
185
|
+
|
|
186
|
+
def display_label
|
|
187
|
+
if @filename
|
|
188
|
+
@label + ' ' + @filename
|
|
189
|
+
else
|
|
190
|
+
@label
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def estimated_lines
|
|
195
|
+
@children.inject(0) {|sum, n| sum + n.estimated_lines }
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def yield_section
|
|
199
|
+
yield self
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def inspect
|
|
203
|
+
"\#<#{self.class} level=#{@level} #{@label}>"
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class Chapter < Section
|
|
210
|
+
|
|
211
|
+
def initialize(label, id, path, page_metric)
|
|
212
|
+
super 1, label, path
|
|
213
|
+
@chapter_id = id
|
|
214
|
+
@path = path
|
|
215
|
+
@page_metric = page_metric
|
|
216
|
+
@volume = nil
|
|
217
|
+
@number = nil
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
attr_accessor :number
|
|
221
|
+
|
|
222
|
+
def chapter?
|
|
223
|
+
true
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
attr_reader :chapter_id
|
|
227
|
+
|
|
228
|
+
def volume
|
|
229
|
+
return @volume if @volume
|
|
230
|
+
return Book::Volume.dummy unless @path
|
|
231
|
+
@volume = Book::Volume.count_file(@path)
|
|
232
|
+
@volume.page_per_kbyte = @page_metric.page_per_kbyte
|
|
233
|
+
@volume.lines = estimated_lines()
|
|
234
|
+
@volume
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def inspect
|
|
238
|
+
"\#<#{self.class} #{@filename}>"
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class Paragraph < Node
|
|
245
|
+
|
|
246
|
+
def initialize(page_metric)
|
|
247
|
+
@bytes = 0
|
|
248
|
+
@page_metric = page_metric
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def inspect
|
|
252
|
+
"\#<#{self.class}>"
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def add(line)
|
|
256
|
+
@bytes += line.strip.bytesize
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def estimated_lines
|
|
260
|
+
(@bytes + 2) / @page_metric.text.n_columns + 1
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def yield_section
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class List < Node
|
|
270
|
+
|
|
271
|
+
def initialize
|
|
272
|
+
@lines = 0
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def inspect
|
|
276
|
+
"\#<#{self.class}>"
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def add(line)
|
|
280
|
+
@lines += 1
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def estimated_lines
|
|
284
|
+
@lines + 2
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def yield_section
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
module TOCRoot
|
|
296
|
+
def level
|
|
297
|
+
0
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def chapter?
|
|
301
|
+
false
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def each_section_with_index
|
|
305
|
+
idx = -1
|
|
306
|
+
each_section do |node|
|
|
307
|
+
yield node, (idx += 1)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def each_section(&block)
|
|
312
|
+
each_chapter do |chap|
|
|
313
|
+
yield chap.toc
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def n_sections
|
|
318
|
+
chapters.size
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def estimated_lines
|
|
322
|
+
chapters.inject(0) {|sum, chap| sum + chap.toc.estimated_lines }
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
class Book::Base # reopen
|
|
327
|
+
include TOCRoot
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
class Book::ChapterSet # reopen
|
|
331
|
+
include TOCRoot
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
class Book::Part
|
|
335
|
+
include TOCRoot
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
class Book::Chapter # reopen
|
|
339
|
+
def toc
|
|
340
|
+
@toc ||= TOCParser.parse(self)
|
|
341
|
+
unless @toc.size == 1
|
|
342
|
+
$stderr.puts "warning: chapter #{@toc.join} contains more than 1 chapter"
|
|
343
|
+
end
|
|
344
|
+
@toc.first
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
end
|