review 5.0.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tex.yml +31 -0
  3. data/.github/workflows/ruby-win.yml +3 -3
  4. data/.github/workflows/ruby.yml +1 -1
  5. data/.rubocop.yml +15 -7
  6. data/NEWS.ja.md +108 -0
  7. data/NEWS.md +108 -0
  8. data/README.md +7 -6
  9. data/Rakefile +7 -2
  10. data/bin/review +2 -4
  11. data/bin/review-catalog-converter +3 -3
  12. data/bin/review-check +6 -8
  13. data/bin/review-checkdep +1 -4
  14. data/bin/review-compile +2 -5
  15. data/bin/review-epub2html +1 -4
  16. data/bin/review-epubmaker +3 -4
  17. data/bin/review-idgxmlmaker +1 -3
  18. data/bin/review-index +11 -5
  19. data/bin/review-init +1 -4
  20. data/bin/review-pdfmaker +1 -3
  21. data/bin/review-preproc +2 -4
  22. data/bin/review-textmaker +1 -3
  23. data/bin/review-update +1 -4
  24. data/bin/review-validate +3 -3
  25. data/bin/review-vol +1 -4
  26. data/bin/review-webmaker +1 -3
  27. data/doc/config.yml.sample +21 -5
  28. data/doc/config.yml.sample-simple +1 -1
  29. data/doc/format.ja.md +21 -10
  30. data/doc/format.md +21 -10
  31. data/doc/quickstart.ja.md +11 -1
  32. data/doc/quickstart.md +11 -2
  33. data/lib/review.rb +1 -1
  34. data/lib/review/book/base.rb +4 -0
  35. data/lib/review/book/book_unit.rb +3 -0
  36. data/lib/review/book/chapter.rb +3 -0
  37. data/lib/review/book/index.rb +1 -0
  38. data/lib/review/book/volume.rb +1 -0
  39. data/lib/review/builder.rb +8 -1
  40. data/lib/review/call_hook.rb +20 -0
  41. data/lib/review/catalog.rb +1 -0
  42. data/lib/review/compiler.rb +27 -10
  43. data/lib/review/configure.rb +64 -7
  44. data/lib/review/epubmaker.rb +93 -96
  45. data/lib/review/epubmaker/content.rb +113 -0
  46. data/lib/review/epubmaker/epubcommon.rb +372 -0
  47. data/lib/review/epubmaker/epubv2.rb +178 -0
  48. data/lib/review/epubmaker/epubv3.rb +231 -0
  49. data/lib/review/epubmaker/producer.rb +168 -0
  50. data/lib/review/epubmaker/reviewheaderlistener.rb +12 -2
  51. data/lib/review/epubmaker/zip_exporter.rb +84 -0
  52. data/lib/review/exception.rb +6 -0
  53. data/lib/review/htmlbuilder.rb +36 -49
  54. data/lib/review/htmlutils.rb +1 -1
  55. data/lib/review/i18n.rb +1 -0
  56. data/lib/review/idgxmlbuilder.rb +33 -30
  57. data/lib/review/idgxmlmaker.rb +3 -1
  58. data/lib/review/img_math.rb +245 -0
  59. data/lib/review/index_builder.rb +1 -0
  60. data/lib/review/init.rb +4 -4
  61. data/lib/review/latexbox.rb +58 -0
  62. data/lib/review/latexbuilder.rb +30 -19
  63. data/lib/review/latexutils.rb +9 -1
  64. data/lib/review/lineinput.rb +112 -2
  65. data/lib/review/logger.rb +41 -2
  66. data/lib/review/makerhelper.rb +2 -205
  67. data/lib/review/markdownbuilder.rb +32 -1
  68. data/lib/review/pdfmaker.rb +31 -29
  69. data/lib/review/plaintextbuilder.rb +9 -1
  70. data/lib/review/preprocessor.rb +12 -6
  71. data/lib/review/rstbuilder.rb +1 -1
  72. data/lib/review/sec_counter.rb +1 -0
  73. data/lib/review/template.rb +6 -0
  74. data/lib/review/textmaker.rb +11 -7
  75. data/lib/review/textutils.rb +2 -10
  76. data/lib/review/tocprinter.rb +85 -68
  77. data/lib/review/topbuilder.rb +18 -11
  78. data/lib/review/update.rb +5 -6
  79. data/lib/review/version.rb +1 -1
  80. data/lib/review/volumeprinter.rb +4 -5
  81. data/lib/review/webmaker.rb +18 -13
  82. data/lib/review/webtocprinter.rb +10 -9
  83. data/lib/review/yamlloader.rb +2 -1
  84. data/review.gemspec +5 -3
  85. data/samples/sample-book/src/config-epub2.yml +1 -1
  86. data/samples/sample-book/src/config.yml +1 -1
  87. data/samples/sample-book/src/lib/tasks/review.rake +17 -1
  88. data/samples/syntax-book/ch01.re +1 -1
  89. data/samples/syntax-book/ch02.re +21 -6
  90. data/samples/syntax-book/ch03.re +1 -1
  91. data/samples/syntax-book/images/img3-2.png +0 -0
  92. data/templates/html/_colophon.html.erb +23 -0
  93. data/templates/html/_colophon_history.html.erb +9 -0
  94. data/templates/html/_cover.html.erb +10 -0
  95. data/templates/html/_part_body.html.erb +6 -0
  96. data/templates/html/_titlepage.html.erb +20 -0
  97. data/templates/html/layout-html5.html.erb +6 -0
  98. data/templates/html/layout-xhtml1.html.erb +6 -0
  99. data/templates/latex/config.erb +8 -0
  100. data/templates/latex/review-jlreq/review-base.sty +4 -5
  101. data/templates/latex/review-jlreq/review-jlreq.cls +10 -2
  102. data/templates/latex/review-jlreq/review-style.sty +6 -1
  103. data/templates/latex/review-jlreq/review-tcbox.sty +348 -0
  104. data/templates/latex/review-jlreq/reviewmacro.sty +5 -0
  105. data/templates/latex/review-jsbook/review-base.sty +5 -7
  106. data/templates/latex/review-jsbook/review-jsbook.cls +10 -2
  107. data/templates/latex/review-jsbook/review-style.sty +6 -1
  108. data/templates/latex/review-jsbook/review-tcbox.sty +348 -0
  109. data/templates/latex/review-jsbook/reviewmacro.sty +5 -0
  110. data/templates/opf/epubv2.opf.erb +7 -7
  111. data/templates/opf/epubv3.opf.erb +7 -7
  112. data/templates/opf/opf_manifest_epubv2.opf.erb +10 -0
  113. data/templates/opf/opf_manifest_epubv3.opf.erb +10 -0
  114. data/templates/opf/opf_metainfo_epubv2.opf.erb +17 -0
  115. data/templates/opf/opf_metainfo_epubv3.opf.erb +49 -0
  116. data/templates/opf/opf_tocx_epubv2.opf.erb +9 -0
  117. data/templates/opf/opf_tocx_epubv3.opf.erb +17 -0
  118. data/templates/web/html/layout-html5.html.erb +6 -5
  119. data/templates/web/html/layout-xhtml1.html.erb +6 -0
  120. data/test/assets/header_listener.html +35 -0
  121. data/test/assets/img_math/img1.png +0 -0
  122. data/test/assets/img_math/img2.png +0 -0
  123. data/test/assets/img_math/img3.png +0 -0
  124. data/test/assets/syntax_book_index_detail.txt +58 -0
  125. data/test/assets/test_template.tex +4 -1
  126. data/test/assets/test_template_backmatter.tex +4 -1
  127. data/test/run_test.rb +1 -1
  128. data/test/test_book_chapter.rb +2 -2
  129. data/test/test_catalog_converter_cmd.rb +1 -1
  130. data/test/test_epub3maker.rb +168 -124
  131. data/test/test_epubmaker.rb +243 -131
  132. data/test/test_epubmaker_cmd.rb +2 -2
  133. data/test/test_helper.rb +5 -4
  134. data/test/test_htmlbuilder.rb +64 -6
  135. data/test/test_idgxmlbuilder.rb +13 -0
  136. data/test/test_idgxmlmaker_cmd.rb +7 -3
  137. data/test/test_img_math.rb +111 -0
  138. data/test/test_indexbuilder.rb +5 -5
  139. data/test/test_latexbuilder.rb +107 -4
  140. data/test/test_lineinput.rb +20 -93
  141. data/test/test_markdownbuilder.rb +29 -0
  142. data/test/test_pdfmaker.rb +71 -0
  143. data/test/test_pdfmaker_cmd.rb +2 -2
  144. data/test/test_plaintextbuilder.rb +10 -18
  145. data/test/test_reviewheaderlistener.rb +49 -0
  146. data/test/test_template.rb +12 -2
  147. data/test/test_textmaker_cmd.rb +5 -1
  148. data/test/test_tocprinter.rb +46 -0
  149. data/test/test_topbuilder.rb +6 -1
  150. data/test/test_update.rb +34 -34
  151. data/test/test_zip_exporter.rb +5 -6
  152. metadata +91 -17
  153. data/lib/epubmaker.rb +0 -23
  154. data/lib/epubmaker/content.rb +0 -111
  155. data/lib/epubmaker/epubcommon.rb +0 -449
  156. data/lib/epubmaker/epubv2.rb +0 -142
  157. data/lib/epubmaker/epubv3.rb +0 -235
  158. data/lib/epubmaker/producer.rb +0 -375
  159. data/lib/epubmaker/zip_exporter.rb +0 -81
  160. data/lib/lineinput.rb +0 -155
data/lib/epubmaker.rb DELETED
@@ -1,23 +0,0 @@
1
- # = epubmaker.rb -- EPUB production set.
2
- #
3
- # Copyright (c) 2010-2017 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
- # == Quick usage
11
- # require 'epubmaker'
12
- # producer = EPUBMaker::Producer.new
13
- # config = producer.load("config.yml")
14
- # producer.contents.push(EPUBMaker::Content.new({"file" => "ch01.xhtml"}))
15
- # producer.contents.push(EPUBMaker::Content.new({"file" => "ch02.xhtml"}))
16
- # ...
17
- # producer.import_imageinfo("images")
18
- # producer.produce
19
-
20
- require 'epubmaker/producer'
21
- require 'epubmaker/content'
22
- require 'epubmaker/epubv2'
23
- require 'epubmaker/epubv3'
@@ -1,111 +0,0 @@
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 EPUBMaker
12
- # EPUBMaker::Content represents a content data for EPUBMaker.
13
- # EPUBMaker#contents takes an array of Content.
14
- class Content
15
- # ID
16
- attr_accessor :id
17
- # File path (will accept #<anchor> suffix also)
18
- attr_accessor :file
19
- # MIME type
20
- attr_accessor :media
21
- # Title
22
- attr_accessor :title
23
- # Header level (from 1)
24
- attr_accessor :level
25
- # Show in TOC? nil:No.
26
- attr_accessor :notoc
27
- # Properties (EPUB3)
28
- attr_accessor :properties
29
- # Chapter type (pre/post/part/nil(body))
30
- attr_accessor :chaptype
31
-
32
- def inspect
33
- "<Content id=#{@id}, file=#{@file}, media=#{@media}, title=#{@title}, level=#{@level}, notoc=#{@notoc}, properties=#{@properties}, chaptype=#{@chaptype}>"
34
- end
35
-
36
- # :call-seq:
37
- # initialize(file, id, media, title, level, notoc)
38
- # initialize(hash)
39
- # Construct Content object by passing a sequence of parameters or hash.
40
- # Keys of +hash+ relate with each parameters.
41
- # +file+ (or +hash+["file"]) is required. Others are optional.
42
- def initialize(fileorhash, id = nil, media = nil, title = nil, level = nil, notoc = nil, properties = nil, chaptype = nil)
43
- if fileorhash.instance_of?(Hash)
44
- @id = fileorhash['id']
45
- @file = fileorhash['file']
46
- @media = fileorhash['media']
47
- @title = fileorhash['title']
48
- @level = fileorhash['level']
49
- @notoc = fileorhash['notoc']
50
- @properties = fileorhash['properties'] || []
51
- @chaptype = fileorhash['chaptype']
52
- else
53
- @file = fileorhash
54
- @id = id
55
- @media = media
56
- @title = title
57
- @level = level
58
- @notoc = notoc
59
- @properties = properties || []
60
- @chaptype = chaptype
61
- end
62
- complement
63
- end
64
-
65
- def ==(other)
66
- return false unless self.class == other.class
67
- [self.id, self.file, self.media, self.title, self.level, self.notoc, self.chaptype, self.properties] ==
68
- [other.id, other.file, other.media, other.title, other.level, other.notoc, other.chaptype, other.properties]
69
- end
70
-
71
- private
72
-
73
- # Complement other parameters by using file parameter.
74
- def complement
75
- if @id.nil?
76
- @id = @file.gsub(%r{[\\/. ]}, '-')
77
- end
78
- if @id =~ /\A[^a-z]/i
79
- @id = "rv-#{@id}"
80
- end
81
- @id = CGI.escape(@id).gsub('%', '_25_')
82
-
83
- if !@file.nil? && @media.nil?
84
- @media = @file.sub(/.+\./, '').downcase
85
- end
86
-
87
- case @media
88
- when 'xhtml', 'xml', 'html'
89
- @media = 'application/xhtml+xml'
90
- when 'css'
91
- @media = 'text/css'
92
- when 'jpg', 'jpeg', 'image/jpg'
93
- @media = 'image/jpeg'
94
- when 'png'
95
- @media = 'image/png'
96
- when 'gif'
97
- @media = 'image/gif'
98
- when 'svg', 'image/svg'
99
- @media = 'image/svg+xml'
100
- when 'ttf', 'otf'
101
- @media = 'application/vnd.ms-opentype'
102
- when 'woff'
103
- @media = 'application/font-woff'
104
- end
105
-
106
- if @id.nil? || @file.nil? || @media.nil?
107
- raise "Type error: #{id}, #{file}, #{media}, #{title}, #{notoc}"
108
- end
109
- end
110
- end
111
- end
@@ -1,449 +0,0 @@
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 EPUBMaker
20
- # EPUBCommon is the common class for EPUB producer.
21
- class EPUBCommon
22
- # Construct object with parameter hash +config+ and message resource hash +res+.
23
- def initialize(producer)
24
- @body_ext = ''
25
- @producer = producer
26
- @body_ext = nil
27
- end
28
-
29
- def h(str)
30
- CGI.escapeHTML(str)
31
- end
32
-
33
- # Return mimetype content.
34
- def mimetype
35
- 'application/epub+zip'
36
- end
37
-
38
- def opf_path
39
- "OEBPS/#{@producer.config['bookname']}.opf"
40
- end
41
-
42
- def opf_coverimage
43
- s = ''
44
- if @producer.config['coverimage']
45
- file = nil
46
- @producer.contents.each do |item|
47
- if !item.media.start_with?('image') || item.file !~ /#{@producer.config['coverimage']}\Z/
48
- next
49
- end
50
- s << %Q( <meta name="cover" content="#{item.id}"/>\n)
51
- file = item.file
52
- break
53
- end
54
-
55
- if file.nil?
56
- raise "coverimage #{@producer.config['coverimage']} not found. Abort."
57
- end
58
- end
59
- s
60
- end
61
-
62
- def ncx_isbn
63
- uid = @producer.config['isbn'] || @producer.config['urnid']
64
- %Q( <meta name="dtb:uid" content="#{uid}"/>\n)
65
- end
66
-
67
- def ncx_doctitle
68
- <<EOT
69
- <docTitle>
70
- <text>#{h(@producer.config['title'])}</text>
71
- </docTitle>
72
- <docAuthor>
73
- <text>#{@producer.config['aut'].nil? ? '' : h(join_with_separator(@producer.config['aut'], ReVIEW::I18n.t('names_splitter')))}</text>
74
- </docAuthor>
75
- EOT
76
- end
77
-
78
- def ncx_navmap(indentarray)
79
- s = <<EOT
80
- <navMap>
81
- <navPoint id="top" playOrder="1">
82
- <navLabel>
83
- <text>#{h(@producer.config['title'])}</text>
84
- </navLabel>
85
- <content src="#{@producer.config['cover']}"/>
86
- </navPoint>
87
- EOT
88
-
89
- nav_count = 2
90
-
91
- unless @producer.config['mytoc'].nil?
92
- s << <<EOT
93
- <navPoint id="toc" playOrder="#{nav_count}">
94
- <navLabel>
95
- <text>#{h(@producer.res.v('toctitle'))}</text>
96
- </navLabel>
97
- <content src="#{@producer.config['bookname']}-toc.#{@producer.config['htmlext']}"/>
98
- </navPoint>
99
- EOT
100
- nav_count += 1
101
- end
102
-
103
- @producer.contents.each do |item|
104
- next if item.title.nil?
105
- indent = indentarray.nil? ? [''] : indentarray
106
- level = item.level.nil? ? 0 : (item.level - 1)
107
- level = indent.size - 1 if level >= indent.size
108
- s << <<EOT
109
- <navPoint id="nav-#{nav_count}" playOrder="#{nav_count}">
110
- <navLabel>
111
- <text>#{indent[level]}#{h(item.title)}</text>
112
- </navLabel>
113
- <content src="#{item.file}"/>
114
- </navPoint>
115
- EOT
116
- nav_count += 1
117
- end
118
-
119
- s << <<EOT
120
- </navMap>
121
- EOT
122
- s
123
- end
124
-
125
- # Return container content.
126
- def container
127
- @opf_path = opf_path
128
- tmplfile = File.expand_path('./xml/container.xml.erb', ReVIEW::Template::TEMPLATE_DIR)
129
- tmpl = ReVIEW::Template.load(tmplfile)
130
- tmpl.result(binding)
131
- end
132
-
133
- # Return cover content.
134
- def cover(type = nil)
135
- @body_ext = type.nil? ? '' : %Q( epub:type="#{type}")
136
-
137
- if @producer.config['coverimage']
138
- file = @producer.coverimage
139
- raise "coverimage #{@producer.config['coverimage']} not found. Abort." unless file
140
- @body = <<-EOT
141
- <div id="cover-image" class="cover-image">
142
- <img src="#{file}" alt="#{h(@producer.config.name_of('title'))}" class="max"/>
143
- </div>
144
- EOT
145
- else
146
- @body = <<-EOT
147
- <h1 class="cover-title">#{h(@producer.config.name_of('title'))}</h1>
148
- EOT
149
- if @producer.config['subtitle']
150
- @body << <<-EOT
151
- <h2 class="cover-subtitle">#{h(@producer.config.name_of('subtitle'))}</h2>
152
- EOT
153
- end
154
- end
155
-
156
- @title = h(@producer.config.name_of('title'))
157
- @language = @producer.config['language']
158
- @stylesheets = @producer.config['stylesheet']
159
- tmplfile = if @producer.config['htmlversion'].to_i == 5
160
- File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
161
- else
162
- File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
163
- end
164
- tmpl = ReVIEW::Template.load(tmplfile)
165
- tmpl.result(binding)
166
- end
167
-
168
- # Return title (copying) content.
169
- # NOTE: this method is not used yet.
170
- # see lib/review/epubmaker.rb#build_titlepage
171
- def titlepage
172
- @title = h(@producer.config.name_of('title'))
173
-
174
- @body = <<EOT
175
- <h1 class="tp-title">#{@title}</h1>
176
- EOT
177
-
178
- if @producer.config['subtitle']
179
- @body << <<EOT
180
- <h2 class="tp-subtitle">#{h(@producer.config.name_of('subtitle'))}</h2>
181
- EOT
182
- end
183
-
184
- if @producer.config['aut']
185
- @body << <<EOT
186
- <p>
187
- <br />
188
- <br />
189
- </p>
190
- <h2 class="tp-author">#{h(join_with_separator(@producer.config.names_of('aut'), ReVIEW::I18n.t('names_splitter')))}</h2>
191
- EOT
192
- end
193
-
194
- publisher = @producer.config.names_of('pbl')
195
- if publisher
196
- @body << <<EOT
197
- <p>
198
- <br />
199
- <br />
200
- <br />
201
- <br />
202
- </p>
203
- <h3 class="tp-publisher">#{h(join_with_separator(publisher, ReVIEW::I18n.t('names_splitter')))}</h3>
204
- EOT
205
- end
206
-
207
- @language = @producer.config['language']
208
- @stylesheets = @producer.config['stylesheet']
209
- tmplfile = if @producer.config['htmlversion'].to_i == 5
210
- File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
211
- else
212
- File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
213
- end
214
- tmpl = ReVIEW::Template.load(tmplfile)
215
- tmpl.result(binding)
216
- end
217
-
218
- # Return colophon content.
219
- def colophon
220
- @title = h(@producer.res.v('colophontitle'))
221
- @body = <<EOT
222
- <div class="colophon">
223
- EOT
224
-
225
- if @producer.config['subtitle'].nil?
226
- @body << <<EOT
227
- <p class="title">#{h(@producer.config.name_of('title'))}</p>
228
- EOT
229
- else
230
- @body << <<EOT
231
- <p class="title">#{h(@producer.config.name_of('title'))}<br /><span class="subtitle">#{h(@producer.config.name_of('subtitle'))}</span></p>
232
- EOT
233
- end
234
-
235
- @body << colophon_history if @producer.config['date'] || @producer.config['history']
236
-
237
- @body << %Q( <table class="colophon">\n)
238
- @body << @producer.config['colophon_order'].map do |role|
239
- if @producer.config[role]
240
- %Q( <tr><th>#{h(@producer.res.v(role))}</th><td>#{h(join_with_separator(@producer.config.names_of(role), ReVIEW::I18n.t('names_splitter')))}</td></tr>\n)
241
- else
242
- ''
243
- end
244
- end.join
245
-
246
- @body << %Q( <tr><th>ISBN</th><td>#{@producer.isbn_hyphen}</td></tr>\n) if @producer.isbn_hyphen
247
- @body << %Q( </table>\n)
248
- if @producer.config['rights'] && !@producer.config['rights'].empty?
249
- @body << %Q( <p class="copyright">#{join_with_separator(@producer.config.names_of('rights').map { |m| h(m) }, '<br />')}</p>\n)
250
- end
251
- @body << %Q( </div>\n)
252
-
253
- @language = @producer.config['language']
254
- @stylesheets = @producer.config['stylesheet']
255
- tmplfile = if @producer.config['htmlversion'].to_i == 5
256
- File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
257
- else
258
- File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
259
- end
260
- tmpl = ReVIEW::Template.load(tmplfile)
261
- tmpl.result(binding)
262
- end
263
-
264
- def colophon_history
265
- buf = ''
266
- buf << %Q( <div class="pubhistory">\n)
267
- if @producer.config['history']
268
- @producer.config['history'].each_with_index do |items, edit|
269
- items.each_with_index do |item, rev|
270
- editstr = edit == 0 ? ReVIEW::I18n.t('first_edition') : ReVIEW::I18n.t('nth_edition', (edit + 1).to_s)
271
- revstr = ReVIEW::I18n.t('nth_impression', (rev + 1).to_s)
272
- if item =~ /\A\d+-\d+-\d+\Z/
273
- buf << %Q( <p>#{ReVIEW::I18n.t('published_by1', [date_to_s(item), editstr + revstr])}</p>\n)
274
- elsif item =~ /\A(\d+-\d+-\d+)[\s ](.+)/
275
- # custom date with string
276
- item.match(/\A(\d+-\d+-\d+)[\s ](.+)/) do |m|
277
- buf << %Q( <p>#{ReVIEW::I18n.t('published_by3', [date_to_s(m[1]), m[2]])}</p>\n)
278
- end
279
- else
280
- # free format
281
- buf << %Q( <p>#{item}</p>\n)
282
- end
283
- end
284
- end
285
- else
286
- buf << %Q( <p>#{ReVIEW::I18n.t('published_by2', date_to_s(@producer.config['date']))}</p>\n)
287
- end
288
- buf << %Q( </div>\n)
289
- buf
290
- end
291
-
292
- def date_to_s(date)
293
- require 'date'
294
- d = Date.parse(date)
295
- d.strftime(ReVIEW::I18n.t('date_format'))
296
- end
297
-
298
- # Return own toc content.
299
- def mytoc
300
- @title = h(@producer.res.v('toctitle'))
301
-
302
- @body = %Q( <h1 class="toc-title">#{h(@producer.res.v('toctitle'))}</h1>\n)
303
- if @producer.config['epubmaker']['flattoc'].nil?
304
- @body << hierarchy_ncx('ul')
305
- else
306
- @body << flat_ncx('ul', @producer.config['epubmaker']['flattocindent'])
307
- end
308
-
309
- @language = @producer.config['language']
310
- @stylesheets = @producer.config['stylesheet']
311
- tmplfile = if @producer.config['htmlversion'].to_i == 5
312
- File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
313
- else
314
- File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
315
- end
316
- tmpl = ReVIEW::Template.load(tmplfile)
317
- tmpl.result(binding)
318
- end
319
-
320
- def hierarchy_ncx(type)
321
- require 'rexml/document'
322
- level = 1
323
- find_jump = nil
324
- has_part = nil
325
- toclevel = @producer.config['toclevel'].to_i
326
-
327
- # check part existance
328
- @producer.contents.each do |item|
329
- next if item.notoc || item.chaptype != 'part'
330
-
331
- has_part = true
332
- break
333
- end
334
-
335
- if has_part
336
- @producer.contents.each do |item|
337
- if item.chaptype == 'part' && item.level > 0
338
- # sections in part
339
- item.level -= 1
340
- end
341
- # down level for part and chaps. pre, appendix, post are preserved
342
- if item.chaptype == 'part' || item.chaptype == 'body'
343
- item.level += 1
344
- end
345
- end
346
- toclevel += 1
347
- end
348
-
349
- doc = REXML::Document.new(%Q(<#{type} class="toc-h#{level}"><li /></#{type}>))
350
- doc.context[:attribute_quote] = :quote
351
-
352
- e = doc.root.elements[1] # first <li/>
353
- @producer.contents.each do |item|
354
- next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > toclevel
355
-
356
- if item.level == level
357
- e2 = e.parent.add_element('li')
358
- e = e2
359
- elsif item.level > level
360
- find_jump = true if (item.level - level) > 1
361
- # deeper
362
- (level + 1).upto(item.level) do |n|
363
- if e.size == 0
364
- # empty span for epubcheck
365
- e.attributes['style'] = 'list-style-type: none;'
366
- es = e.add_element('span', 'style' => 'display:none;')
367
- es.add_text(REXML::Text.new('&#xa0;', false, nil, true))
368
- end
369
-
370
- e2 = e.add_element(type, 'class' => "toc-h#{n}")
371
- e3 = e2.add_element('li')
372
- e = e3
373
- end
374
- level = item.level
375
- elsif item.level < level
376
- # shallower
377
- (level - 1).downto(item.level) { e = e.parent.parent }
378
- e2 = e.parent.add_element('li')
379
- e = e2
380
- level = item.level
381
- end
382
- e2 = e.add_element('a', 'href' => item.file)
383
- e2.add_text(REXML::Text.new(item.title, true))
384
- end
385
-
386
- warn %Q(found level jumping in table of contents. consider to use 'epubmaker:flattoc: true' for strict ePUB validator.) unless find_jump.nil?
387
-
388
- doc.to_s.gsub('<li/>', '').gsub('</li>', "</li>\n").gsub("<#{type} ", "\n" + '\&') # ugly
389
- end
390
-
391
- def flat_ncx(type, indent = nil)
392
- s = %Q(<#{type} class="toc-h1">\n)
393
- @producer.contents.each do |item|
394
- next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > @producer.config['toclevel'].to_i
395
- is = indent == true ? ' ' * item.level : ''
396
- s << %Q(<li><a href="#{item.file}">#{is}#{h(item.title)}</a></li>\n)
397
- end
398
- s << %Q(</#{type}>\n)
399
-
400
- s
401
- end
402
-
403
- def produce_write_common(basedir, tmpdir)
404
- File.open("#{tmpdir}/mimetype", 'w') { |f| @producer.mimetype(f) }
405
-
406
- FileUtils.mkdir_p("#{tmpdir}/META-INF")
407
- File.open("#{tmpdir}/META-INF/container.xml", 'w') { |f| @producer.container(f) }
408
-
409
- FileUtils.mkdir_p("#{tmpdir}/OEBPS")
410
- File.open(File.join(tmpdir, opf_path), 'w') { |f| @producer.opf(f) }
411
-
412
- if File.exist?("#{basedir}/#{@producer.config['cover']}")
413
- FileUtils.cp("#{basedir}/#{@producer.config['cover']}", "#{tmpdir}/OEBPS")
414
- else
415
- File.open("#{tmpdir}/OEBPS/#{@producer.config['cover']}", 'w') { |f| @producer.cover(f) }
416
- end
417
-
418
- @producer.contents.each do |item|
419
- next if item.file =~ /#/ # skip subgroup
420
- fname = "#{basedir}/#{item.file}"
421
- raise "#{fname} doesn't exist. Abort." unless File.exist?(fname)
422
- FileUtils.mkdir_p(File.dirname("#{tmpdir}/OEBPS/#{item.file}"))
423
- FileUtils.cp(fname, "#{tmpdir}/OEBPS/#{item.file}")
424
- end
425
- end
426
-
427
- def legacy_cover_and_title_file(loadfile, writefile)
428
- @title = @producer.config['booktitle']
429
- s = ''
430
- File.open(loadfile) do |f|
431
- f.each_line do |l|
432
- s << l
433
- end
434
- end
435
-
436
- File.open(writefile, 'w') do |f|
437
- f.puts s
438
- end
439
- end
440
-
441
- def join_with_separator(value, sep)
442
- if value.is_a?(Array)
443
- value.join(sep)
444
- else
445
- value
446
- end
447
- end
448
- end
449
- end