tmtms-review 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +9 -0
  3. data/COPYING +515 -0
  4. data/ChangeLog +2083 -0
  5. data/README.rdoc +50 -0
  6. data/Rakefile +56 -0
  7. data/VERSION +1 -0
  8. data/bin/review-check +178 -0
  9. data/bin/review-checkdep +63 -0
  10. data/bin/review-compile +205 -0
  11. data/bin/review-epubmaker +661 -0
  12. data/bin/review-epubmaker-ng +176 -0
  13. data/bin/review-index +118 -0
  14. data/bin/review-pdfmaker +208 -0
  15. data/bin/review-preproc +142 -0
  16. data/bin/review-validate +51 -0
  17. data/bin/review-vol +102 -0
  18. data/debian/README.Debian +12 -0
  19. data/debian/README.source +5 -0
  20. data/debian/changelog +5 -0
  21. data/debian/compat +1 -0
  22. data/debian/control +22 -0
  23. data/debian/copyright +62 -0
  24. data/debian/docs +6 -0
  25. data/debian/manpage.1.ex +59 -0
  26. data/debian/patches/path.diff +91 -0
  27. data/debian/patches/series +1 -0
  28. data/debian/review.install +13 -0
  29. data/debian/review.links +4 -0
  30. data/debian/rules +13 -0
  31. data/debian/source/format +1 -0
  32. data/doc/format.rdoc +582 -0
  33. data/doc/format_idg.rdoc +180 -0
  34. data/doc/libepubmaker/sample.yaml +90 -0
  35. data/doc/quickstart.rdoc +188 -0
  36. data/doc/ruby-uuid/README +11 -0
  37. data/doc/ruby-uuid/README.ja +34 -0
  38. data/doc/sample.css +108 -0
  39. data/doc/sample.yaml +62 -0
  40. data/lib/epubmaker.rb +28 -0
  41. data/lib/epubmaker/content.rb +82 -0
  42. data/lib/epubmaker/epubv2.rb +418 -0
  43. data/lib/epubmaker/epubv3.rb +249 -0
  44. data/lib/epubmaker/producer.rb +204 -0
  45. data/lib/epubmaker/resource.rb +66 -0
  46. data/lib/lineinput.rb +155 -0
  47. data/lib/review.rb +3 -0
  48. data/lib/review/book.rb +46 -0
  49. data/lib/review/book/base.rb +235 -0
  50. data/lib/review/book/chapter.rb +81 -0
  51. data/lib/review/book/compilable.rb +159 -0
  52. data/lib/review/book/index.rb +339 -0
  53. data/lib/review/book/page_metric.rb +38 -0
  54. data/lib/review/book/parameters.rb +97 -0
  55. data/lib/review/book/part.rb +44 -0
  56. data/lib/review/book/volume.rb +65 -0
  57. data/lib/review/builder.rb +444 -0
  58. data/lib/review/compiler.rb +550 -0
  59. data/lib/review/configure.rb +38 -0
  60. data/lib/review/epubbuilder.rb +18 -0
  61. data/lib/review/exception.rb +21 -0
  62. data/lib/review/extentions.rb +3 -0
  63. data/lib/review/extentions/object.rb +9 -0
  64. data/lib/review/extentions/string.rb +33 -0
  65. data/lib/review/htmlbuilder.rb +1097 -0
  66. data/lib/review/htmllayout.rb +19 -0
  67. data/lib/review/htmlutils.rb +36 -0
  68. data/lib/review/i18n.rb +30 -0
  69. data/lib/review/i18n.yaml +34 -0
  70. data/lib/review/idgxmlbuilder.rb +1145 -0
  71. data/lib/review/latexbuilder.rb +815 -0
  72. data/lib/review/latexindex.rb +35 -0
  73. data/lib/review/latexutils.rb +79 -0
  74. data/lib/review/preprocessor.rb +563 -0
  75. data/lib/review/review.tex.erb +232 -0
  76. data/lib/review/textbuilder.rb +17 -0
  77. data/lib/review/textutils.rb +66 -0
  78. data/lib/review/tocparser.rb +342 -0
  79. data/lib/review/tocprinter.rb +221 -0
  80. data/lib/review/topbuilder.rb +785 -0
  81. data/lib/review/unfold.rb +138 -0
  82. data/lib/uuid.rb +312 -0
  83. data/review.gemspec +141 -0
  84. data/test/CHAPS +2 -0
  85. data/test/bib.re +13 -0
  86. data/test/book_test_helper.rb +35 -0
  87. data/test/test.re +43 -0
  88. data/test/test_book.rb +598 -0
  89. data/test/test_book_chapter.rb +418 -0
  90. data/test/test_book_parameter.rb +42 -0
  91. data/test/test_book_part.rb +50 -0
  92. data/test/test_builder.rb +144 -0
  93. data/test/test_compiler.rb +44 -0
  94. data/test/test_epubmaker.rb +507 -0
  95. data/test/test_helper.rb +27 -0
  96. data/test/test_htmlbuilder.rb +554 -0
  97. data/test/test_htmlutils.rb +28 -0
  98. data/test/test_i18n.rb +64 -0
  99. data/test/test_idgxmlbuilder.rb +589 -0
  100. data/test/test_index.rb +31 -0
  101. data/test/test_latexbuilder.rb +656 -0
  102. data/test/test_lineinput.rb +198 -0
  103. data/test/test_preprocessor.rb +23 -0
  104. data/test/test_textutils.rb +68 -0
  105. data/test/test_topbuilder.rb +244 -0
  106. data/test/test_uuid.rb +156 -0
  107. metadata +161 -0
@@ -0,0 +1,232 @@
1
+ \documentclass[<%= documentclassoption %>]{<%= documentclass %>}
2
+ \usepackage[deluxe]{otf}
3
+ \usepackage[dvipdfmx]{color}
4
+ \usepackage[dvipdfmx]{graphicx}
5
+ \usepackage{framed}
6
+ \usepackage{wrapfig}
7
+ \definecolor{shadecolor}{gray}{0.9}
8
+ \definecolor{shadecolorb}{gray}{0.1}
9
+ \usepackage[utf8]{inputenc}
10
+ \usepackage{ascmac}
11
+ \usepackage{float}
12
+ \usepackage{alltt}
13
+ \usepackage{amsmath}
14
+
15
+ %% if you use @<u>{} (underline), use jumoline.sty
16
+ %%\usepackage{jumoline}
17
+
18
+ \newenvironment{shadedb}{%
19
+ \def\FrameCommand{\fboxsep=\FrameSep \colorbox{shadecolorb}}%
20
+ \MakeFramed {\FrameRestore}}%
21
+ {\endMakeFramed}
22
+
23
+ \usepackage[top=10zw,bottom=12zw,left=10zw,right=10zw]{geometry}
24
+ %\usepackage[top=5zw,bottom=5zw,left=1zw,right=1zw]{geometry}
25
+
26
+
27
+ \newcommand{\parasep}{\vspace*{3zh}}
28
+ \setlength{\footskip}{30pt}
29
+
30
+ %% Bookmarkの文字化け対策(日本語向け)
31
+ \ifnum 46273=\euc"B4C1 % 46273 == 0xB4C1 == 漢(EUC-JP)
32
+ \usepackage{atbegshi}%
33
+ \AtBeginShipoutFirst{\special{pdf:tounicode EUC-UCS2}}%
34
+ %%\AtBeginDvi{\special{pdf:tounicode EUC-UCS2}}%
35
+ \else
36
+ \usepackage{atbegshi}%
37
+ \AtBeginShipoutFirst{\special{pdf:tounicode 90ms-RKSJ-UCS2}}%
38
+ %%\AtBeginDvi{\special{pdf:tounicode 90ms-RKSJ-UCS2}}%
39
+ \fi
40
+
41
+ \usepackage[dvipdfm,bookmarks=true,bookmarksnumbered=true,colorlinks=true,%
42
+ pdftitle={<%= values["booktitle"] %>},%
43
+ pdfauthor={<%= values["aut"] %>}]{hyperref}
44
+
45
+ \newenvironment{reviewimage}{%
46
+ \begin{figure}[H]
47
+ \begin{center}}{%
48
+ \end{center}
49
+ \end{figure}}
50
+
51
+ \newenvironment{reviewdummyimage}{%
52
+ \begin{figure}[H]
53
+ \begin{center}}{%
54
+ \end{center}
55
+ \end{figure}}
56
+
57
+ \newenvironment{reviewemlist}{%
58
+ \medskip\small\begin{shaded}\setlength{\baselineskip}{1.3zw}}{%
59
+ \end{shaded}}
60
+
61
+ \newenvironment{reviewlist}{%
62
+ \begin{shaded}\small\setlength{\baselineskip}{1.3zw}}{%
63
+ \end{shaded}\par\vspace*{0.5zw}}
64
+
65
+ \newenvironment{reviewcmd}{%
66
+ \color{white}\medskip\small\begin{shadedb}\setlength{\baselineskip}{1.3zw}}{%
67
+ \end{shadedb}}
68
+
69
+ \newenvironment{reviewtable}[1]{%
70
+ \begin{center}\small\setlength{\baselineskip}{1.2zw}
71
+ \begin{tabular}{#1}}{%
72
+ \end{tabular}
73
+ \end{center}}
74
+
75
+ \newenvironment{reviewcolumn}{%
76
+ \begin{framed}
77
+ }{%
78
+ \end{framed}
79
+ \vspace{2zw}}
80
+
81
+ \newcommand{\reviewcolumnhead}[2]{%
82
+ {\noindent\large ■コラム: #2}}
83
+
84
+ \newcommand{\reviewtablecaption}[1]{%
85
+ \caption{#1}}
86
+
87
+ \newcommand{\reviewbackslash}[0]{%
88
+ \textbackslash{}}
89
+
90
+ \newcommand{\reviewlistcaption}[1]{%
91
+ \medskip{\small\noindent #1}\vspace*{-1.3zw}}
92
+
93
+ \newcommand{\reviewemlistcaption}[1]{%
94
+ \medskip{\small\noindent #1}\vspace*{-1.3zw}}
95
+
96
+ \newcommand{\reviewcmdcaption}[1]{%
97
+ \medskip{\small\noindent #1}\vspace*{-1.3zw}}
98
+
99
+ \newcommand{\reviewindepimagecaption}[1]{%
100
+ \begin{center}#1\end{center}}
101
+
102
+ \newcommand{\reviewimageref}[2]{%
103
+ 図 #1}
104
+ \newcommand{\reviewtableref}[2]{%
105
+ 表 #1}
106
+ \newcommand{\reviewlistref}[1]{%
107
+ リスト #1}
108
+
109
+ \newcommand{\reviewminicolumntitle}[1]{%
110
+ {\large ■メモ:#1}\\}
111
+
112
+ \newenvironment{reviewminicolumn}{%
113
+ \vspace{1.5zw}\begin{screen}}{%
114
+ \end{screen}\vspace{2zw}}
115
+
116
+ \newcommand{\reviewkw}[1]{%
117
+ \textbf{\textgt{#1}}}
118
+
119
+ \newcommand{\reviewami}[1]{%
120
+ \mask{#1}{A}}
121
+
122
+ \newcommand{\reviewem}[1]{%
123
+ \textbf{#1}}
124
+
125
+ \newcommand{\reviewstrong}[1]{%
126
+ \textbf{#1}}
127
+
128
+ \newcommand{\reviewth}[1]{%
129
+ \textgt{#1}}
130
+
131
+ \newcommand{\reviewtitlefont}[0]{%
132
+ \usefont{T1}{phv}{b}{n}\gtfamily}
133
+
134
+ \newcommand{\reviewmainfont}[0]{%
135
+ }
136
+
137
+ \newcommand{\reviewcolophon}[0]{%
138
+ \backmatter
139
+ \clearpage}
140
+ \newcommand{\reviewappendix}[0]{%
141
+ \appendix}
142
+
143
+ \makeatletter
144
+ \def\maxwidth{%
145
+ \ifdim\Gin@nat@width>\linewidth
146
+ \linewidth
147
+ \else
148
+ \Gin@nat@width
149
+ \fi
150
+ }
151
+ \makeatother
152
+
153
+ <%= values["usepackage"] %>
154
+
155
+ \usepackage[T1]{fontenc}
156
+
157
+ \begin{document}
158
+
159
+ \reviewmainfont
160
+
161
+ <% if values["titlepage"] %>
162
+ <% if custom_titlepage %>
163
+ <%= custom_titlepage %>
164
+ <% else %>
165
+ \begin{titlepage}
166
+ <% if values["coverimage"] %>
167
+ \begin{center}
168
+ %%%\mbox{}\vskip5zw%
169
+ \includegraphics[width=\textwidth,height=\textheight,keepaspectratio]{./images/<%= values["coverimage"] %>}
170
+ \end{center}
171
+ \clearpage
172
+ <% end %>
173
+ \thispagestyle{empty}
174
+ \begin{center}%
175
+ \mbox{} \vskip5zw
176
+ \reviewtitlefont%
177
+ {\Huge <%= values["booktitle"] %> \par}%
178
+ \vskip 15em%
179
+ {\huge
180
+ \lineskip .75em
181
+ \begin{tabular}[t]{c}%
182
+ <%= authors %>
183
+ \end{tabular}\par}%
184
+ \vfill
185
+ {\large <%= values["date"] %> 版\hspace{2zw}<%= values["prt"] %> 発行\par}%
186
+ \vskip4zw\mbox{}
187
+ \end{center}%
188
+ \end{titlepage}
189
+ <% end %>
190
+ <% end %>
191
+
192
+ \renewcommand{\chaptermark}[1]{{}}
193
+ \frontmatter
194
+
195
+ %% preface
196
+ <%= values["pre_str"] %>
197
+
198
+ <% if values["toc"] %>
199
+ \setcounter{tocdepth}{<%= values["toclevel"] %>}
200
+ \tableofcontents
201
+ <% end %>
202
+
203
+ \renewcommand{\chaptermark}[1]{\markboth{\prechaptername\thechapter\postchaptername~#1}{}}
204
+ \mainmatter
205
+ <%= values["chap_str"] %>
206
+ \renewcommand{\chaptermark}[1]{\markboth{\appendixname\thechapter~#1}{}}
207
+ \reviewappendix
208
+ <%= values["post_str"] %>
209
+
210
+ <% if values["colophon"] %>
211
+ %% okuduke
212
+ \reviewcolophon
213
+ \thispagestyle{empty}
214
+
215
+ \vspace*{\fill}
216
+
217
+ {\noindent\reviewtitlefont\Large <%= values["booktitle"] %>} \\
218
+ \rule[8pt]{14cm}{1pt} \\
219
+ {\noindent
220
+ <%= values["pubhistory"].to_s.gsub(/\n/){"\n\n\\noindent"} %>
221
+ }
222
+
223
+ \begin{tabular}{ll}
224
+ <%= okuduke %>
225
+ \end{tabular}
226
+  \\
227
+ \rule[0pt]{14cm}{1pt} \\
228
+ <%= values["rights"] %> \\
229
+ <% end %>
230
+
231
+
232
+ \end{document}
@@ -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,66 @@
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
+
16
+ def split_paragraph(lines)
17
+ pre = pre_paragraph
18
+ post = post_paragraph
19
+
20
+ blocked_lines = [[]]
21
+ lines.each {|element|
22
+ if element == ""
23
+ if blocked_lines.last != []
24
+ blocked_lines << []
25
+ end
26
+ else
27
+ blocked_lines.last << element
28
+ end
29
+ }
30
+
31
+ if !pre.nil? and !post.nil?
32
+ blocked_lines.map!{|i| [pre] + i + [post] }
33
+ end
34
+
35
+ blocked_lines.map{|l| l.join("")}
36
+ end
37
+
38
+ def convert_inencoding(str, enc)
39
+ case enc
40
+ when /^EUC$/i
41
+ NKF.nkf("-E -w -m0x", str)
42
+ when /^SJIS$/i
43
+ NKF.nkf("-S -w -m0x", str)
44
+ when /^JIS$/i
45
+ NKF.nkf("-J -w -m0x", str)
46
+ when /^UTF-8$/i
47
+ NKF.nkf("-W -w -m0x", str)
48
+ else
49
+ NKF.nkf("-w -m0 -m0x", str)
50
+ end
51
+ end
52
+
53
+ def convert_outencoding(str, enc)
54
+ case enc
55
+ when /^EUC$/i
56
+ NKF.nkf("-W -e -m0x", str)
57
+ when /^SJIS$/i
58
+ NKF.nkf("-W -s -m0x", str)
59
+ when /^JIS$/i
60
+ NKF.nkf("-W -j -m0x", str)
61
+ else
62
+ str
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,342 @@
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 'forwardable'
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).map {|root|
24
+ root.number = chap.number
25
+ root
26
+ }
27
+ }
28
+ end
29
+
30
+ def parse(f, id, filename)
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)
47
+ roots.push path.first
48
+ end
49
+ next if get_label(line) =~ /\A\[\// # ex) "[/column]"
50
+ new = Section.new(lev, get_label(line))
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)
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)
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 = TEXTBuilder.new
101
+ b.bind(ReVIEW::Compiler.new(b), nil, nil)
102
+ b.compile_inline(line)
103
+ end
104
+
105
+ def error!(filename, lineno, msg)
106
+ raise "#{filename}:#{lineno}: #{msg}"
107
+ end
108
+
109
+
110
+ class Node
111
+
112
+ def initialize(children = [])
113
+ @children = children
114
+ end
115
+
116
+ attr_reader :children
117
+
118
+ def add_child(c)
119
+ @children.push c
120
+ end
121
+
122
+ def each_node(&block)
123
+ @children.each do |c|
124
+ yield c
125
+ c.each(&block)
126
+ end
127
+ end
128
+
129
+ def each_child(&block)
130
+ @children.each(&block)
131
+ end
132
+
133
+ def chapter?
134
+ false
135
+ end
136
+
137
+ def each_section(&block)
138
+ @children.each do |n|
139
+ n.yield_section(&block)
140
+ end
141
+ end
142
+
143
+ def each_section_with_index
144
+ i = 0
145
+ each_section do |n|
146
+ yield n, i
147
+ i += 1
148
+ end
149
+ end
150
+
151
+ def n_sections
152
+ cnt = 0
153
+ @children.each do |n|
154
+ n.yield_section { cnt += 1 }
155
+ end
156
+ cnt
157
+ end
158
+
159
+ end
160
+
161
+
162
+ class Section < Node
163
+
164
+ def initialize(level, label, path = nil)
165
+ super()
166
+ @level = level
167
+ @label = label
168
+ @filename = (path ? real_filename(path) : nil)
169
+ end
170
+
171
+ def real_filename(path)
172
+ if FileTest.symlink?(path)
173
+ File.basename(File.readlink(path))
174
+ else
175
+ File.basename(path)
176
+ end
177
+ end
178
+ private :real_filename
179
+
180
+ attr_reader :level
181
+ attr_reader :label
182
+
183
+ def display_label
184
+ if @filename
185
+ @label + ' ' + @filename
186
+ else
187
+ @label
188
+ end
189
+ end
190
+
191
+ def estimated_lines
192
+ @children.inject(0) {|sum, n| sum + n.estimated_lines }
193
+ end
194
+
195
+ def yield_section
196
+ yield self
197
+ end
198
+
199
+ def inspect
200
+ "\#<#{self.class} level=#{@level} #{@label}>"
201
+ end
202
+
203
+ end
204
+
205
+
206
+ class Chapter < Section
207
+
208
+ def initialize(label, id, path)
209
+ super 1, label, path
210
+ @chapter_id = id
211
+ @path = path
212
+ @volume = nil
213
+ @number = nil
214
+ end
215
+
216
+ attr_accessor :number
217
+
218
+ def chapter?
219
+ true
220
+ end
221
+
222
+ attr_reader :chapter_id
223
+
224
+ def volume
225
+ return @volume if @volume
226
+ return Book::Volume.dummy unless @path
227
+ @volume = Book::Volume.count_file(@path)
228
+ @volume.lines = estimated_lines()
229
+ @volume
230
+ end
231
+
232
+ def inspect
233
+ "\#<#{self.class} #{@filename}>"
234
+ end
235
+
236
+ end
237
+
238
+
239
+ class Paragraph < Node
240
+
241
+ def initialize
242
+ @bytes = 0
243
+ end
244
+
245
+ def inspect
246
+ "\#<#{self.class}>"
247
+ end
248
+
249
+ def add(line)
250
+ @bytes += line.strip.bytesize
251
+ end
252
+
253
+ def estimated_lines
254
+ (@bytes + 2) / ReVIEW.book.page_metric.text.n_columns + 1
255
+ end
256
+
257
+ def yield_section
258
+ end
259
+
260
+ end
261
+
262
+
263
+ class List < Node
264
+
265
+ def initialize
266
+ @lines = 0
267
+ end
268
+
269
+ def inspect
270
+ "\#<#{self.class}>"
271
+ end
272
+
273
+ def add(line)
274
+ @lines += 1
275
+ end
276
+
277
+ def estimated_lines
278
+ @lines + 2
279
+ end
280
+
281
+ def yield_section
282
+ end
283
+
284
+ end
285
+
286
+ end
287
+
288
+
289
+ module TOCRoot
290
+ def level
291
+ 0
292
+ end
293
+
294
+ def chapter?
295
+ false
296
+ end
297
+
298
+ def each_section_with_index
299
+ idx = -1
300
+ each_section do |node|
301
+ yield node, (idx += 1)
302
+ end
303
+ end
304
+
305
+ def each_section(&block)
306
+ each_chapter do |chap|
307
+ yield chap.toc
308
+ end
309
+ end
310
+
311
+ def n_sections
312
+ chapters.size
313
+ end
314
+
315
+ def estimated_lines
316
+ chapters.inject(0) {|sum, chap| sum + chap.toc.estimated_lines }
317
+ end
318
+ end
319
+
320
+ class Book::Base # reopen
321
+ include TOCRoot
322
+ end
323
+
324
+ class Book::ChapterSet # reopen
325
+ include TOCRoot
326
+ end
327
+
328
+ class Book::Part
329
+ include TOCRoot
330
+ end
331
+
332
+ class Book::Chapter # reopen
333
+ def toc
334
+ @toc ||= TOCParser.parse(self)
335
+ unless @toc.size == 1
336
+ $stderr.puts "warning: chapter #{@toc.join} contains more than 1 chapter"
337
+ end
338
+ @toc.first
339
+ end
340
+ end
341
+
342
+ end