review 4.1.0 → 5.2.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 +19 -9
- data/.github/workflows/ruby.yml +7 -3
- data/.rubocop.yml +138 -34
- data/NEWS.ja.md +285 -0
- data/NEWS.md +285 -1
- data/README.md +7 -6
- data/Rakefile +7 -2
- data/bin/review +2 -4
- data/bin/review-catalog-converter +4 -4
- data/bin/review-check +8 -12
- data/bin/review-checkdep +2 -5
- data/bin/review-compile +18 -34
- data/bin/review-epub2html +1 -4
- data/bin/review-epubmaker +3 -4
- data/bin/review-idgxmlmaker +1 -3
- data/bin/review-index +5 -86
- 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 +4 -4
- data/bin/review-vol +5 -82
- data/bin/review-webmaker +1 -3
- data/doc/config.yml.sample +45 -11
- data/doc/config.yml.sample-simple +3 -3
- data/doc/format.ja.md +103 -13
- data/doc/format.md +104 -16
- data/doc/makeindex.ja.md +2 -2
- data/doc/pdfmaker.ja.md +42 -0
- data/doc/pdfmaker.md +41 -0
- data/doc/quickstart.ja.md +19 -6
- data/doc/quickstart.md +18 -6
- data/doc/writing_vertical.ja.md +6 -0
- data/lib/review.rb +1 -1
- data/lib/review/book.rb +2 -2
- data/lib/review/book/base.rb +67 -29
- data/lib/review/book/bib.rb +21 -0
- data/lib/review/book/book_unit.rb +158 -0
- data/lib/review/book/chapter.rb +33 -26
- data/lib/review/book/index.rb +24 -185
- data/lib/review/book/index/item.rb +7 -1
- data/lib/review/book/page_metric.rb +7 -7
- data/lib/review/book/part.rb +26 -11
- data/lib/review/book/volume.rb +5 -5
- data/lib/review/builder.rb +121 -52
- data/lib/review/call_hook.rb +20 -0
- data/lib/review/catalog.rb +3 -2
- data/lib/review/compiler.rb +230 -111
- data/lib/review/configure.rb +91 -7
- data/lib/review/converter.rb +1 -1
- data/lib/review/epub2html.rb +6 -1
- data/lib/review/epubmaker.rb +124 -152
- 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/exception.rb +13 -0
- data/lib/review/htmlbuilder.rb +176 -89
- data/lib/review/htmlutils.rb +8 -11
- data/lib/review/i18n.rb +2 -1
- data/lib/review/idgxmlbuilder.rb +165 -75
- data/lib/review/idgxmlmaker.rb +24 -28
- data/lib/review/img_math.rb +238 -0
- data/lib/review/index_builder.rb +645 -0
- data/lib/review/init.rb +9 -17
- data/lib/review/latexbox.rb +58 -0
- data/lib/review/latexbuilder.rb +193 -75
- 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 +90 -3
- data/lib/review/makerhelper.rb +17 -188
- data/lib/review/markdownbuilder.rb +54 -4
- data/lib/review/pdfmaker.rb +76 -84
- data/lib/review/plaintextbuilder.rb +106 -22
- data/lib/review/preprocessor.rb +107 -303
- 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/rstbuilder.rb +27 -8
- data/lib/review/sec_counter.rb +14 -0
- data/lib/review/template.rb +11 -1
- data/lib/review/textmaker.rb +27 -32
- data/lib/review/textutils.rb +3 -12
- data/lib/review/tocprinter.rb +242 -97
- data/lib/review/topbuilder.rb +98 -31
- data/lib/review/update.rb +12 -13
- data/lib/review/version.rb +1 -1
- data/lib/review/volumeprinter.rb +97 -0
- data/lib/review/webmaker.rb +40 -47
- data/lib/review/webtocprinter.rb +39 -35
- data/lib/review/yamlloader.rb +2 -1
- data/review.gemspec +5 -3
- data/samples/sample-book/src/config-epub2.yml +1 -1
- data/samples/sample-book/src/config.yml +3 -3
- 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/Gemfile +1 -1
- data/samples/syntax-book/ch01.re +1 -1
- data/samples/syntax-book/ch02.re +21 -6
- data/samples/syntax-book/ch03.re +1 -1
- data/samples/syntax-book/config.yml +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 +35 -23
- data/templates/latex/review-jlreq/README.md +3 -1
- data/templates/latex/review-jlreq/review-base.sty +36 -23
- data/templates/latex/review-jlreq/review-jlreq.cls +18 -25
- 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/README.md +7 -5
- data/templates/latex/review-jsbook/review-base.sty +40 -24
- data/templates/latex/review-jsbook/review-jsbook.cls +13 -3
- 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 +9 -8
- 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 +58 -0
- data/test/assets/test_template.tex +6 -3
- data/test/assets/test_template_backmatter.tex +6 -3
- data/test/book_test_helper.rb +11 -5
- data/test/run_test.rb +1 -1
- data/test/test_book.rb +54 -63
- data/test/test_book_chapter.rb +95 -54
- data/test/test_book_part.rb +3 -3
- data/test/test_builder.rb +29 -20
- data/test/test_catalog_converter_cmd.rb +1 -1
- data/test/test_converter.rb +1 -0
- data/test/test_epub3maker.rb +170 -126
- data/test/test_epubmaker.rb +254 -129
- data/test/test_epubmaker_cmd.rb +15 -4
- data/test/test_helper.rb +12 -5
- data/test/test_htmlbuilder.rb +926 -76
- data/test/test_htmlutils.rb +0 -12
- data/test/test_i18n.rb +33 -33
- data/test/test_idgxmlbuilder.rb +531 -20
- data/test/test_idgxmlmaker_cmd.rb +7 -3
- data/test/test_img_math.rb +111 -0
- data/test/test_index.rb +62 -52
- data/test/test_indexbuilder.rb +52 -0
- data/test/test_latexbuilder.rb +891 -20
- data/test/test_latexbuilder_v2.rb +56 -10
- data/test/test_lineinput.rb +20 -93
- data/test/test_logger.rb +7 -7
- data/test/test_makerhelper.rb +0 -12
- data/test/test_markdownbuilder.rb +32 -0
- data/test/test_pdfmaker.rb +100 -11
- data/test/test_pdfmaker_cmd.rb +3 -3
- data/test/test_plaintextbuilder.rb +546 -32
- data/test/test_preprocessor.rb +188 -1
- data/test/test_review_ext.rb +2 -1
- data/test/test_reviewheaderlistener.rb +49 -0
- data/test/test_rstbuilder.rb +25 -1
- data/test/test_sec_counter.rb +156 -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 +324 -20
- data/test/test_update.rb +44 -44
- data/test/test_webtocprinter.rb +75 -43
- data/test/test_zip_exporter.rb +5 -6
- data/vendor/gentombow/LICENSE +1 -1
- data/vendor/gentombow/Makefile +0 -1
- data/vendor/gentombow/bounddvi-en.pdf +0 -0
- data/vendor/gentombow/bounddvi-en.tex +1 -0
- data/vendor/gentombow/bounddvi.pdf +0 -0
- data/vendor/gentombow/bounddvi.sty +30 -7
- data/vendor/gentombow/bounddvi.tex +1 -0
- data/vendor/gentombow/create_archive.sh +1 -0
- data/vendor/gentombow/gentombow-ja.pdf +0 -0
- data/vendor/gentombow/gentombow-ja.tex +9 -0
- data/vendor/gentombow/gentombow.pdf +0 -0
- data/vendor/gentombow/gentombow.sty +32 -10
- data/vendor/gentombow/gentombow.tex +8 -0
- data/vendor/gentombow/tests/gentombow-01-pdfx.tex +8 -0
- data/vendor/gentombow/tests/gentombow-02-pdfx.tex +8 -0
- data/vendor/jsclasses/Makefile +3 -2
- data/vendor/jsclasses/create_archive.sh +5 -5
- data/vendor/jsclasses/jis/Makefile +3 -2
- data/vendor/jsclasses/jis/jsarticle.cls +22 -18
- data/vendor/jsclasses/jis/jsbook.cls +22 -18
- data/vendor/jsclasses/jis/jsclasses.dtx +94 -13
- data/vendor/jsclasses/jis/jsclasses.ins +15 -5
- data/vendor/jsclasses/jis/jslogo.ins +9 -0
- data/vendor/jsclasses/jis/jslogo.sty +1 -13
- data/vendor/jsclasses/jis/jspf.cls +22 -18
- data/vendor/jsclasses/jis/jsreport.cls +22 -18
- data/vendor/jsclasses/jis/jsverb.ins +9 -0
- data/vendor/jsclasses/jis/jsverb.sty +1 -13
- data/vendor/jsclasses/jis/kiyou.cls +22 -18
- data/vendor/jsclasses/jis/minijs.sty +65 -22
- data/vendor/jsclasses/jis/okumacro.ins +9 -0
- data/vendor/jsclasses/jis/okumacro.sty +1 -13
- data/vendor/jsclasses/jis/okuverb.ins +9 -0
- data/vendor/jsclasses/jis/okuverb.sty +1 -13
- data/vendor/jsclasses/jis/winjis.sty +23 -19
- data/vendor/jsclasses/jsarticle.cls +22 -18
- data/vendor/jsclasses/jsbook.cls +22 -18
- data/vendor/jsclasses/jsclasses.dtx +94 -13
- data/vendor/jsclasses/jsclasses.ins +15 -5
- data/vendor/jsclasses/jsclasses.pdf +0 -0
- data/vendor/jsclasses/jslogo.ins +9 -0
- data/vendor/jsclasses/jslogo.pdf +0 -0
- data/vendor/jsclasses/jslogo.sty +1 -13
- data/vendor/jsclasses/jspf.cls +22 -18
- data/vendor/jsclasses/jsreport.cls +22 -18
- data/vendor/jsclasses/jsverb.ins +9 -0
- data/vendor/jsclasses/jsverb.pdf +0 -0
- data/vendor/jsclasses/jsverb.sty +1 -13
- data/vendor/jsclasses/kiyou.cls +22 -18
- data/vendor/jsclasses/minijs.sty +68 -22
- data/vendor/jsclasses/okumacro.ins +9 -0
- data/vendor/jsclasses/okumacro.pdf +0 -0
- data/vendor/jsclasses/okumacro.sty +1 -13
- data/vendor/jsclasses/okuverb.ins +9 -0
- data/vendor/jsclasses/okuverb.pdf +0 -0
- data/vendor/jsclasses/okuverb.sty +1 -13
- data/vendor/jsclasses/tests/relfont.tex +10 -0
- data/vendor/jsclasses/winjis.sty +23 -19
- metadata +106 -22
- data/.rubocop_todo.yml +0 -7
- data/lib/epubmaker.rb +0 -23
- data/lib/epubmaker/content.rb +0 -110
- data/lib/epubmaker/epubcommon.rb +0 -441
- data/lib/epubmaker/epubv2.rb +0 -143
- data/lib/epubmaker/epubv3.rb +0 -233
- data/lib/epubmaker/producer.rb +0 -375
- data/lib/epubmaker/zip_exporter.rb +0 -81
- data/lib/lineinput.rb +0 -155
- data/lib/review/book/compilable.rb +0 -178
- data/lib/review/tocparser.rb +0 -275
- data/test/test_tocparser.rb +0 -25
@@ -0,0 +1,113 @@
|
|
1
|
+
# = content.rb -- Content object for EPUBMaker.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010-2020 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
|
+
# For details of the GNU LGPL, see the file "COPYING".
|
9
|
+
#
|
10
|
+
|
11
|
+
module ReVIEW
|
12
|
+
class EPUBMaker
|
13
|
+
# EPUBMaker::Content represents a content data for EPUBMaker.
|
14
|
+
# EPUBMaker#contents takes an array of Content.
|
15
|
+
class Content
|
16
|
+
# ID
|
17
|
+
attr_accessor :id
|
18
|
+
# File path (will accept #<anchor> suffix also)
|
19
|
+
attr_accessor :file
|
20
|
+
# MIME type
|
21
|
+
attr_accessor :media
|
22
|
+
# Title
|
23
|
+
attr_accessor :title
|
24
|
+
# Header level (from 1)
|
25
|
+
attr_accessor :level
|
26
|
+
# Show in TOC? nil:No.
|
27
|
+
attr_accessor :notoc
|
28
|
+
# Properties (EPUB3)
|
29
|
+
attr_accessor :properties
|
30
|
+
# Chapter type (pre/post/part/nil(body))
|
31
|
+
attr_accessor :chaptype
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
"<Content id=#{@id}, file=#{@file}, media=#{@media}, title=#{@title}, level=#{@level}, notoc=#{@notoc}, properties=#{@properties}, chaptype=#{@chaptype}>"
|
35
|
+
end
|
36
|
+
|
37
|
+
# :call-seq:
|
38
|
+
# initialize(params)
|
39
|
+
# Construct Content object by passing named parameters.
|
40
|
+
# +params+[:file] is required. Others are optional.
|
41
|
+
def initialize(file:, id: nil, media: nil, title: nil, level: nil, notoc: nil, properties: nil, chaptype: nil)
|
42
|
+
@id = id
|
43
|
+
@file = file
|
44
|
+
@media = media
|
45
|
+
@title = title
|
46
|
+
@level = level
|
47
|
+
@notoc = notoc
|
48
|
+
@properties = properties || []
|
49
|
+
@chaptype = chaptype
|
50
|
+
complement
|
51
|
+
end
|
52
|
+
|
53
|
+
def ==(other)
|
54
|
+
return false unless self.class == other.class
|
55
|
+
|
56
|
+
[self.id, self.file, self.media, self.title, self.level, self.notoc, self.chaptype, self.properties] ==
|
57
|
+
[other.id, other.file, other.media, other.title, other.level, other.notoc, other.chaptype, other.properties]
|
58
|
+
end
|
59
|
+
|
60
|
+
def coverimage?(imagefile)
|
61
|
+
self.media.start_with?('image') && self.file =~ /#{imagefile}\Z/
|
62
|
+
end
|
63
|
+
|
64
|
+
def properties_attribute
|
65
|
+
if self.properties.size > 0
|
66
|
+
%Q( properties="#{self.properties.sort.uniq.join(' ')}")
|
67
|
+
else
|
68
|
+
''
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Complement other parameters by using file parameter.
|
75
|
+
def complement
|
76
|
+
if @id.nil?
|
77
|
+
@id = @file.gsub(%r{[\\/. ]}, '-')
|
78
|
+
end
|
79
|
+
if @id =~ /\A[^a-z]/i
|
80
|
+
@id = "rv-#{@id}"
|
81
|
+
end
|
82
|
+
@id = CGI.escape(@id).gsub('%', '_25_')
|
83
|
+
|
84
|
+
if !@file.nil? && @media.nil?
|
85
|
+
@media = @file.sub(/.+\./, '').downcase
|
86
|
+
end
|
87
|
+
|
88
|
+
case @media
|
89
|
+
when 'xhtml', 'xml', 'html'
|
90
|
+
@media = 'application/xhtml+xml'
|
91
|
+
when 'css'
|
92
|
+
@media = 'text/css'
|
93
|
+
when 'jpg', 'jpeg', 'image/jpg'
|
94
|
+
@media = 'image/jpeg'
|
95
|
+
when 'png'
|
96
|
+
@media = 'image/png'
|
97
|
+
when 'gif'
|
98
|
+
@media = 'image/gif'
|
99
|
+
when 'svg', 'image/svg'
|
100
|
+
@media = 'image/svg+xml'
|
101
|
+
when 'ttf', 'otf'
|
102
|
+
@media = 'application/vnd.ms-opentype'
|
103
|
+
when 'woff'
|
104
|
+
@media = 'application/font-woff'
|
105
|
+
end
|
106
|
+
|
107
|
+
if @id.nil? || @file.nil? || @media.nil?
|
108
|
+
raise "Type error: #{id}, #{file}, #{media}, #{title}, #{notoc}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,372 @@
|
|
1
|
+
# = epubcommon.rb -- super class for EPUBv2 and EPUBv3
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010-2019 Kenshi Muto and Masayoshi Takahashi
|
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
|
+
# For details of the GNU LGPL, see the file "COPYING".
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'review/i18n'
|
12
|
+
require 'review/template'
|
13
|
+
begin
|
14
|
+
require 'cgi/escape'
|
15
|
+
rescue LoadError
|
16
|
+
require 'cgi/util'
|
17
|
+
end
|
18
|
+
|
19
|
+
module ReVIEW
|
20
|
+
class EPUBMaker
|
21
|
+
# EPUBCommon is the common class for EPUB producer.
|
22
|
+
# Some methods of this class are overridden by subclasses
|
23
|
+
class EPUBCommon
|
24
|
+
# Construct object with parameter hash +config+ and message resource hash +res+.
|
25
|
+
def initialize(producer)
|
26
|
+
@config = producer.config
|
27
|
+
@contents = producer.contents
|
28
|
+
@body_ext = nil
|
29
|
+
@logger = ReVIEW.logger
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :config
|
33
|
+
attr_reader :contents
|
34
|
+
|
35
|
+
def h(str)
|
36
|
+
CGI.escapeHTML(str)
|
37
|
+
end
|
38
|
+
|
39
|
+
def produce(epubfile, basedir, tmpdir)
|
40
|
+
raise NotImplementedError # should be overridden
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return mimetype content.
|
44
|
+
def mimetype
|
45
|
+
'application/epub+zip'
|
46
|
+
end
|
47
|
+
|
48
|
+
def opf
|
49
|
+
raise NotImplementedError # should be overridden
|
50
|
+
end
|
51
|
+
|
52
|
+
def opf_manifest
|
53
|
+
raise NotImplementedError # should be overridden
|
54
|
+
end
|
55
|
+
|
56
|
+
def opf_metainfo
|
57
|
+
raise NotImplementedError # should be overridden
|
58
|
+
end
|
59
|
+
|
60
|
+
def opf_tocx
|
61
|
+
raise NotImplementedError # should be overridden
|
62
|
+
end
|
63
|
+
|
64
|
+
def opf_path
|
65
|
+
"OEBPS/#{config['bookname']}.opf"
|
66
|
+
end
|
67
|
+
|
68
|
+
def opf_coverimage
|
69
|
+
if config['coverimage']
|
70
|
+
item = contents.find { |content| content.coverimage?(config['coverimage']) }
|
71
|
+
|
72
|
+
unless item
|
73
|
+
raise "coverimage #{config['coverimage']} not found. Abort."
|
74
|
+
end
|
75
|
+
|
76
|
+
%Q( <meta name="cover" content="#{item.id}"/>\n)
|
77
|
+
else
|
78
|
+
''
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def ncx(indentarray)
|
83
|
+
raise NotImplementedError # should be overridden
|
84
|
+
end
|
85
|
+
|
86
|
+
# Return container content.
|
87
|
+
def container
|
88
|
+
@opf_path = opf_path
|
89
|
+
ReVIEW::Template.generate(path: './xml/container.xml.erb', binding: binding)
|
90
|
+
end
|
91
|
+
|
92
|
+
def coverimage
|
93
|
+
return nil unless config['coverimage']
|
94
|
+
|
95
|
+
item = contents.find { |content| content.coverimage?(config['coverimage']) }
|
96
|
+
|
97
|
+
if item
|
98
|
+
item.file
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Return cover content.
|
103
|
+
# If Producer#config["coverimage"] is defined, it will be used for
|
104
|
+
# the cover image.
|
105
|
+
def cover
|
106
|
+
@body_ext = config['epubversion'] >= 3 ? %Q( epub:type="cover") : ''
|
107
|
+
|
108
|
+
if config['coverimage']
|
109
|
+
@coverimage_src = coverimage
|
110
|
+
raise "coverimage #{config['coverimage']} not found. Abort." unless @coverimage_src
|
111
|
+
end
|
112
|
+
@body = ReVIEW::Template.generate(path: './html/_cover.html.erb', binding: binding)
|
113
|
+
|
114
|
+
@title = h(config.name_of('title'))
|
115
|
+
@language = config['language']
|
116
|
+
@stylesheets = config['stylesheet']
|
117
|
+
template_path = if config['htmlversion'].to_i == 5
|
118
|
+
'./html/layout-html5.html.erb'
|
119
|
+
else
|
120
|
+
'./html/layout-xhtml1.html.erb'
|
121
|
+
end
|
122
|
+
ReVIEW::Template.generate(path: template_path, binding: binding)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Return title (copying) content.
|
126
|
+
# NOTE: this method is not used yet.
|
127
|
+
# see lib/review/epubmaker.rb#build_titlepage
|
128
|
+
def titlepage
|
129
|
+
@title = h(config.name_of('title'))
|
130
|
+
|
131
|
+
@title_str = config.name_of('title')
|
132
|
+
if config['subtitle']
|
133
|
+
@subtitle_str = config.name_of('subtitle')
|
134
|
+
end
|
135
|
+
if config['aut']
|
136
|
+
@author_str = join_with_separator(config.names_of('aut'), ReVIEW::I18n.t('names_splitter'))
|
137
|
+
end
|
138
|
+
if config.names_of('pbl')
|
139
|
+
@publisher_str = join_with_separator(config.names_of('pbl'), ReVIEW::I18n.t('names_splitter'))
|
140
|
+
end
|
141
|
+
@body = ReVIEW::Template.generate(path: './html/_titlepage.html.erb', binding: binding)
|
142
|
+
|
143
|
+
@language = config['language']
|
144
|
+
@stylesheets = config['stylesheet']
|
145
|
+
template_path = if config['htmlversion'].to_i == 5
|
146
|
+
'./html/layout-html5.html.erb'
|
147
|
+
else
|
148
|
+
'./html/layout-xhtml1.html.erb'
|
149
|
+
end
|
150
|
+
ReVIEW::Template.generate(path: template_path, binding: binding)
|
151
|
+
end
|
152
|
+
|
153
|
+
# Return colophon content.
|
154
|
+
def colophon
|
155
|
+
@title = h(ReVIEW::I18n.t('colophontitle'))
|
156
|
+
@isbn_hyphen = isbn_hyphen
|
157
|
+
|
158
|
+
@body = ReVIEW::Template.generate(path: './html/_colophon.html.erb', binding: binding)
|
159
|
+
|
160
|
+
@language = config['language']
|
161
|
+
@stylesheets = config['stylesheet']
|
162
|
+
template_path = if config['htmlversion'].to_i == 5
|
163
|
+
'./html/layout-html5.html.erb'
|
164
|
+
else
|
165
|
+
'./html/layout-xhtml1.html.erb'
|
166
|
+
end
|
167
|
+
ReVIEW::Template.generate(path: template_path, binding: binding)
|
168
|
+
end
|
169
|
+
|
170
|
+
def isbn_hyphen
|
171
|
+
str = config['isbn'].to_s
|
172
|
+
|
173
|
+
if str =~ /\A\d{10}\Z/
|
174
|
+
"#{str[0..0]}-#{str[1..5]}-#{str[6..8]}-#{str[9..9]}"
|
175
|
+
elsif str =~ /\A\d{13}\Z/
|
176
|
+
"#{str[0..2]}-#{str[3..3]}-#{str[4..8]}-#{str[9..11]}-#{str[12..12]}"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def colophon_history
|
181
|
+
@col_history = []
|
182
|
+
if config['history']
|
183
|
+
config['history'].each_with_index do |items, edit|
|
184
|
+
items.each_with_index do |item, rev|
|
185
|
+
editstr = edit == 0 ? ReVIEW::I18n.t('first_edition') : ReVIEW::I18n.t('nth_edition', (edit + 1).to_s)
|
186
|
+
revstr = ReVIEW::I18n.t('nth_impression', (rev + 1).to_s)
|
187
|
+
if item =~ /\A\d+-\d+-\d+\Z/
|
188
|
+
@col_history << ReVIEW::I18n.t('published_by1', [date_to_s(item), editstr + revstr])
|
189
|
+
elsif item =~ /\A(\d+-\d+-\d+)[\s ](.+)/
|
190
|
+
# custom date with string
|
191
|
+
item.match(/\A(\d+-\d+-\d+)[\s ](.+)/) do |m|
|
192
|
+
@col_history << ReVIEW::I18n.t('published_by3', [date_to_s(m[1]), m[2]])
|
193
|
+
end
|
194
|
+
else
|
195
|
+
# free format
|
196
|
+
@col_history << item
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
ReVIEW::Template.generate(path: './html/_colophon_history.html.erb', binding: binding)
|
203
|
+
end
|
204
|
+
|
205
|
+
def date_to_s(date)
|
206
|
+
require 'date'
|
207
|
+
d = Date.parse(date)
|
208
|
+
d.strftime(ReVIEW::I18n.t('date_format'))
|
209
|
+
end
|
210
|
+
|
211
|
+
# Return own toc content.
|
212
|
+
def mytoc
|
213
|
+
@title = h(ReVIEW::I18n.t('toctitle'))
|
214
|
+
|
215
|
+
@body = %Q( <h1 class="toc-title">#{h(ReVIEW::I18n.t('toctitle'))}</h1>\n)
|
216
|
+
if config['epubmaker']['flattoc'].nil?
|
217
|
+
@body << hierarchy_ncx('ul')
|
218
|
+
else
|
219
|
+
@body << flat_ncx('ul', config['epubmaker']['flattocindent'])
|
220
|
+
end
|
221
|
+
|
222
|
+
@language = config['language']
|
223
|
+
@stylesheets = config['stylesheet']
|
224
|
+
template_path = if config['htmlversion'].to_i == 5
|
225
|
+
'./html/layout-html5.html.erb'
|
226
|
+
else
|
227
|
+
'./html/layout-xhtml1.html.erb'
|
228
|
+
end
|
229
|
+
ReVIEW::Template.generate(path: template_path, binding: binding)
|
230
|
+
end
|
231
|
+
|
232
|
+
def hierarchy_ncx(type)
|
233
|
+
require 'rexml/document'
|
234
|
+
level = 1
|
235
|
+
find_jump = nil
|
236
|
+
has_part = nil
|
237
|
+
toclevel = config['toclevel'].to_i
|
238
|
+
|
239
|
+
# check part existance
|
240
|
+
contents.each do |item|
|
241
|
+
next if item.notoc || item.chaptype != 'part'
|
242
|
+
|
243
|
+
has_part = true
|
244
|
+
break
|
245
|
+
end
|
246
|
+
|
247
|
+
if has_part
|
248
|
+
contents.each do |item|
|
249
|
+
if item.chaptype == 'part' && item.level > 0
|
250
|
+
# sections in part
|
251
|
+
item.level -= 1
|
252
|
+
end
|
253
|
+
# down level for part and chaps. pre, appendix, post are preserved
|
254
|
+
if item.chaptype == 'part' || item.chaptype == 'body'
|
255
|
+
item.level += 1
|
256
|
+
end
|
257
|
+
end
|
258
|
+
toclevel += 1
|
259
|
+
end
|
260
|
+
|
261
|
+
doc = REXML::Document.new(%Q(<#{type} class="toc-h#{level}"><li /></#{type}>))
|
262
|
+
doc.context[:attribute_quote] = :quote
|
263
|
+
|
264
|
+
e = doc.root.elements[1] # first <li/>
|
265
|
+
contents.each do |item|
|
266
|
+
next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > toclevel
|
267
|
+
|
268
|
+
if item.level == level
|
269
|
+
e2 = e.parent.add_element('li')
|
270
|
+
e = e2
|
271
|
+
elsif item.level > level
|
272
|
+
find_jump = true if (item.level - level) > 1
|
273
|
+
# deeper
|
274
|
+
(level + 1).upto(item.level) do |n|
|
275
|
+
if e.size == 0
|
276
|
+
# empty span for epubcheck
|
277
|
+
e.attributes['style'] = 'list-style-type: none;'
|
278
|
+
es = e.add_element('span', 'style' => 'display:none;')
|
279
|
+
es.add_text(REXML::Text.new(' ', false, nil, true))
|
280
|
+
end
|
281
|
+
|
282
|
+
e2 = e.add_element(type, 'class' => "toc-h#{n}")
|
283
|
+
e3 = e2.add_element('li')
|
284
|
+
e = e3
|
285
|
+
end
|
286
|
+
level = item.level
|
287
|
+
elsif item.level < level
|
288
|
+
# shallower
|
289
|
+
(level - 1).downto(item.level) { e = e.parent.parent }
|
290
|
+
e2 = e.parent.add_element('li')
|
291
|
+
e = e2
|
292
|
+
level = item.level
|
293
|
+
end
|
294
|
+
e2 = e.add_element('a', 'href' => item.file)
|
295
|
+
e2.add_text(REXML::Text.new(item.title, true))
|
296
|
+
end
|
297
|
+
|
298
|
+
warn %Q(found level jumping in table of contents. consider to use 'epubmaker:flattoc: true' for strict ePUB validator.) unless find_jump.nil?
|
299
|
+
|
300
|
+
doc.to_s.gsub('<li/>', '').gsub('</li>', "</li>\n").gsub("<#{type} ", "\n" + '\&') # ugly
|
301
|
+
end
|
302
|
+
|
303
|
+
def flat_ncx(type, indent = nil)
|
304
|
+
s = %Q(<#{type} class="toc-h1">\n)
|
305
|
+
contents.each do |item|
|
306
|
+
next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > config['toclevel'].to_i
|
307
|
+
|
308
|
+
is = indent == true ? ' ' * item.level : ''
|
309
|
+
s << %Q(<li><a href="#{item.file}">#{is}#{h(item.title)}</a></li>\n)
|
310
|
+
end
|
311
|
+
s << %Q(</#{type}>\n)
|
312
|
+
|
313
|
+
s
|
314
|
+
end
|
315
|
+
|
316
|
+
def produce_write_common(basedir, tmpdir)
|
317
|
+
File.write("#{tmpdir}/mimetype", mimetype)
|
318
|
+
|
319
|
+
FileUtils.mkdir_p("#{tmpdir}/META-INF")
|
320
|
+
File.write("#{tmpdir}/META-INF/container.xml", container)
|
321
|
+
|
322
|
+
FileUtils.mkdir_p("#{tmpdir}/OEBPS")
|
323
|
+
File.write(File.join(tmpdir, opf_path), opf)
|
324
|
+
|
325
|
+
if File.exist?("#{basedir}/#{config['cover']}")
|
326
|
+
FileUtils.cp("#{basedir}/#{config['cover']}", "#{tmpdir}/OEBPS")
|
327
|
+
else
|
328
|
+
File.write("#{tmpdir}/OEBPS/#{config['cover']}", cover)
|
329
|
+
end
|
330
|
+
|
331
|
+
if config['colophon'] && !config['colophon'].is_a?(String)
|
332
|
+
filename = File.join(basedir, "colophon.#{config['htmlext']}")
|
333
|
+
File.write(filename, colophon)
|
334
|
+
end
|
335
|
+
|
336
|
+
contents.each do |item|
|
337
|
+
next if item.file =~ /#/ # skip subgroup
|
338
|
+
|
339
|
+
fname = "#{basedir}/#{item.file}"
|
340
|
+
unless File.exist?(fname)
|
341
|
+
raise "#{fname} is not found."
|
342
|
+
end
|
343
|
+
|
344
|
+
FileUtils.mkdir_p(File.dirname("#{tmpdir}/OEBPS/#{item.file}"))
|
345
|
+
FileUtils.cp(fname, "#{tmpdir}/OEBPS/#{item.file}")
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def call_hook(filename, *params)
|
350
|
+
return if !filename.present? || !File.exist?(filename) || !FileTest.executable?(filename)
|
351
|
+
|
352
|
+
if ENV['REVIEW_SAFE_MODE'].to_i & 1 > 0
|
353
|
+
warn 'hook is prohibited in safe mode. ignored.'
|
354
|
+
else
|
355
|
+
system(filename, *params)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def legacy_cover_and_title_file(loadfile, writefile)
|
360
|
+
FileUtils.cp(loadfile, writefile)
|
361
|
+
end
|
362
|
+
|
363
|
+
def join_with_separator(value, sep)
|
364
|
+
if value.is_a?(Array)
|
365
|
+
value.join(sep)
|
366
|
+
else
|
367
|
+
value
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|