review 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +515 -0
- data/ChangeLog +1278 -0
- data/README.rdoc +21 -0
- data/Rakefile +42 -0
- data/VERSION +1 -0
- data/bin/review-check +190 -0
- data/bin/review-checkdep +63 -0
- data/bin/review-compile +165 -0
- data/bin/review-epubmaker +525 -0
- data/bin/review-index +108 -0
- data/bin/review-preproc +140 -0
- data/bin/review-validate +51 -0
- data/bin/review-vol +106 -0
- data/doc/format.re +486 -0
- data/doc/format.txt +434 -0
- data/doc/format_idg.txt +194 -0
- data/doc/format_sjis.txt +313 -0
- data/doc/sample.css +91 -0
- data/doc/sample.yaml +46 -0
- data/lib/lineinput.rb +155 -0
- data/lib/review/book.rb +580 -0
- data/lib/review/builder.rb +274 -0
- data/lib/review/compat.rb +22 -0
- data/lib/review/compiler.rb +483 -0
- data/lib/review/epubbuilder.rb +692 -0
- data/lib/review/ewbbuilder.rb +382 -0
- data/lib/review/exception.rb +21 -0
- data/lib/review/htmlbuilder.rb +370 -0
- data/lib/review/htmllayout.rb +19 -0
- data/lib/review/htmlutils.rb +27 -0
- data/lib/review/idgxmlbuilder.rb +1078 -0
- data/lib/review/index.rb +224 -0
- data/lib/review/latexbuilder.rb +420 -0
- data/lib/review/latexindex.rb +35 -0
- data/lib/review/latexutils.rb +52 -0
- data/lib/review/preprocessor.rb +520 -0
- data/lib/review/textutils.rb +19 -0
- data/lib/review/tocparser.rb +333 -0
- data/lib/review/tocprinter.rb +220 -0
- data/lib/review/topbuilder.rb +572 -0
- data/lib/review/unfold.rb +138 -0
- data/lib/review/volume.rb +66 -0
- data/lib/review.rb +4 -0
- data/review.gemspec +93 -0
- data/setup.rb +1587 -0
- data/test/test_epubbuilder.rb +73 -0
- data/test/test_helper.rb +2 -0
- data/test/test_htmlbuilder.rb +42 -0
- data/test/test_latexbuilder.rb +74 -0
- metadata +122 -0
@@ -0,0 +1,525 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010 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 'tmpdir'
|
12
|
+
require 'fileutils'
|
13
|
+
require 'yaml'
|
14
|
+
require 'optparse'
|
15
|
+
require 'rexml/document'
|
16
|
+
|
17
|
+
def main
|
18
|
+
values = { # These parameters can be overridden by YAML file.
|
19
|
+
"bookname"=> "sample", # it defines epub file name also
|
20
|
+
"booktitle" => "ReVIEW EPUBサンプル",
|
21
|
+
"aut" => "吟遊詩人", # author
|
22
|
+
"prt" => nil, # printer(publisher)
|
23
|
+
"asn" => nil, # associated name
|
24
|
+
"ant" => nil, # bibliographic antecedent
|
25
|
+
"clb" => nil, # Collaborator
|
26
|
+
"edt" => nil, # Editor
|
27
|
+
"dsr" => nil, # Designer
|
28
|
+
"ill" => nil, # Illustrator
|
29
|
+
"pht" => nil, # Photographer
|
30
|
+
"trl" => nil, # Translator
|
31
|
+
"date" => nil, # publishing date
|
32
|
+
"rights" => nil, # Copyright messages
|
33
|
+
"description" => nil, # Description
|
34
|
+
"urnid" => "example.jp", # just used for unique ID
|
35
|
+
"stylesheet" => "stylesheet.css", # stylesheet file
|
36
|
+
"coverfile" => nil, # content file of body of cover page
|
37
|
+
"mytoc" => nil, # whether make own table of contents or not
|
38
|
+
"params" => "", # specify review2epub parameters
|
39
|
+
"toclevel" => 3, # level of toc
|
40
|
+
"secnolevel" => 2, # level of section #
|
41
|
+
"posthook" => nil, # command path of post hook
|
42
|
+
"debug" => nil, # debug flag
|
43
|
+
}
|
44
|
+
yamlfile = ""
|
45
|
+
|
46
|
+
if ARGV.size == 1
|
47
|
+
values = values.merge(YAML.load_file(ARGV[0]))
|
48
|
+
yamlfile = ARGV[0]
|
49
|
+
end
|
50
|
+
|
51
|
+
bookname = values["bookname"]
|
52
|
+
|
53
|
+
if File.exist?("#{bookname}.epub")
|
54
|
+
STDERR.puts "#{bookname}.epub exists. Please remove or rename first."
|
55
|
+
exit 1
|
56
|
+
end
|
57
|
+
if File.exist?("#{bookname}")
|
58
|
+
STDERR.puts "#{bookname} directory exists. Please remove or rename first."
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
identifier = "urn:uuid:#{values["urnid"]}_#{bookname}"
|
63
|
+
|
64
|
+
tmp = values["debug"].nil? ? Dir.mktmpdir : "."
|
65
|
+
Dir.mkdir("#{tmp}/#{bookname}")
|
66
|
+
|
67
|
+
# MIME type
|
68
|
+
File.open("#{tmp}/#{bookname}/mimetype", "w") {|f|
|
69
|
+
f.puts "application/epub+zip"
|
70
|
+
}
|
71
|
+
|
72
|
+
Dir.mkdir("#{tmp}/#{bookname}/OEBPS")
|
73
|
+
# XHTML
|
74
|
+
pre = 0
|
75
|
+
body = 0
|
76
|
+
post = 0
|
77
|
+
@manifeststr = ""
|
78
|
+
@ncxstr = ""
|
79
|
+
@tocdesc = Array.new
|
80
|
+
toccount = 2
|
81
|
+
|
82
|
+
if File.exists?("PREDEF")
|
83
|
+
File.open("PREDEF") {|chaps|
|
84
|
+
chaps.each_line {|l|
|
85
|
+
next if l =~ /^#/
|
86
|
+
pre = pre + 1
|
87
|
+
toccount = toccount + 1
|
88
|
+
fork {
|
89
|
+
STDOUT.reopen("#{tmp}/#{bookname}/OEBPS/pre#{pre}.html")
|
90
|
+
exec("review-compile --target=epub --level=#{values["secnolevel"]} #{values["params"]} #{l}")
|
91
|
+
}
|
92
|
+
Process.waitall
|
93
|
+
getanchors("#{tmp}/#{bookname}/OEBPS/pre#{pre}.html")
|
94
|
+
@manifeststr << %Q(<item id="pre#{pre}" href="pre#{pre}.html" media-type="application/xhtml+xml" />\n)
|
95
|
+
@ncxstr << %Q(<itemref idref="pre#{pre}" />\n)
|
96
|
+
}
|
97
|
+
}
|
98
|
+
end
|
99
|
+
if File.exists?("CHAPS")
|
100
|
+
File.open("CHAPS") {|chaps|
|
101
|
+
chaps.each_line {|l|
|
102
|
+
body = body + 1
|
103
|
+
toccount = toccount + 1
|
104
|
+
next if l =~ /^#/
|
105
|
+
fork {
|
106
|
+
STDOUT.reopen("#{tmp}/#{bookname}/OEBPS/chap#{body}.html")
|
107
|
+
exec("review-compile --target=epub --level=#{values["secnolevel"]} #{values["params"]} #{l}")
|
108
|
+
}
|
109
|
+
Process.waitall
|
110
|
+
getanchors("#{tmp}/#{bookname}/OEBPS/chap#{body}.html")
|
111
|
+
@manifeststr << %Q(<item id="chap#{body}" href="chap#{body}.html" media-type="application/xhtml+xml" />\n)
|
112
|
+
@ncxstr << %Q(<itemref idref="chap#{body}" />\n)
|
113
|
+
}
|
114
|
+
}
|
115
|
+
end
|
116
|
+
if File.exists?("POSTDEF")
|
117
|
+
File.open("POSTDEF") {|chaps|
|
118
|
+
chaps.each_line {|l|
|
119
|
+
next if l =~ /^#/
|
120
|
+
post = post + 1
|
121
|
+
toccount = toccount + 1
|
122
|
+
fork {
|
123
|
+
STDOUT.reopen("#{tmp}/#{bookname}/OEBPS/post#{post}.html")
|
124
|
+
exec("review-compile --target=epub --level=#{values["secnolevel"]} #{values["params"]} #{l}")
|
125
|
+
}
|
126
|
+
Process.waitall
|
127
|
+
getanchors("#{tmp}/#{bookname}/OEBPS/post#{post}.html")
|
128
|
+
@manifeststr << %Q(<item id="post#{post}" href="post#{post}.html" media-type="application/xhtml+xml" />\n)
|
129
|
+
@ncxstr << %Q(<itemref idref="post#{post}" />\n)
|
130
|
+
}
|
131
|
+
}
|
132
|
+
end
|
133
|
+
if File.exist?("images")
|
134
|
+
Dir.mkdir("#{tmp}/#{bookname}/OEBPS/images")
|
135
|
+
copyImagesToDir("images", "#{tmp}/#{bookname}/OEBPS/images")
|
136
|
+
end
|
137
|
+
|
138
|
+
# container
|
139
|
+
Dir.mkdir("#{tmp}/#{bookname}/META-INF")
|
140
|
+
File.open("#{tmp}/#{bookname}/META-INF/container.xml", "w") {|f|
|
141
|
+
f.puts <<EOT
|
142
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
143
|
+
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
|
144
|
+
<rootfiles>
|
145
|
+
<rootfile full-path="OEBPS/#{bookname}.opf" media-type="application/oebps-package+xml" />
|
146
|
+
</rootfiles>
|
147
|
+
</container>
|
148
|
+
EOT
|
149
|
+
}
|
150
|
+
|
151
|
+
# opf (meta info)
|
152
|
+
File.open("#{tmp}/#{bookname}/OEBPS/#{bookname}.opf", "w") {|f|
|
153
|
+
f.puts <<EOT
|
154
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
155
|
+
<package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
|
156
|
+
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
|
157
|
+
<dc:title>#{values["booktitle"]}</dc:title>
|
158
|
+
EOT
|
159
|
+
|
160
|
+
f.puts %Q(<dc:creator opf:role="aut">#{values["aut"]}</dc:creator>) unless values["aut"].nil? # FIXME: support multiple members
|
161
|
+
|
162
|
+
f.puts %Q(<dc:publisher>#{values["prt"]}</dc:publisher>) unless values["prt"].nil?
|
163
|
+
|
164
|
+
f.puts %Q(<dc:date>#{values["date"]}</dc:date>) unless values["date"].nil?
|
165
|
+
f.puts %Q(<dc:rights>#{values["rights"]}</dc:rights>) unless values["rights"].nil?
|
166
|
+
|
167
|
+
f.puts %Q(<dc:contributor opf:role="asn">#{values["asn"]}</dc:contributor>) unless values["asn"].nil?
|
168
|
+
f.puts %Q(<dc:contributor opf:role="ant">#{values["ant"]}</dc:contributor>) unless values["ant"].nil?
|
169
|
+
f.puts %Q(<dc:contributor opf:role="clb">#{values["clb"]}</dc:contributor>) unless values["clb"].nil?
|
170
|
+
f.puts %Q(<dc:contributor opf:role="edt">#{values["edt"]}</dc:contributor>) unless values["edt"].nil?
|
171
|
+
f.puts %Q(<dc:contributor opf:role="dsr">#{values["dsr"]}</dc:contributor>) unless values["dsr"].nil?
|
172
|
+
f.puts %Q(<dc:contributor opf:role="ill">#{values["ill"]}</dc:contributor>) unless values["ill"].nil?
|
173
|
+
f.puts %Q(<dc:contributor opf:role="pht">#{values["pht"]}</dc:contributor>) unless values["pht"].nil?
|
174
|
+
f.puts %Q(<dc:contributor opf:role="trl">#{values["trl"]}</dc:contributor>) unless values["trl"].nil?
|
175
|
+
|
176
|
+
f.puts %Q(<dc:description>#{values["description"]}</dc:description>) unless values["description"].nil?
|
177
|
+
|
178
|
+
if values["coverimage"]
|
179
|
+
f.puts %Q(<meta name="cover" content="#{getFigId(values["coverimage"])}"/>)
|
180
|
+
end
|
181
|
+
f.puts <<EOT
|
182
|
+
<dc:language>ja</dc:language>
|
183
|
+
<dc:identifier id="BookId">#{identifier}</dc:identifier>
|
184
|
+
</metadata>
|
185
|
+
<manifest>
|
186
|
+
<item id="ncx" href="#{bookname}.ncx" media-type="application/x-dtbncx+xml" />
|
187
|
+
<item id="style" href="#{values["stylesheet"]}" media-type="text/css" />
|
188
|
+
<item id="#{bookname}" href="#{bookname}.html" media-type="application/xhtml+xml" />
|
189
|
+
<item id="top" href="top.html" media-type="application/xhtml+xml" />
|
190
|
+
EOT
|
191
|
+
|
192
|
+
unless values["mytoc"].nil?
|
193
|
+
f.puts <<EOT
|
194
|
+
<item id="toc" href="toc.html" media-type="application/xhtml+xml" />
|
195
|
+
EOT
|
196
|
+
end
|
197
|
+
|
198
|
+
f.puts @manifeststr
|
199
|
+
f.puts <<EOT
|
200
|
+
</manifest>
|
201
|
+
<spine toc="ncx">
|
202
|
+
<itemref idref="#{bookname}" linear="no" />
|
203
|
+
<itemref idref="top" />
|
204
|
+
<itemref idref="toc" />
|
205
|
+
EOT
|
206
|
+
f.puts @ncxstr
|
207
|
+
f.puts <<EOT
|
208
|
+
</spine>
|
209
|
+
<guide>
|
210
|
+
<reference type="cover" title="表紙" href="#{bookname}.html"/>
|
211
|
+
<reference type="title-page" title="Title Page" href="top.html"/>
|
212
|
+
EOT
|
213
|
+
unless values["mytoc"].nil?
|
214
|
+
f.puts <<EOT
|
215
|
+
<reference type="toc" title="目次" href="toc.html"/>
|
216
|
+
EOT
|
217
|
+
end
|
218
|
+
f.puts <<EOT
|
219
|
+
</guide>
|
220
|
+
</package>
|
221
|
+
EOT
|
222
|
+
}
|
223
|
+
|
224
|
+
# ncx (toc)
|
225
|
+
File.open("#{tmp}/#{bookname}/OEBPS/#{bookname}.ncx", "w") {|f|
|
226
|
+
f.puts <<EOT
|
227
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
228
|
+
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
|
229
|
+
<head>
|
230
|
+
<meta name="dtb:uid" content="#{identifier}"/>
|
231
|
+
<meta name="dtb:depth" content="1"/>
|
232
|
+
<meta name="dtb:totalPageCount" content="0"/>
|
233
|
+
<meta name="dtb:maxPageNumber" content="0"/>
|
234
|
+
</head>
|
235
|
+
<docTitle>
|
236
|
+
<text>#{values["booktitle"]}</text>
|
237
|
+
</docTitle>
|
238
|
+
<docAuthor>
|
239
|
+
<text>#{values["aut"].nil? ? "" : values["aut"]}</text>
|
240
|
+
</docAuthor>
|
241
|
+
<navMap>
|
242
|
+
<navPoint id="top" playOrder="1">
|
243
|
+
<navLabel>
|
244
|
+
<text>#{values["booktitle"]}</text>
|
245
|
+
</navLabel>
|
246
|
+
<content src="#{bookname}.html"/>
|
247
|
+
</navPoint>
|
248
|
+
EOT
|
249
|
+
|
250
|
+
nav_count = 2
|
251
|
+
|
252
|
+
unless values["mytoc"].nil?
|
253
|
+
f.puts <<EOT
|
254
|
+
<navPoint id="toc" playOrder="2">
|
255
|
+
<navLabel>
|
256
|
+
<text>目次</text>
|
257
|
+
</navLabel>
|
258
|
+
<content src="toc.html"/>
|
259
|
+
</navPoint>
|
260
|
+
EOT
|
261
|
+
nav_count = 3
|
262
|
+
end
|
263
|
+
|
264
|
+
@tocdesc.each {|item|
|
265
|
+
level, file, id, content = item
|
266
|
+
# values["level"]
|
267
|
+
next if level > values["toclevel"].to_i
|
268
|
+
indent = ""
|
269
|
+
if level > values["secnolevel"].to_i
|
270
|
+
indent = "- "
|
271
|
+
end
|
272
|
+
f.puts <<EOT
|
273
|
+
<navPoint id="navPoint-#{nav_count}" playOrder="#{nav_count}">
|
274
|
+
<navLabel>
|
275
|
+
<text>#{indent}#{content}</text>
|
276
|
+
</navLabel>
|
277
|
+
<content src="#{file}##{id}"/>
|
278
|
+
</navPoint>
|
279
|
+
EOT
|
280
|
+
nav_count += 1
|
281
|
+
}
|
282
|
+
f.puts <<EOT
|
283
|
+
</navMap>
|
284
|
+
</ncx>
|
285
|
+
EOT
|
286
|
+
}
|
287
|
+
|
288
|
+
# Cover page
|
289
|
+
File.open("#{tmp}/#{bookname}/OEBPS/#{bookname}.html", "w") {|f|
|
290
|
+
f.puts <<EOT
|
291
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
292
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
293
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
|
294
|
+
<head>
|
295
|
+
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
296
|
+
<meta http-equiv="Content-Style-Type" content="text/css"/>
|
297
|
+
<link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
|
298
|
+
<meta name="generator" content="ReVIEW EPUB Maker"/>
|
299
|
+
<title>#{values["booktitle"]}</title>
|
300
|
+
</head>
|
301
|
+
<body>
|
302
|
+
EOT
|
303
|
+
if !values["coverfile"].nil? && File.exist?(values["coverfile"])
|
304
|
+
File.open(values["coverfile"]) {|f2|
|
305
|
+
f2.each_line {|l|
|
306
|
+
f.puts l
|
307
|
+
}
|
308
|
+
}
|
309
|
+
else
|
310
|
+
f.puts <<EOT
|
311
|
+
<h1>#{values["booktitle"]}</h1>
|
312
|
+
EOT
|
313
|
+
end
|
314
|
+
|
315
|
+
f.puts <<EOT
|
316
|
+
</body>
|
317
|
+
</html>
|
318
|
+
EOT
|
319
|
+
}
|
320
|
+
|
321
|
+
|
322
|
+
# Title page
|
323
|
+
File.open("#{tmp}/#{bookname}/OEBPS/top.html", "w") {|f|
|
324
|
+
f.puts <<EOT
|
325
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
326
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
327
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
|
328
|
+
<head>
|
329
|
+
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
330
|
+
<meta http-equiv="Content-Style-Type" content="text/css"/>
|
331
|
+
<link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
|
332
|
+
<meta name="generator" content="ReVIEW EPUB Maker"/>
|
333
|
+
<title>#{values["booktitle"]}</title>
|
334
|
+
</head>
|
335
|
+
<body>
|
336
|
+
EOT
|
337
|
+
if !values["titlepagefile"].nil? && File.exist?(values["titlepagefile"])
|
338
|
+
File.open(values["titlepagefile"]) {|f2|
|
339
|
+
f2.each_line {|l|
|
340
|
+
f.puts l
|
341
|
+
}
|
342
|
+
}
|
343
|
+
else
|
344
|
+
f.puts <<EOT
|
345
|
+
<h1 class="tp-title">#{values["booktitle"]}</h1>
|
346
|
+
EOT
|
347
|
+
if values["aut"]
|
348
|
+
f.puts <<EOT
|
349
|
+
<p>
|
350
|
+
<br />
|
351
|
+
<br />
|
352
|
+
</p>
|
353
|
+
<h2 class="tp-author">#{values["aut"]}</h2>
|
354
|
+
EOT
|
355
|
+
end
|
356
|
+
if values["prt"]
|
357
|
+
f.puts <<EOT
|
358
|
+
<p>
|
359
|
+
<br />
|
360
|
+
<br />
|
361
|
+
<br />
|
362
|
+
<br />
|
363
|
+
</p>
|
364
|
+
<h3 class="tp-publisher">#{values["prt"]}</h3>
|
365
|
+
EOT
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
f.puts <<EOT
|
370
|
+
</body>
|
371
|
+
</html>
|
372
|
+
EOT
|
373
|
+
}
|
374
|
+
|
375
|
+
# Additional toc page
|
376
|
+
unless values["mytoc"].nil?
|
377
|
+
File.open("#{tmp}/#{bookname}/OEBPS/toc.html", "w") {|f|
|
378
|
+
f.puts <<EOT
|
379
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
380
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
381
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
|
382
|
+
<head>
|
383
|
+
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
384
|
+
<meta http-equiv="Content-Style-Type" content="text/css"/>
|
385
|
+
<link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
|
386
|
+
<meta name="generator" content="ReVIEW EPUB Maker"/>
|
387
|
+
<title>目次</title>
|
388
|
+
</head>
|
389
|
+
<body>
|
390
|
+
<h1>目次</h1>
|
391
|
+
<ul class=\"toc-h1\">
|
392
|
+
EOT
|
393
|
+
|
394
|
+
current = 1
|
395
|
+
init_item = true
|
396
|
+
@tocdesc.each {|item|
|
397
|
+
level, file, id, content = item
|
398
|
+
# values["level"]
|
399
|
+
next if level > values["toclevel"].to_i
|
400
|
+
if level > current
|
401
|
+
f.puts ""
|
402
|
+
f.puts "<ul class=\"toc-h#{level}\">"
|
403
|
+
current = level
|
404
|
+
elsif level < current
|
405
|
+
f.puts "</li>"
|
406
|
+
f.puts "</ul>"
|
407
|
+
f.puts "</li>"
|
408
|
+
current = level
|
409
|
+
elsif init_item
|
410
|
+
# noop
|
411
|
+
else
|
412
|
+
f.puts "</li>"
|
413
|
+
end
|
414
|
+
f.write "<li><a href=\"#{file}##{id}\">#{content}</a>"
|
415
|
+
init_item = false
|
416
|
+
}
|
417
|
+
|
418
|
+
(current - 1).downto(1) {|n|
|
419
|
+
f.puts "</li>"
|
420
|
+
f.puts "</ul>"
|
421
|
+
}
|
422
|
+
if !init_item
|
423
|
+
f.puts "</li>"
|
424
|
+
end
|
425
|
+
|
426
|
+
f.puts <<EOT
|
427
|
+
</ul>
|
428
|
+
</body>
|
429
|
+
</html>
|
430
|
+
EOT
|
431
|
+
}
|
432
|
+
end
|
433
|
+
|
434
|
+
# stylesheet
|
435
|
+
File.open("#{tmp}/#{bookname}/OEBPS/stylesheet.css", "w") {|f|
|
436
|
+
f.puts <<EOT
|
437
|
+
/* sample style sheet for epub */
|
438
|
+
@charset "utf-8";
|
439
|
+
|
440
|
+
body {
|
441
|
+
}
|
442
|
+
EOT
|
443
|
+
}
|
444
|
+
if File.exist?(values["stylesheet"])
|
445
|
+
FileUtils.cp values["stylesheet"], "#{tmp}/#{bookname}/OEBPS/#{values["stylesheet"]}"
|
446
|
+
end
|
447
|
+
|
448
|
+
# hook
|
449
|
+
if !values["posthook"].nil? && !values["posthook"].empty? && FileTest.executable?(values["posthook"])
|
450
|
+
fork {
|
451
|
+
exec(values["posthook"], "#{tmp}/#{bookname}", Dir.pwd, yamlfile)
|
452
|
+
}
|
453
|
+
Process.waitall
|
454
|
+
end
|
455
|
+
|
456
|
+
# Zip epubファイルの作成。mimetypeは圧縮しないようにする
|
457
|
+
fork {
|
458
|
+
basedir = Dir.pwd
|
459
|
+
Dir.chdir("#{tmp}/#{bookname}") {|d|
|
460
|
+
exec("zip -0X #{basedir}/#{bookname}.epub mimetype")
|
461
|
+
}
|
462
|
+
}
|
463
|
+
Process.waitall
|
464
|
+
fork {
|
465
|
+
basedir = Dir.pwd
|
466
|
+
Dir.chdir("#{tmp}/#{bookname}") {|d|
|
467
|
+
exec("zip -Xr9D #{basedir}/#{bookname}.epub META-INF OEBPS")
|
468
|
+
}
|
469
|
+
}
|
470
|
+
Process.waitall
|
471
|
+
|
472
|
+
FileUtils.rm_r(tmp) if values["debug"].nil?
|
473
|
+
end
|
474
|
+
|
475
|
+
def copyImagesToDir(dirname, copybase)
|
476
|
+
Dir.open(dirname) {|dir|
|
477
|
+
dir.each {|fname|
|
478
|
+
next if fname =~ /^\./
|
479
|
+
if FileTest.directory?("#{dirname}/#{fname}")
|
480
|
+
copyImagesToDir("#{dirname}/#{fname}", "#{copybase}/#{fname}")
|
481
|
+
else
|
482
|
+
if fname =~ /\.(png|gif|jpg|jpeg|svg)$/i
|
483
|
+
Dir.mkdir(copybase) unless File.exist?(copybase)
|
484
|
+
FileUtils.cp "#{dirname}/#{fname}", copybase
|
485
|
+
figid = getFigId(fname)
|
486
|
+
mime = nil
|
487
|
+
case fname.downcase.match(/\.(png|gif|jpg|jpeg|svg)$/)[1]
|
488
|
+
when "png": mime = "image/png"
|
489
|
+
when "gif": mime = "image/gif"
|
490
|
+
when "jpg", "jpeg": mime = "image/jpeg"
|
491
|
+
when "svg": mime = "image/svg+xml"
|
492
|
+
else
|
493
|
+
raise "unsupported type #{fname}"
|
494
|
+
end
|
495
|
+
@manifeststr << %Q(<item id="#{figid}" href="#{dirname}/#{fname}" media-type="#{mime}" />\n)
|
496
|
+
end
|
497
|
+
end
|
498
|
+
}
|
499
|
+
}
|
500
|
+
end
|
501
|
+
|
502
|
+
def getFigId(filename)
|
503
|
+
figid = filename.sub(/\.(png|gif|jpg|jpeg|svg)$/, '')
|
504
|
+
"fig-#{figid}"
|
505
|
+
end
|
506
|
+
|
507
|
+
def getTitle(filename)
|
508
|
+
File.open(filename) {|f|
|
509
|
+
return REXML::Document.new(f).elements["//html/head/title"].text
|
510
|
+
}
|
511
|
+
end
|
512
|
+
|
513
|
+
def getanchors(filename)
|
514
|
+
File.open(filename) {|f|
|
515
|
+
file = filename.sub(/.+\//, '')
|
516
|
+
f.each_line {|l|
|
517
|
+
if l =~ /\A<h(\d)><a id=\"(.+?)\" \/>(.+?)<\/h/
|
518
|
+
# level, ID, content
|
519
|
+
@tocdesc << [$1.to_i, file, $2, $3]
|
520
|
+
end
|
521
|
+
}
|
522
|
+
}
|
523
|
+
end
|
524
|
+
|
525
|
+
main
|