review 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/ChangeLog +4 -0
- data/bin/review-init +8 -0
- data/doc/NEWS.ja.md +328 -0
- data/doc/NEWS.md +332 -0
- data/doc/sample.yml +4 -1
- data/lib/epubmaker/epubcommon.rb +6 -5
- data/lib/epubmaker/epubv3.rb +1 -1
- data/lib/epubmaker/producer.rb +1 -1
- data/lib/review/book/chapter.rb +1 -1
- data/lib/review/book/index.rb +2 -1
- data/lib/review/builder.rb +3 -3
- data/lib/review/compiler.rb +2 -2
- data/lib/review/epubmaker.rb +56 -54
- data/lib/review/htmlbuilder.rb +9 -6
- data/lib/review/htmlutils.rb +6 -1
- data/lib/review/i18n.rb +3 -4
- data/lib/review/i18n.yml +11 -0
- data/lib/review/idgxmlbuilder.rb +3 -3
- data/lib/review/latexbuilder.rb +19 -10
- data/lib/review/layout.tex.erb +33 -2
- data/lib/review/lineinput.rb +17 -0
- data/lib/review/pdfmaker.rb +18 -6
- data/lib/review/topbuilder.rb +1 -1
- data/lib/review/version.rb +1 -1
- data/review.gemspec +1 -1
- data/test/assets/test_template.tex +255 -0
- data/test/assets/test_template_backmatter.tex +32 -0
- data/test/sample-book/src/config.yml +3 -0
- data/test/test_epub3maker.rb +3 -1
- data/test/test_helper.rb +4 -0
- data/test/test_htmlbuilder.rb +36 -11
- data/test/test_i18n.rb +3 -1
- data/test/test_index.rb +15 -0
- data/test/test_latexbuilder.rb +9 -0
- data/test/test_pdfmaker.rb +39 -2
- metadata +10 -4
data/doc/sample.yml
CHANGED
@@ -89,7 +89,10 @@ secnolevel: 2
|
|
89
89
|
# 部番号を表示する見出しレベル(未実装)
|
90
90
|
# part_secnolevel: 1
|
91
91
|
|
92
|
-
#
|
92
|
+
# 本文中に目次ページを作成するか。省略した場合はnull (作成しない)
|
93
|
+
# toc: true
|
94
|
+
|
95
|
+
# EPUB2標準の目次(NCX)以外に物理目次ファイルを作成するか。省略した場合はnull (作成しない)
|
93
96
|
# ePUB3においてはこの設定によらず必ず作成される
|
94
97
|
# mytoc: true
|
95
98
|
|
data/lib/epubmaker/epubcommon.rb
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
require 'epubmaker/producer'
|
13
13
|
require 'review/i18n'
|
14
14
|
require 'cgi'
|
15
|
+
require 'shellwords'
|
15
16
|
|
16
17
|
module EPUBMaker
|
17
18
|
|
@@ -389,10 +390,10 @@ EOT
|
|
389
390
|
def produce_write_common(basedir, tmpdir)
|
390
391
|
File.open("#{tmpdir}/mimetype", "w") {|f| @producer.mimetype(f) }
|
391
392
|
|
392
|
-
|
393
|
+
FileUtils.mkdir_p("#{tmpdir}/META-INF")
|
393
394
|
File.open("#{tmpdir}/META-INF/container.xml", "w") {|f| @producer.container(f) }
|
394
395
|
|
395
|
-
|
396
|
+
FileUtils.mkdir_p("#{tmpdir}/OEBPS")
|
396
397
|
File.open("#{tmpdir}/OEBPS/#{@producer.params["bookname"]}.opf", "w") {|f| @producer.opf(f) }
|
397
398
|
|
398
399
|
if File.exist?("#{basedir}/#{@producer.params["cover"]}")
|
@@ -405,14 +406,14 @@ EOT
|
|
405
406
|
next if item.file =~ /#/ # skip subgroup
|
406
407
|
fname = "#{basedir}/#{item.file}"
|
407
408
|
raise "#{fname} doesn't exist. Abort." unless File.exist?(fname)
|
408
|
-
FileUtils.mkdir_p(File.dirname("#{tmpdir}/OEBPS/#{item.file}"))
|
409
|
+
FileUtils.mkdir_p(File.dirname("#{tmpdir}/OEBPS/#{item.file}"))
|
409
410
|
FileUtils.cp(fname, "#{tmpdir}/OEBPS/#{item.file}")
|
410
411
|
end
|
411
412
|
end
|
412
413
|
|
413
414
|
def export_zip(tmpdir, epubfile)
|
414
|
-
Dir.chdir(tmpdir) {|d| `#{@producer.params["epubmaker"]["zip_stage1"]} #{epubfile} mimetype` }
|
415
|
-
Dir.chdir(tmpdir) {|d| `#{@producer.params["epubmaker"]["zip_stage2"]} #{epubfile} META-INF OEBPS #{@producer.params["epubmaker"]["zip_addpath"]}` }
|
415
|
+
Dir.chdir(tmpdir) {|d| `#{@producer.params["epubmaker"]["zip_stage1"]} #{epubfile.shellescape} mimetype` }
|
416
|
+
Dir.chdir(tmpdir) {|d| `#{@producer.params["epubmaker"]["zip_stage2"]} #{epubfile.shellescape} META-INF OEBPS #{@producer.params["epubmaker"]["zip_addpath"]}` }
|
416
417
|
end
|
417
418
|
|
418
419
|
def legacy_cover_and_title_file(loadfile, writefile)
|
data/lib/epubmaker/epubv3.rb
CHANGED
@@ -126,7 +126,7 @@ EOT
|
|
126
126
|
|
127
127
|
if @producer.params["coverimage"]
|
128
128
|
@producer.contents.each do |item|
|
129
|
-
if item.media =~ /\Aimage/ && item.file
|
129
|
+
if item.media =~ /\Aimage/ && File.basename(item.file) == @producer.params["coverimage"]
|
130
130
|
s << %Q[ <item properties="cover-image" id="cover-#{item.id}" href="#{item.file}" media-type="#{item.media}"/>\n]
|
131
131
|
item.id = nil
|
132
132
|
break
|
data/lib/epubmaker/producer.rb
CHANGED
@@ -268,7 +268,7 @@ module EPUBMaker
|
|
268
268
|
end
|
269
269
|
end
|
270
270
|
|
271
|
-
@params["htmlversion"]
|
271
|
+
@params["htmlversion"] = 5 if @params["epubversion"] >= 3
|
272
272
|
|
273
273
|
%w[bookname title].each do |k|
|
274
274
|
raise "Key #{k} must have a value. Abort." if @params[k].nil?
|
data/lib/review/book/chapter.rb
CHANGED
data/lib/review/book/index.rb
CHANGED
@@ -57,11 +57,12 @@ module ReVIEW
|
|
57
57
|
def [](id)
|
58
58
|
@index.fetch(id)
|
59
59
|
rescue
|
60
|
-
if @index.keys.map{|i| i.split(/\|/) }.flatten. # unfold all ids
|
60
|
+
if @index.keys.map{|i| i.split(/\|/).last }.flatten. # unfold all ids
|
61
61
|
reduce(Hash.new(0)){|h, i| h[i] += 1; h}. # number of occurrences
|
62
62
|
select{|k, v| k == id && v > 1 }.present? # detect duplicated
|
63
63
|
raise KeyError, "key '#{id}' is ambiguous for #{self.class}"
|
64
64
|
end
|
65
|
+
|
65
66
|
@items.each do |i|
|
66
67
|
if i.id.split(/\|/).include?(id)
|
67
68
|
return i
|
data/lib/review/builder.rb
CHANGED
@@ -104,9 +104,9 @@ module ReVIEW
|
|
104
104
|
listnum_body lines, lang
|
105
105
|
end
|
106
106
|
|
107
|
-
def source(lines, caption)
|
107
|
+
def source(lines, caption, lang = nil)
|
108
108
|
source_header caption
|
109
|
-
source_body lines
|
109
|
+
source_body lines, lang
|
110
110
|
end
|
111
111
|
|
112
112
|
def image(lines, id, caption, metric = nil)
|
@@ -344,7 +344,7 @@ module ReVIEW
|
|
344
344
|
|
345
345
|
def get_chap(chapter = @chapter)
|
346
346
|
if @book.config["secnolevel"] > 0 && !chapter.number.nil? && !chapter.number.to_s.empty?
|
347
|
-
return
|
347
|
+
return chapter.format_number(nil)
|
348
348
|
end
|
349
349
|
return nil
|
350
350
|
end
|
data/lib/review/compiler.rb
CHANGED
@@ -11,7 +11,6 @@
|
|
11
11
|
require 'review/extentions'
|
12
12
|
require 'review/preprocessor'
|
13
13
|
require 'review/exception'
|
14
|
-
require 'lineinput'
|
15
14
|
require 'strscan'
|
16
15
|
|
17
16
|
module ReVIEW
|
@@ -137,7 +136,7 @@ module ReVIEW
|
|
137
136
|
defblock :table, 0..2
|
138
137
|
defblock :quote, 0
|
139
138
|
defblock :image, 2..3, true
|
140
|
-
defblock :source, 0..
|
139
|
+
defblock :source, 0..2
|
141
140
|
defblock :listnum, 2..3
|
142
141
|
defblock :emlistnum, 0..2
|
143
142
|
defblock :bibpaper, 2..3, true
|
@@ -409,6 +408,7 @@ module ReVIEW
|
|
409
408
|
@strategy.dt text(f.gets.sub(/\A\s*:/, '').strip)
|
410
409
|
@strategy.dd f.break(/\A(\S|\s*:)/).map {|line| text(line.strip) }
|
411
410
|
f.skip_blank_lines
|
411
|
+
f.skip_comment_lines
|
412
412
|
end
|
413
413
|
@strategy.dl_end
|
414
414
|
end
|
data/lib/review/epubmaker.rb
CHANGED
@@ -18,20 +18,20 @@ module ReVIEW
|
|
18
18
|
include REXML
|
19
19
|
|
20
20
|
def initialize
|
21
|
-
@
|
21
|
+
@producer = nil
|
22
22
|
@tochtmltxt = "toc-html.txt"
|
23
23
|
@buildlogtxt = "build-log.txt"
|
24
24
|
end
|
25
25
|
|
26
26
|
def log(s)
|
27
|
-
puts s
|
27
|
+
puts s if @params["debug"].present?
|
28
28
|
end
|
29
29
|
|
30
30
|
def load_yaml(yamlfile)
|
31
31
|
@params = ReVIEW::Configure.values.merge(YAML.load_file(yamlfile)) # FIXME:設定がRe:VIEW側とepubmaker/producer.rb側の2つに分かれて面倒
|
32
|
-
@
|
33
|
-
@
|
34
|
-
@params = @
|
32
|
+
@producer = Producer.new(@params)
|
33
|
+
@producer.load(yamlfile)
|
34
|
+
@params = @producer.params
|
35
35
|
end
|
36
36
|
|
37
37
|
def produce(yamlfile, bookname=nil)
|
@@ -42,33 +42,31 @@ module ReVIEW
|
|
42
42
|
|
43
43
|
log("Loaded yaml file (#{yamlfile}). I will produce #{bookname}.epub.")
|
44
44
|
|
45
|
-
|
46
|
-
FileUtils.rm_rf(booktmpname) if @params["debug"]
|
45
|
+
FileUtils.rm_f("#{bookname}.epub")
|
46
|
+
FileUtils.rm_rf(booktmpname) if @params["debug"]
|
47
47
|
|
48
48
|
basetmpdir = Dir.mktmpdir("#{bookname}-", Dir.pwd)
|
49
49
|
begin
|
50
50
|
log("Created first temporary directory as #{basetmpdir}.")
|
51
51
|
|
52
|
-
|
53
|
-
call_hook(@params["epubmaker"]["hook_beforeprocess"], basetmpdir)
|
52
|
+
call_hook("hook_beforeprocess", basetmpdir)
|
54
53
|
|
54
|
+
## copy all files into basetmpdir
|
55
55
|
copy_stylesheet(basetmpdir)
|
56
56
|
|
57
57
|
copy_frontmatter(basetmpdir)
|
58
|
-
|
59
|
-
call_hook(@params["epubmaker"]["hook_afterfrontmatter"], basetmpdir)
|
58
|
+
call_hook("hook_afterfrontmatter", basetmpdir)
|
60
59
|
|
61
60
|
build_body(basetmpdir, yamlfile)
|
62
|
-
|
63
|
-
call_hook(@params["epubmaker"]["hook_afterbody"], basetmpdir)
|
61
|
+
call_hook("hook_afterbody", basetmpdir)
|
64
62
|
|
65
63
|
copy_backmatter(basetmpdir)
|
66
|
-
|
67
|
-
call_hook(@params["epubmaker"]["hook_afterbackmatter"], basetmpdir)
|
64
|
+
call_hook("hook_afterbackmatter", basetmpdir)
|
68
65
|
|
66
|
+
## push contents in basetmpdir into @producer
|
69
67
|
push_contents(basetmpdir)
|
70
68
|
|
71
|
-
if
|
69
|
+
if @params["epubmaker"]["verify_target_images"].present?
|
72
70
|
verify_target_images(basetmpdir)
|
73
71
|
copy_images(@params["imagedir"], basetmpdir)
|
74
72
|
else
|
@@ -79,24 +77,28 @@ module ReVIEW
|
|
79
77
|
copy_resources("adv", "#{basetmpdir}/images")
|
80
78
|
copy_resources(@params["fontdir"], "#{basetmpdir}/fonts", @params["font_ext"])
|
81
79
|
|
82
|
-
|
83
|
-
call_hook(@params["epubmaker"]["hook_aftercopyimage"], basetmpdir)
|
80
|
+
call_hook("hook_aftercopyimage", basetmpdir)
|
84
81
|
|
85
|
-
@
|
86
|
-
@
|
82
|
+
@producer.import_imageinfo("#{basetmpdir}/images", basetmpdir)
|
83
|
+
@producer.import_imageinfo("#{basetmpdir}/fonts", basetmpdir, @params["font_ext"])
|
87
84
|
|
88
|
-
epubtmpdir =
|
89
|
-
|
85
|
+
epubtmpdir = nil
|
86
|
+
if @params["debug"].present?
|
87
|
+
epubtmpdir = "#{Dir.pwd}/#{booktmpname}"
|
88
|
+
Dir.mkdir(epubtmpdir)
|
89
|
+
end
|
90
90
|
log("Call ePUB producer.")
|
91
|
-
@
|
91
|
+
@producer.produce("#{bookname}.epub", basetmpdir, epubtmpdir)
|
92
92
|
log("Finished.")
|
93
93
|
ensure
|
94
94
|
FileUtils.remove_entry_secure basetmpdir if @params["debug"].nil?
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
def call_hook(
|
99
|
-
|
98
|
+
def call_hook(hook_name, *params)
|
99
|
+
filename = @params["epubmaker"][hook_name]
|
100
|
+
log("Call #{hook_name}. (#{filename})")
|
101
|
+
if filename.present? && File.exist?(filename) && FileTest.executable?(filename)
|
100
102
|
if ENV["REVIEW_SAFE_MODE"].to_i & 1 > 0
|
101
103
|
warn "hook is prohibited in safe mode. ignored."
|
102
104
|
else
|
@@ -106,7 +108,7 @@ module ReVIEW
|
|
106
108
|
end
|
107
109
|
|
108
110
|
def verify_target_images(basetmpdir)
|
109
|
-
@
|
111
|
+
@producer.contents.each do |content|
|
110
112
|
if content.media == "application/xhtml+xml"
|
111
113
|
|
112
114
|
File.open("#{basetmpdir}/#{content.file}") do |f|
|
@@ -133,15 +135,15 @@ module ReVIEW
|
|
133
135
|
def copy_images(resdir, destdir, allow_exts=nil)
|
134
136
|
return nil unless File.exist?(resdir)
|
135
137
|
allow_exts = @params["image_ext"] if allow_exts.nil?
|
136
|
-
FileUtils.mkdir_p(destdir)
|
137
|
-
if
|
138
|
+
FileUtils.mkdir_p(destdir)
|
139
|
+
if @params["epubmaker"]["verify_target_images"].present?
|
138
140
|
@params["epubmaker"]["force_include_images"].each do |file|
|
139
141
|
unless File.exist?(file)
|
140
142
|
warn "#{file} is not found, skip." if file !~ /\Ahttp[s]?:/
|
141
143
|
next
|
142
144
|
end
|
143
145
|
basedir = File.dirname(file)
|
144
|
-
FileUtils.mkdir_p("#{destdir}/#{basedir}")
|
146
|
+
FileUtils.mkdir_p("#{destdir}/#{basedir}")
|
145
147
|
log("Copy #{file} to the temporary directory.")
|
146
148
|
FileUtils.cp(file, "#{destdir}/#{basedir}")
|
147
149
|
end
|
@@ -153,7 +155,7 @@ module ReVIEW
|
|
153
155
|
def copy_resources(resdir, destdir, allow_exts=nil)
|
154
156
|
return nil unless File.exist?(resdir)
|
155
157
|
allow_exts = @params["image_ext"] if allow_exts.nil?
|
156
|
-
FileUtils.mkdir_p(destdir)
|
158
|
+
FileUtils.mkdir_p(destdir)
|
157
159
|
recursive_copy_files(resdir, destdir, allow_exts)
|
158
160
|
end
|
159
161
|
|
@@ -165,7 +167,7 @@ module ReVIEW
|
|
165
167
|
recursive_copy_files("#{resdir}/#{fname}", "#{destdir}/#{fname}", allow_exts)
|
166
168
|
else
|
167
169
|
if fname =~ /\.(#{allow_exts.join("|")})\Z/i
|
168
|
-
FileUtils.mkdir_p(destdir)
|
170
|
+
FileUtils.mkdir_p(destdir)
|
169
171
|
log("Copy #{resdir}/#{fname} to the temporary directory.")
|
170
172
|
FileUtils.cp("#{resdir}/#{fname}", destdir)
|
171
173
|
end
|
@@ -235,7 +237,7 @@ EOT
|
|
235
237
|
filename = ""
|
236
238
|
|
237
239
|
chaptype = "body"
|
238
|
-
if
|
240
|
+
if ispart.present?
|
239
241
|
chaptype = "part"
|
240
242
|
elsif chap.on_PREDEF?
|
241
243
|
chaptype = "pre"
|
@@ -243,7 +245,7 @@ EOT
|
|
243
245
|
chaptype = "post"
|
244
246
|
end
|
245
247
|
|
246
|
-
if
|
248
|
+
if ispart.present?
|
247
249
|
filename = chap.path
|
248
250
|
else
|
249
251
|
filename = Pathname.new(chap.path).relative_path_from(base_path).to_s
|
@@ -316,7 +318,7 @@ EOT
|
|
316
318
|
end
|
317
319
|
first = true
|
318
320
|
headlines.each do |headline|
|
319
|
-
headline["level"] = 0 if
|
321
|
+
headline["level"] = 0 if ispart.present? && headline["level"] == 1
|
320
322
|
if first.nil?
|
321
323
|
write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}##{headline["id"]}\t#{headline["title"]}\tchaptype=#{chaptype}")
|
322
324
|
else
|
@@ -334,7 +336,7 @@ EOT
|
|
334
336
|
chaptype = nil
|
335
337
|
properties = nil
|
336
338
|
level, file, title, custom = l.chomp.split("\t")
|
337
|
-
|
339
|
+
if custom.present?
|
338
340
|
# custom setting
|
339
341
|
vars = custom.split(/,\s*/)
|
340
342
|
vars.each do |var|
|
@@ -361,7 +363,7 @@ EOT
|
|
361
363
|
if properties.present?
|
362
364
|
hash["properties"] = properties.split(" ")
|
363
365
|
end
|
364
|
-
@
|
366
|
+
@producer.contents.push(Content.new(hash))
|
365
367
|
end
|
366
368
|
end
|
367
369
|
end
|
@@ -370,13 +372,13 @@ EOT
|
|
370
372
|
if @params["stylesheet"].size > 0
|
371
373
|
@params["stylesheet"].each do |sfile|
|
372
374
|
FileUtils.cp(sfile, basetmpdir)
|
373
|
-
@
|
375
|
+
@producer.contents.push(Content.new("file" => sfile))
|
374
376
|
end
|
375
377
|
end
|
376
378
|
end
|
377
379
|
|
378
380
|
def copy_frontmatter(basetmpdir)
|
379
|
-
FileUtils.cp(@params["cover"], "#{basetmpdir}/#{File.basename(@params["cover"])}") if
|
381
|
+
FileUtils.cp(@params["cover"], "#{basetmpdir}/#{File.basename(@params["cover"])}") if @params["cover"].present? && File.exist?(@params["cover"])
|
380
382
|
|
381
383
|
if @params["titlepage"]
|
382
384
|
if @params["titlefile"].nil?
|
@@ -384,17 +386,17 @@ EOT
|
|
384
386
|
else
|
385
387
|
FileUtils.cp(@params["titlefile"], "#{basetmpdir}/titlepage.#{@params["htmlext"]}")
|
386
388
|
end
|
387
|
-
write_tochtmltxt(basetmpdir, "1\ttitlepage.#{@params["htmlext"]}\t#{@
|
389
|
+
write_tochtmltxt(basetmpdir, "1\ttitlepage.#{@params["htmlext"]}\t#{@producer.res.v("titlepagetitle")}\tchaptype=pre")
|
388
390
|
end
|
389
391
|
|
390
|
-
if
|
392
|
+
if @params["originaltitlefile"].present? && File.exist?(@params["originaltitlefile"])
|
391
393
|
FileUtils.cp(@params["originaltitlefile"], "#{basetmpdir}/#{File.basename(@params["originaltitlefile"])}")
|
392
|
-
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["originaltitlefile"])}\t#{@
|
394
|
+
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["originaltitlefile"])}\t#{@producer.res.v("originaltitle")}\tchaptype=pre")
|
393
395
|
end
|
394
396
|
|
395
|
-
if
|
397
|
+
if @params["creditfile"].present? && File.exist?(@params["creditfile"])
|
396
398
|
FileUtils.cp(@params["creditfile"], "#{basetmpdir}/#{File.basename(@params["creditfile"])}")
|
397
|
-
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["creditfile"])}\t#{@
|
399
|
+
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["creditfile"])}\t#{@producer.res.v("credittitle")}\tchaptype=pre")
|
398
400
|
end
|
399
401
|
end
|
400
402
|
|
@@ -427,26 +429,26 @@ EOT
|
|
427
429
|
def copy_backmatter(basetmpdir)
|
428
430
|
if @params["profile"]
|
429
431
|
FileUtils.cp(@params["profile"], "#{basetmpdir}/#{File.basename(@params["profile"])}")
|
430
|
-
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["profile"])}\t#{@
|
432
|
+
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["profile"])}\t#{@producer.res.v("profiletitle")}\tchaptype=post")
|
431
433
|
end
|
432
434
|
|
433
435
|
if @params["advfile"]
|
434
436
|
FileUtils.cp(@params["advfile"], "#{basetmpdir}/#{File.basename(@params["advfile"])}")
|
435
|
-
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["advfile"])}\t#{@
|
437
|
+
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["advfile"])}\t#{@producer.res.v("advtitle")}\tchaptype=post")
|
436
438
|
end
|
437
439
|
|
438
440
|
if @params["colophon"]
|
439
441
|
if @params["colophon"].instance_of?(String) # FIXME:このやり方はやめる?
|
440
442
|
FileUtils.cp(@params["colophon"], "#{basetmpdir}/colophon.#{@params["htmlext"]}")
|
441
443
|
else
|
442
|
-
File.open("#{basetmpdir}/colophon.#{@params["htmlext"]}", "w") {|f| @
|
444
|
+
File.open("#{basetmpdir}/colophon.#{@params["htmlext"]}", "w") {|f| @producer.colophon(f) }
|
443
445
|
end
|
444
|
-
write_tochtmltxt(basetmpdir, "1\tcolophon.#{@params["htmlext"]}\t#{@
|
446
|
+
write_tochtmltxt(basetmpdir, "1\tcolophon.#{@params["htmlext"]}\t#{@producer.res.v("colophontitle")}\tchaptype=post")
|
445
447
|
end
|
446
448
|
|
447
449
|
if @params["backcover"]
|
448
450
|
FileUtils.cp(@params["backcover"], "#{basetmpdir}/#{File.basename(@params["backcover"])}")
|
449
|
-
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["backcover"])}\t#{@
|
451
|
+
write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["backcover"])}\t#{@producer.res.v("backcovertitle")}\tchaptype=post")
|
450
452
|
end
|
451
453
|
end
|
452
454
|
|
@@ -515,15 +517,15 @@ EOT
|
|
515
517
|
|
516
518
|
def tag_start(name, attrs)
|
517
519
|
if name =~ /\Ah(\d+)/
|
518
|
-
|
520
|
+
if @level.present?
|
519
521
|
raise "#{name}, #{attrs}"
|
520
522
|
end
|
521
523
|
@level = $1.to_i
|
522
|
-
@id = attrs["id"] if
|
524
|
+
@id = attrs["id"] if attrs["id"].present?
|
523
525
|
elsif !@level.nil?
|
524
|
-
if name == "img" &&
|
526
|
+
if name == "img" && attrs["alt"].present?
|
525
527
|
@content << attrs["alt"]
|
526
|
-
elsif name == "a" &&
|
528
|
+
elsif name == "a" && attrs["id"].present?
|
527
529
|
@id = attrs["id"]
|
528
530
|
end
|
529
531
|
end
|
@@ -531,7 +533,7 @@ EOT
|
|
531
533
|
|
532
534
|
def tag_end(name)
|
533
535
|
if name =~ /\Ah\d+/
|
534
|
-
@headlines.push({"level" => @level, "id" => @id, "title" => @content})
|
536
|
+
@headlines.push({"level" => @level, "id" => @id, "title" => @content}) if @id.present?
|
535
537
|
@content = ""
|
536
538
|
@level = nil
|
537
539
|
@id = nil
|
@@ -539,7 +541,7 @@ EOT
|
|
539
541
|
end
|
540
542
|
|
541
543
|
def text(text)
|
542
|
-
|
544
|
+
if @level.present?
|
543
545
|
@content << text.gsub("\t", " ") # FIXME:区切り文字
|
544
546
|
end
|
545
547
|
end
|
data/lib/review/htmlbuilder.rb
CHANGED
@@ -193,6 +193,9 @@ EOT
|
|
193
193
|
|
194
194
|
def headline(level, label, caption)
|
195
195
|
prefix, anchor = headline_prefix(level)
|
196
|
+
unless prefix.nil?
|
197
|
+
prefix = %Q[<span class="secno">#{prefix}</span>]
|
198
|
+
end
|
196
199
|
puts '' if level > 1
|
197
200
|
a_id = ""
|
198
201
|
unless anchor.nil?
|
@@ -453,10 +456,10 @@ EOT
|
|
453
456
|
puts '</pre>'
|
454
457
|
end
|
455
458
|
|
456
|
-
def source(lines, caption = nil)
|
459
|
+
def source(lines, caption = nil, lang = nil)
|
457
460
|
puts %Q[<div class="source-code">]
|
458
461
|
source_header caption
|
459
|
-
source_body caption, lines
|
462
|
+
source_body caption, lines, lang
|
460
463
|
puts '</div>'
|
461
464
|
end
|
462
465
|
|
@@ -466,11 +469,11 @@ EOT
|
|
466
469
|
end
|
467
470
|
end
|
468
471
|
|
469
|
-
def source_body(id, lines)
|
472
|
+
def source_body(id, lines, lang)
|
470
473
|
id ||= ''
|
471
474
|
print %Q[<pre class="source">]
|
472
475
|
body = lines.inject(''){|i, j| i + detab(j) + "\n"}
|
473
|
-
lexer = File.extname(id).gsub(/\./, '')
|
476
|
+
lexer = lang || File.extname(id).gsub(/\./, '')
|
474
477
|
puts highlight(:body => body, :lexer => lexer, :format => 'html')
|
475
478
|
puts '</pre>'
|
476
479
|
end
|
@@ -942,9 +945,9 @@ QUOTE
|
|
942
945
|
def inline_hd_chap(chap, id)
|
943
946
|
n = chap.headline_index.number(id)
|
944
947
|
if chap.number and @book.config["secnolevel"] >= n.split('.').size
|
945
|
-
str = "
|
948
|
+
str = I18n.t("chapter_quote", "#{n} #{compile_inline(chap.headline(id).caption)}")
|
946
949
|
else
|
947
|
-
str = "
|
950
|
+
str = I18n.t("chapter_quote", compile_inline(chap.headline(id).caption))
|
948
951
|
end
|
949
952
|
if @book.config["chapterlink"]
|
950
953
|
anchor = "h"+n.gsub(/\./, "-")
|