review 5.0.0 → 5.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby-tex.yml +35 -0
- data/.github/workflows/ruby-win.yml +8 -4
- data/.github/workflows/ruby.yml +6 -2
- data/.rubocop.yml +24 -9
- data/NEWS.ja.md +215 -0
- data/NEWS.md +215 -1
- data/README.md +7 -6
- data/Rakefile +7 -2
- data/bin/review +2 -4
- data/bin/review-catalog-converter +3 -3
- data/bin/review-check +6 -8
- data/bin/review-checkdep +1 -4
- data/bin/review-compile +10 -20
- data/bin/review-epub2html +1 -4
- data/bin/review-epubmaker +3 -4
- data/bin/review-idgxmlmaker +1 -3
- data/bin/review-index +11 -5
- data/bin/review-init +1 -4
- data/bin/review-pdfmaker +1 -3
- data/bin/review-preproc +30 -38
- data/bin/review-textmaker +1 -3
- data/bin/review-update +1 -4
- data/bin/review-validate +3 -3
- data/bin/review-vol +1 -4
- data/bin/review-webmaker +1 -3
- data/doc/config.yml.sample +23 -5
- data/doc/config.yml.sample-simple +1 -1
- data/doc/format.ja.md +49 -12
- data/doc/format.md +52 -12
- data/doc/quickstart.ja.md +11 -1
- data/doc/quickstart.md +11 -2
- data/doc/writing_vertical.ja.md +6 -0
- data/lib/review/book/base.rb +4 -0
- data/lib/review/book/book_unit.rb +15 -2
- data/lib/review/book/chapter.rb +3 -0
- data/lib/review/book/index.rb +5 -1
- data/lib/review/book/volume.rb +1 -0
- data/lib/review/builder.rb +90 -54
- data/lib/review/call_hook.rb +20 -0
- data/lib/review/catalog.rb +2 -0
- data/lib/review/compiler.rb +88 -52
- data/lib/review/configure.rb +64 -7
- data/lib/review/epubmaker/content.rb +113 -0
- data/lib/review/epubmaker/epubcommon.rb +372 -0
- data/lib/review/epubmaker/epubv2.rb +178 -0
- data/lib/review/epubmaker/epubv3.rb +231 -0
- data/lib/review/epubmaker/producer.rb +167 -0
- data/lib/review/epubmaker/reviewheaderlistener.rb +12 -2
- data/lib/review/epubmaker/zip_exporter.rb +84 -0
- data/lib/review/epubmaker.rb +114 -129
- data/lib/review/exception.rb +13 -0
- data/lib/review/htmlbuilder.rb +109 -67
- data/lib/review/htmlutils.rb +1 -1
- data/lib/review/i18n.rb +1 -0
- data/lib/review/i18n.yml +6 -0
- data/lib/review/idgxmlbuilder.rb +72 -48
- data/lib/review/idgxmlmaker.rb +15 -14
- data/lib/review/img_math.rb +239 -0
- data/lib/review/index_builder.rb +90 -32
- data/lib/review/init.rb +4 -4
- data/lib/review/latexbox.rb +58 -0
- data/lib/review/latexbuilder.rb +79 -58
- data/lib/review/latexutils.rb +9 -1
- data/lib/review/lineinput.rb +112 -2
- data/lib/review/loggable.rb +27 -0
- data/lib/review/logger.rb +89 -2
- data/lib/review/makerhelper.rb +7 -206
- data/lib/review/markdownbuilder.rb +44 -4
- data/lib/review/pdfmaker.rb +70 -51
- data/lib/review/plaintextbuilder.rb +20 -11
- data/lib/review/preprocessor/directive.rb +35 -0
- data/lib/review/preprocessor/line.rb +34 -0
- data/lib/review/preprocessor/repository.rb +177 -0
- data/lib/review/preprocessor.rb +105 -301
- data/lib/review/rstbuilder.rb +13 -4
- data/lib/review/sec_counter.rb +1 -0
- data/lib/review/template.rb +11 -1
- data/lib/review/textmaker.rb +23 -20
- data/lib/review/textutils.rb +10 -17
- data/lib/review/tocprinter.rb +93 -71
- data/lib/review/topbuilder.rb +44 -19
- data/lib/review/update.rb +5 -6
- data/lib/review/version.rb +1 -1
- data/lib/review/volumeprinter.rb +11 -12
- data/lib/review/webmaker.rb +31 -27
- data/lib/review/webtocprinter.rb +10 -9
- data/lib/review/yamlloader.rb +2 -1
- data/lib/review.rb +1 -1
- data/review.gemspec +5 -3
- data/samples/sample-book/src/config-epub2.yml +1 -1
- data/samples/sample-book/src/config.yml +1 -1
- data/samples/sample-book/src/lib/tasks/review.rake +19 -1
- data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +2 -1
- data/samples/syntax-book/ch01.re +1 -1
- data/samples/syntax-book/ch02.re +30 -6
- data/samples/syntax-book/ch03.re +1 -1
- data/samples/syntax-book/images/img3-2.png +0 -0
- data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +2 -1
- data/templates/html/_colophon.html.erb +23 -0
- data/templates/html/_colophon_history.html.erb +9 -0
- data/templates/html/_cover.html.erb +10 -0
- data/templates/html/_part_body.html.erb +6 -0
- data/templates/html/_titlepage.html.erb +20 -0
- data/templates/html/layout-html5.html.erb +6 -0
- data/templates/html/layout-xhtml1.html.erb +6 -0
- data/templates/latex/config.erb +11 -0
- data/templates/latex/review-jlreq/review-base.sty +7 -9
- data/templates/latex/review-jlreq/review-jlreq.cls +48 -6
- data/templates/latex/review-jlreq/review-style.sty +6 -1
- data/templates/latex/review-jlreq/review-tcbox.sty +348 -0
- data/templates/latex/review-jlreq/reviewmacro.sty +5 -0
- data/templates/latex/review-jsbook/review-base.sty +13 -9
- data/templates/latex/review-jsbook/review-jsbook.cls +41 -6
- data/templates/latex/review-jsbook/review-style.sty +6 -1
- data/templates/latex/review-jsbook/review-tcbox.sty +348 -0
- data/templates/latex/review-jsbook/reviewmacro.sty +5 -0
- data/templates/opf/epubv2.opf.erb +7 -7
- data/templates/opf/epubv3.opf.erb +7 -7
- data/templates/opf/opf_manifest_epubv2.opf.erb +10 -0
- data/templates/opf/opf_manifest_epubv3.opf.erb +10 -0
- data/templates/opf/opf_metainfo_epubv2.opf.erb +17 -0
- data/templates/opf/opf_metainfo_epubv3.opf.erb +49 -0
- data/templates/opf/opf_tocx_epubv2.opf.erb +9 -0
- data/templates/opf/opf_tocx_epubv3.opf.erb +17 -0
- data/templates/web/html/layout-html5.html.erb +6 -5
- data/templates/web/html/layout-xhtml1.html.erb +6 -0
- data/test/assets/header_listener.html +35 -0
- data/test/assets/img_math/img1.png +0 -0
- data/test/assets/img_math/img2.png +0 -0
- data/test/assets/img_math/img3.png +0 -0
- data/test/assets/syntax_book_index_detail.txt +60 -0
- data/test/assets/test_template.tex +7 -1
- data/test/assets/test_template_backmatter.tex +7 -1
- data/test/run_test.rb +1 -1
- data/test/test_book_chapter.rb +27 -4
- data/test/test_builder.rb +10 -8
- data/test/test_catalog_converter_cmd.rb +1 -1
- data/test/test_epub3maker.rb +168 -124
- data/test/test_epubmaker.rb +248 -131
- data/test/test_epubmaker_cmd.rb +15 -4
- data/test/test_helper.rb +5 -4
- data/test/test_htmlbuilder.rb +170 -31
- data/test/test_idgxmlbuilder.rb +44 -23
- data/test/test_idgxmlmaker_cmd.rb +7 -3
- data/test/test_img_math.rb +111 -0
- data/test/test_index.rb +30 -4
- data/test/test_indexbuilder.rb +5 -5
- data/test/test_latexbuilder.rb +151 -26
- data/test/test_latexbuilder_v2.rb +18 -10
- data/test/test_lineinput.rb +20 -93
- data/test/test_markdownbuilder.rb +42 -0
- data/test/test_pdfmaker.rb +90 -0
- data/test/test_pdfmaker_cmd.rb +2 -2
- data/test/test_plaintextbuilder.rb +56 -40
- data/test/test_preprocessor.rb +188 -1
- data/test/test_reviewheaderlistener.rb +49 -0
- data/test/test_rstbuilder.rb +13 -0
- data/test/test_template.rb +12 -2
- data/test/test_textmaker_cmd.rb +5 -1
- data/test/test_tocprinter.rb +46 -0
- data/test/test_topbuilder.rb +50 -19
- data/test/test_update.rb +34 -34
- data/test/test_zip_exporter.rb +5 -6
- metadata +95 -17
- data/lib/epubmaker/content.rb +0 -111
- data/lib/epubmaker/epubcommon.rb +0 -449
- data/lib/epubmaker/epubv2.rb +0 -142
- data/lib/epubmaker/epubv3.rb +0 -235
- data/lib/epubmaker/producer.rb +0 -375
- data/lib/epubmaker/zip_exporter.rb +0 -81
- data/lib/epubmaker.rb +0 -23
- data/lib/lineinput.rb +0 -155
data/lib/review/epubmaker.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010-
|
1
|
+
# Copyright (c) 2010-2021 Kenshi Muto and Masayoshi Takahashi
|
2
2
|
#
|
3
3
|
# This program is free software.
|
4
4
|
# You can distribute or modify this program under the terms of
|
@@ -13,47 +13,35 @@ require 'review/book'
|
|
13
13
|
require 'review/configure'
|
14
14
|
require 'review/converter'
|
15
15
|
require 'review/latexbuilder'
|
16
|
-
require 'review/yamlloader'
|
17
16
|
require 'review/version'
|
18
17
|
require 'review/htmltoc'
|
19
18
|
require 'review/htmlbuilder'
|
19
|
+
require 'review/img_math'
|
20
20
|
|
21
21
|
require 'rexml/document'
|
22
22
|
require 'rexml/streamlistener'
|
23
|
-
require '
|
23
|
+
require 'review/call_hook'
|
24
|
+
require 'review/epubmaker/producer'
|
25
|
+
require 'review/epubmaker/content'
|
26
|
+
require 'review/epubmaker/epubv2'
|
27
|
+
require 'review/epubmaker/epubv3'
|
24
28
|
require 'review/epubmaker/reviewheaderlistener'
|
25
29
|
require 'review/makerhelper'
|
30
|
+
require 'review/loggable'
|
26
31
|
|
27
32
|
module ReVIEW
|
28
33
|
class EPUBMaker
|
29
|
-
include ::EPUBMaker
|
30
|
-
include REXML
|
31
34
|
include MakerHelper
|
35
|
+
include Loggable
|
36
|
+
include ReVIEW::CallHook
|
32
37
|
|
33
38
|
def initialize
|
34
39
|
@producer = nil
|
35
40
|
@htmltoc = nil
|
36
41
|
@buildlogtxt = 'build-log.txt'
|
37
42
|
@logger = ReVIEW.logger
|
38
|
-
|
39
|
-
|
40
|
-
def error(msg)
|
41
|
-
@logger.error msg
|
42
|
-
exit 1
|
43
|
-
end
|
44
|
-
|
45
|
-
def warn(msg)
|
46
|
-
@logger.warn msg
|
47
|
-
end
|
48
|
-
|
49
|
-
def log(msg)
|
50
|
-
@logger.debug(msg)
|
51
|
-
end
|
52
|
-
|
53
|
-
def load_yaml(yamlfile)
|
54
|
-
@producer = Producer.new(@config)
|
55
|
-
@producer.load(yamlfile)
|
56
|
-
@config = @producer.config
|
43
|
+
@img_math = nil
|
44
|
+
@basedir = nil
|
57
45
|
end
|
58
46
|
|
59
47
|
def self.execute(*args)
|
@@ -85,22 +73,28 @@ module ReVIEW
|
|
85
73
|
|
86
74
|
def execute(*args)
|
87
75
|
cmd_config, yamlfile, exportfile = parse_opts(args)
|
88
|
-
error "#{yamlfile} not found." unless File.exist?(yamlfile)
|
76
|
+
error! "#{yamlfile} not found." unless File.exist?(yamlfile)
|
89
77
|
|
90
78
|
@config = ReVIEW::Configure.create(maker: 'epubmaker',
|
91
79
|
yamlfile: yamlfile,
|
92
80
|
config: cmd_config)
|
93
|
-
|
81
|
+
@producer = ReVIEW::EPUBMaker::Producer.new(@config)
|
94
82
|
update_log_level
|
95
|
-
|
83
|
+
debug("Loaded yaml file (#{yamlfile}).")
|
84
|
+
@basedir = File.absolute_path(File.dirname(yamlfile))
|
96
85
|
|
97
86
|
produce(yamlfile, exportfile)
|
98
87
|
end
|
99
88
|
|
100
89
|
def update_log_level
|
101
90
|
if @config['debug']
|
102
|
-
@logger.
|
103
|
-
|
91
|
+
if @logger.ttylogger?
|
92
|
+
ReVIEW.logger = nil
|
93
|
+
@logger = ReVIEW.logger(level: 'debug')
|
94
|
+
else
|
95
|
+
@logger.level = Logger::DEBUG
|
96
|
+
end
|
97
|
+
elsif !@logger.ttylogger?
|
104
98
|
@logger.level = Logger::INFO
|
105
99
|
end
|
106
100
|
end
|
@@ -123,43 +117,43 @@ module ReVIEW
|
|
123
117
|
bookname ||= @config['bookname']
|
124
118
|
booktmpname = "#{bookname}-epub"
|
125
119
|
|
120
|
+
@img_math = ReVIEW::ImgMath.new(@config)
|
126
121
|
begin
|
127
|
-
@config.check_version(ReVIEW::VERSION)
|
122
|
+
@config.check_version(ReVIEW::VERSION, exception: true)
|
128
123
|
rescue ReVIEW::ConfigError => e
|
129
124
|
warn e.message
|
130
125
|
end
|
131
|
-
|
126
|
+
debug("#{bookname}.epub will be created.")
|
132
127
|
|
133
128
|
FileUtils.rm_f("#{bookname}.epub")
|
134
129
|
if @config['debug']
|
135
130
|
FileUtils.rm_rf(booktmpname)
|
136
131
|
end
|
137
132
|
|
138
|
-
cleanup_mathimg
|
133
|
+
@img_math.cleanup_mathimg
|
139
134
|
|
140
135
|
basetmpdir = build_path
|
141
136
|
begin
|
142
|
-
|
137
|
+
debug("Created first temporary directory as #{basetmpdir}.")
|
143
138
|
|
144
|
-
call_hook('hook_beforeprocess', basetmpdir)
|
139
|
+
call_hook('hook_beforeprocess', basetmpdir, base_dir: @basedir)
|
145
140
|
|
146
141
|
@htmltoc = ReVIEW::HTMLToc.new(basetmpdir)
|
147
142
|
## copy all files into basetmpdir
|
148
143
|
copy_stylesheet(basetmpdir)
|
149
144
|
|
150
145
|
copy_frontmatter(basetmpdir)
|
151
|
-
call_hook('hook_afterfrontmatter', basetmpdir)
|
146
|
+
call_hook('hook_afterfrontmatter', basetmpdir, base_dir: @basedir)
|
152
147
|
|
153
148
|
build_body(basetmpdir, yamlfile)
|
154
|
-
call_hook('hook_afterbody', basetmpdir)
|
149
|
+
call_hook('hook_afterbody', basetmpdir, base_dir: @basedir)
|
155
150
|
|
156
151
|
copy_backmatter(basetmpdir)
|
157
152
|
|
158
|
-
|
159
|
-
|
160
|
-
make_math_images(math_dir)
|
153
|
+
if @config['math_format'] == 'imgmath'
|
154
|
+
@img_math.make_math_images
|
161
155
|
end
|
162
|
-
call_hook('hook_afterbackmatter', basetmpdir)
|
156
|
+
call_hook('hook_afterbackmatter', basetmpdir, base_dir: @basedir)
|
163
157
|
|
164
158
|
## push contents in basetmpdir into @producer
|
165
159
|
push_contents(basetmpdir)
|
@@ -175,7 +169,7 @@ module ReVIEW
|
|
175
169
|
copy_resources('adv', File.join(basetmpdir, @config['imagedir']))
|
176
170
|
copy_resources(@config['fontdir'], File.join(basetmpdir, 'fonts'), @config['font_ext'])
|
177
171
|
|
178
|
-
call_hook('hook_aftercopyimage', basetmpdir)
|
172
|
+
call_hook('hook_aftercopyimage', basetmpdir, base_dir: @basedir)
|
179
173
|
|
180
174
|
@producer.import_imageinfo(File.join(basetmpdir, @config['imagedir']), basetmpdir)
|
181
175
|
@producer.import_imageinfo(File.join(basetmpdir, 'fonts'), basetmpdir, @config['font_ext'])
|
@@ -187,35 +181,25 @@ module ReVIEW
|
|
187
181
|
epubtmpdir = File.join(basetmpdir, booktmpname)
|
188
182
|
Dir.mkdir(epubtmpdir)
|
189
183
|
end
|
190
|
-
|
191
|
-
@producer.produce("#{bookname}.epub", basetmpdir, epubtmpdir)
|
192
|
-
|
184
|
+
debug('Call ePUB producer.')
|
185
|
+
@producer.produce("#{bookname}.epub", basetmpdir, epubtmpdir, base_dir: @basedir)
|
186
|
+
debug('Finished.')
|
187
|
+
@logger.success("built #{bookname}.epub")
|
193
188
|
rescue ApplicationError => e
|
194
189
|
raise if @config['debug']
|
195
|
-
|
190
|
+
|
191
|
+
error! e.message
|
196
192
|
ensure
|
197
193
|
FileUtils.remove_entry_secure(basetmpdir) unless @config['debug']
|
198
194
|
end
|
199
195
|
end
|
200
196
|
|
201
|
-
def call_hook(hook_name, *params)
|
202
|
-
filename = @config['epubmaker'][hook_name]
|
203
|
-
log("Call #{hook_name}. (#{filename})")
|
204
|
-
if filename.present? && File.exist?(filename) && FileTest.executable?(filename)
|
205
|
-
if ENV['REVIEW_SAFE_MODE'].to_i & 1 > 0
|
206
|
-
warn 'hook is prohibited in safe mode. ignored.'
|
207
|
-
else
|
208
|
-
system(filename, *params)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
197
|
def verify_target_images(basetmpdir)
|
214
198
|
@producer.contents.each do |content|
|
215
199
|
case content.media
|
216
200
|
when 'application/xhtml+xml'
|
217
201
|
File.open("#{basetmpdir}/#{content.file}") do |f|
|
218
|
-
Document.new(File.new(f)).each_element('//img') do |e|
|
202
|
+
REXML::Document.new(File.new(f)).each_element('//img') do |e|
|
219
203
|
@config['epubmaker']['force_include_images'].push(e.attributes['src'])
|
220
204
|
if e.attributes['src'] =~ /svg\Z/i
|
221
205
|
content.properties.push('svg')
|
@@ -237,6 +221,7 @@ module ReVIEW
|
|
237
221
|
|
238
222
|
def copy_images(resdir, destdir, allow_exts = nil)
|
239
223
|
return nil unless File.exist?(resdir)
|
224
|
+
|
240
225
|
allow_exts ||= @config['image_ext']
|
241
226
|
FileUtils.mkdir_p(destdir)
|
242
227
|
if @config['epubmaker']['verify_target_images'].present?
|
@@ -249,8 +234,8 @@ module ReVIEW
|
|
249
234
|
end
|
250
235
|
basedir = File.dirname(file)
|
251
236
|
FileUtils.mkdir_p(File.join(destdir, basedir))
|
252
|
-
|
253
|
-
FileUtils.cp(file, File.join(destdir, basedir))
|
237
|
+
debug("Copy #{file} to the temporary directory.")
|
238
|
+
FileUtils.cp(file, File.join(destdir, basedir), preserve: true)
|
254
239
|
end
|
255
240
|
else
|
256
241
|
recursive_copy_files(resdir, destdir, allow_exts)
|
@@ -259,6 +244,7 @@ module ReVIEW
|
|
259
244
|
|
260
245
|
def copy_resources(resdir, destdir, allow_exts = nil)
|
261
246
|
return nil unless File.exist?(resdir)
|
247
|
+
|
262
248
|
allow_exts ||= @config['image_ext']
|
263
249
|
FileUtils.mkdir_p(destdir)
|
264
250
|
recursive_copy_files(resdir, destdir, allow_exts)
|
@@ -268,12 +254,13 @@ module ReVIEW
|
|
268
254
|
Dir.open(resdir) do |dir|
|
269
255
|
dir.each do |fname|
|
270
256
|
next if fname.start_with?('.')
|
257
|
+
|
271
258
|
if FileTest.directory?(File.join(resdir, fname))
|
272
259
|
recursive_copy_files(File.join(resdir, fname), File.join(destdir, fname), allow_exts)
|
273
260
|
elsif fname =~ /\.(#{allow_exts.join('|')})\Z/i
|
274
261
|
FileUtils.mkdir_p(destdir)
|
275
|
-
|
276
|
-
FileUtils.cp(File.join(resdir, fname), destdir)
|
262
|
+
debug("Copy #{resdir}/#{fname} to the temporary directory.")
|
263
|
+
FileUtils.cp(File.join(resdir, fname), destdir, preserve: true)
|
277
264
|
end
|
278
265
|
end
|
279
266
|
end
|
@@ -282,8 +269,7 @@ module ReVIEW
|
|
282
269
|
def check_compile_status
|
283
270
|
return unless @compile_errors
|
284
271
|
|
285
|
-
|
286
|
-
exit 1
|
272
|
+
error! 'compile error, No EPUB file output.'
|
287
273
|
end
|
288
274
|
|
289
275
|
def build_body(basetmpdir, yamlfile)
|
@@ -298,7 +284,7 @@ module ReVIEW
|
|
298
284
|
basedir = File.dirname(yamlfile)
|
299
285
|
base_path = Pathname.new(basedir)
|
300
286
|
book = ReVIEW::Book::Base.new(basedir, config: @config)
|
301
|
-
@converter = ReVIEW::Converter.new(book, ReVIEW::HTMLBuilder.new)
|
287
|
+
@converter = ReVIEW::Converter.new(book, ReVIEW::HTMLBuilder.new(img_math: @img_math))
|
302
288
|
@compile_errors = nil
|
303
289
|
|
304
290
|
book.parts.each do |part|
|
@@ -325,21 +311,15 @@ module ReVIEW
|
|
325
311
|
end
|
326
312
|
|
327
313
|
def build_part(part, basetmpdir, htmlfile)
|
328
|
-
|
314
|
+
debug("Create #{htmlfile} from a template.")
|
329
315
|
File.open(File.join(basetmpdir, htmlfile), 'w') do |f|
|
330
|
-
@
|
331
|
-
@
|
332
|
-
@body
|
333
|
-
if part.name.strip.present?
|
334
|
-
@body << %Q(<h2 class="part-title">#{h(part.name.strip)}</h2>\n)
|
335
|
-
end
|
336
|
-
@body << %Q(</div>\n)
|
316
|
+
@part_number = part.number
|
317
|
+
@part_title = part.name.strip
|
318
|
+
@body = ReVIEW::Template.generate(path: 'html/_part_body.html.erb', binding: binding)
|
337
319
|
|
338
320
|
@language = @producer.config['language']
|
339
321
|
@stylesheets = @producer.config['stylesheet']
|
340
|
-
|
341
|
-
tmpl = ReVIEW::Template.load(tmplfile)
|
342
|
-
f.write tmpl.result(binding)
|
322
|
+
f.write ReVIEW::Template.generate(path: template_name, binding: binding)
|
343
323
|
end
|
344
324
|
end
|
345
325
|
|
@@ -392,7 +372,7 @@ module ReVIEW
|
|
392
372
|
|
393
373
|
htmlfile = "#{id}.#{@config['htmlext']}"
|
394
374
|
write_buildlogtxt(basetmpdir, htmlfile, filename)
|
395
|
-
|
375
|
+
debug("Create #{htmlfile} from #{filename}.")
|
396
376
|
|
397
377
|
if @config['params'].present?
|
398
378
|
warn %Q('params:' in config.yml is obsoleted.)
|
@@ -406,8 +386,8 @@ module ReVIEW
|
|
406
386
|
remove_hidden_title(basetmpdir, htmlfile)
|
407
387
|
rescue => e
|
408
388
|
@compile_errors = true
|
409
|
-
|
410
|
-
|
389
|
+
error "compile error in #{filename} (#{e.class})"
|
390
|
+
error e.message
|
411
391
|
end
|
412
392
|
end
|
413
393
|
|
@@ -436,12 +416,19 @@ module ReVIEW
|
|
436
416
|
properties
|
437
417
|
end
|
438
418
|
|
439
|
-
def
|
419
|
+
def parse_headlines(path)
|
440
420
|
headlines = []
|
421
|
+
|
422
|
+
File.open(path) do |htmlio|
|
423
|
+
REXML::Document.parse_stream(htmlio, ReVIEWHeaderListener.new(headlines))
|
424
|
+
end
|
425
|
+
|
426
|
+
headlines
|
427
|
+
end
|
428
|
+
|
429
|
+
def write_info_body(basetmpdir, _id, filename, ispart = nil, chaptype = nil)
|
441
430
|
path = File.join(basetmpdir, filename)
|
442
|
-
|
443
|
-
Document.parse_stream(htmlio, ReVIEWHeaderListener.new(headlines))
|
444
|
-
htmlio.close
|
431
|
+
headlines = parse_headlines(path)
|
445
432
|
|
446
433
|
if headlines.empty?
|
447
434
|
warn "#{filename} is discarded because there is no heading. Use `=[notoc]' or `=[nodisp]' to exclude headlines from the table of contents."
|
@@ -480,70 +467,77 @@ module ReVIEW
|
|
480
467
|
def push_contents(_basetmpdir)
|
481
468
|
@htmltoc.each_item do |level, file, title, args|
|
482
469
|
next if level.to_i > @config['toclevel'] && args[:force_include].nil?
|
483
|
-
log("Push #{file} to ePUB contents.")
|
484
470
|
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
471
|
+
debug("Push #{file} to ePUB contents.")
|
472
|
+
|
473
|
+
params = { file: file,
|
474
|
+
level: level.to_i,
|
475
|
+
title: title,
|
476
|
+
chaptype: args[:chaptype] }
|
489
477
|
if args[:id].present?
|
490
|
-
|
478
|
+
params[:id] = args[:id]
|
491
479
|
end
|
492
480
|
if args[:properties].present?
|
493
|
-
|
481
|
+
params[:properties] = args[:properties].split(' ') # rubocop:disable Style/RedundantArgument
|
494
482
|
end
|
495
483
|
if args[:notoc].present?
|
496
|
-
|
484
|
+
params[:notoc] = args[:notoc]
|
497
485
|
end
|
498
|
-
@producer.contents.push(Content.new(
|
486
|
+
@producer.contents.push(ReVIEW::EPUBMaker::Content.new(**params))
|
499
487
|
end
|
500
488
|
end
|
501
489
|
|
502
490
|
def copy_stylesheet(basetmpdir)
|
503
491
|
return if @config['stylesheet'].empty?
|
492
|
+
|
504
493
|
@config['stylesheet'].each do |sfile|
|
505
494
|
unless File.exist?(sfile)
|
506
|
-
error "#{sfile} is not found."
|
495
|
+
error! "stylesheet: #{sfile} is not found."
|
507
496
|
end
|
508
|
-
FileUtils.cp(sfile, basetmpdir)
|
509
|
-
@producer.contents.push(Content.new(
|
497
|
+
FileUtils.cp(sfile, basetmpdir, preserve: true)
|
498
|
+
@producer.contents.push(ReVIEW::EPUBMaker::Content.new(file: sfile))
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
def copy_static_file(configname, destdir, destfilename: nil)
|
503
|
+
destfilename ||= @config[configname]
|
504
|
+
unless File.exist?(@config[configname])
|
505
|
+
error! "#{configname}: #{@config[configname]} is not found."
|
510
506
|
end
|
507
|
+
FileUtils.cp(@config[configname],
|
508
|
+
File.join(destdir, destfilename), preserve: true)
|
511
509
|
end
|
512
510
|
|
513
511
|
def copy_frontmatter(basetmpdir)
|
514
512
|
if @config['cover'].present? && File.exist?(@config['cover'])
|
515
|
-
|
516
|
-
File.join(basetmpdir, File.basename(@config['cover'])))
|
513
|
+
copy_static_file('cover', basetmpdir)
|
517
514
|
end
|
518
515
|
|
519
516
|
if @config['titlepage']
|
520
517
|
if @config['titlefile'].nil?
|
521
518
|
build_titlepage(basetmpdir, "titlepage.#{@config['htmlext']}")
|
522
519
|
else
|
523
|
-
|
524
|
-
File.join(basetmpdir, "titlepage.#{@config['htmlext']}"))
|
520
|
+
copy_static_file('titlefile', basetmpdir, destfilename: "titlepage.#{@config['htmlext']}")
|
525
521
|
end
|
526
522
|
@htmltoc.add_item(1,
|
527
523
|
"titlepage.#{@config['htmlext']}",
|
528
|
-
|
524
|
+
ReVIEW::I18n.t('titlepagetitle'),
|
529
525
|
chaptype: 'pre')
|
530
526
|
end
|
531
527
|
|
532
|
-
if @config['originaltitlefile'].present?
|
533
|
-
|
534
|
-
File.join(basetmpdir, File.basename(@config['originaltitlefile'])))
|
528
|
+
if @config['originaltitlefile'].present?
|
529
|
+
copy_static_file('originaltitlefile', basetmpdir)
|
535
530
|
@htmltoc.add_item(1,
|
536
531
|
File.basename(@config['originaltitlefile']),
|
537
|
-
|
532
|
+
ReVIEW::I18n.t('originaltitle'),
|
538
533
|
chaptype: 'pre')
|
539
534
|
end
|
540
535
|
|
541
|
-
if @config['creditfile'].present?
|
542
|
-
|
543
|
-
File.join(basetmpdir, File.basename(@config['creditfile'])))
|
536
|
+
if @config['creditfile'].present?
|
537
|
+
copy_static_file('creditfile', basetmpdir)
|
544
538
|
@htmltoc.add_item(1,
|
545
539
|
File.basename(@config['creditfile']),
|
546
|
-
|
540
|
+
ReVIEW::I18n.t('credittitle'),
|
547
541
|
chaptype: 'pre')
|
548
542
|
end
|
549
543
|
|
@@ -570,53 +564,42 @@ module ReVIEW
|
|
570
564
|
|
571
565
|
@language = @producer.config['language']
|
572
566
|
@stylesheets = @producer.config['stylesheet']
|
573
|
-
|
574
|
-
tmpl = ReVIEW::Template.load(tmplfile)
|
575
|
-
f.write tmpl.result(binding)
|
567
|
+
f.write ReVIEW::Template.generate(path: template_name, binding: binding)
|
576
568
|
end
|
577
569
|
end
|
578
570
|
|
579
571
|
def copy_backmatter(basetmpdir)
|
580
572
|
if @config['profile']
|
581
|
-
|
582
|
-
File.join(basetmpdir, File.basename(@config['profile'])))
|
573
|
+
copy_static_file('profile', basetmpdir)
|
583
574
|
@htmltoc.add_item(1,
|
584
575
|
File.basename(@config['profile']),
|
585
|
-
|
576
|
+
ReVIEW::I18n.t('profiletitle'),
|
586
577
|
chaptype: 'post')
|
587
578
|
end
|
588
579
|
|
589
580
|
if @config['advfile']
|
590
|
-
|
591
|
-
File.join(basetmpdir, File.basename(@config['advfile'])))
|
581
|
+
copy_static_file('advfile', basetmpdir)
|
592
582
|
@htmltoc.add_item(1,
|
593
583
|
File.basename(@config['advfile']),
|
594
|
-
|
584
|
+
ReVIEW::I18n.t('advtitle'),
|
595
585
|
chaptype: 'post')
|
596
586
|
end
|
597
587
|
|
598
588
|
if @config['colophon']
|
599
|
-
if @config['colophon'].is_a?(String)
|
600
|
-
|
601
|
-
File.join(basetmpdir, "colophon.#{@config['htmlext']}"))
|
602
|
-
else
|
603
|
-
filename = File.join(basetmpdir, "colophon.#{@config['htmlext']}")
|
604
|
-
File.open(filename, 'w') do |f|
|
605
|
-
@producer.colophon(f)
|
606
|
-
end
|
589
|
+
if @config['colophon'].is_a?(String)
|
590
|
+
copy_static_file('colophon', basetmpdir, destfilename: "colophon.#{@config['htmlext']}") # override pre-built colophon
|
607
591
|
end
|
608
592
|
@htmltoc.add_item(1,
|
609
593
|
"colophon.#{@config['htmlext']}",
|
610
|
-
|
594
|
+
ReVIEW::I18n.t('colophontitle'),
|
611
595
|
chaptype: 'post')
|
612
596
|
end
|
613
597
|
|
614
598
|
if @config['backcover']
|
615
|
-
|
616
|
-
File.join(basetmpdir, File.basename(@config['backcover'])))
|
599
|
+
copy_static_file('backcover', basetmpdir)
|
617
600
|
@htmltoc.add_item(1,
|
618
601
|
File.basename(@config['backcover']),
|
619
|
-
|
602
|
+
ReVIEW::I18n.t('backcovertitle'),
|
620
603
|
chaptype: 'post')
|
621
604
|
end
|
622
605
|
|
@@ -642,8 +625,10 @@ module ReVIEW
|
|
642
625
|
extre = Regexp.new(pat, Regexp::IGNORECASE)
|
643
626
|
Find.find(basetmpdir) do |fname|
|
644
627
|
next unless fname.match(extre)
|
628
|
+
|
645
629
|
img = ImageSize.path(fname)
|
646
630
|
next if img.width.nil? || img.width * img.height <= maxpixels
|
631
|
+
|
647
632
|
h = Math.sqrt(img.height * maxpixels / img.width)
|
648
633
|
w = maxpixels / h
|
649
634
|
fname.sub!("#{basetmpdir}/", '')
|
data/lib/review/exception.rb
CHANGED
@@ -10,10 +10,23 @@
|
|
10
10
|
|
11
11
|
module ReVIEW
|
12
12
|
class Error < ::StandardError; end
|
13
|
+
|
13
14
|
class ApplicationError < Error; end
|
15
|
+
|
14
16
|
class ConfigError < ApplicationError; end
|
17
|
+
|
15
18
|
class CompileError < ApplicationError; end
|
19
|
+
|
16
20
|
class SyntaxError < CompileError; end
|
21
|
+
|
17
22
|
class FileNotFound < ApplicationError; end
|
23
|
+
|
18
24
|
class KeyError < CompileError; end
|
25
|
+
|
26
|
+
class BuildError < ApplicationError
|
27
|
+
def initialize(msg, location: nil)
|
28
|
+
@location = location
|
29
|
+
super(msg)
|
30
|
+
end
|
31
|
+
end
|
19
32
|
end
|