review 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/doc/sample.yml CHANGED
@@ -89,7 +89,10 @@ secnolevel: 2
89
89
  # 部番号を表示する見出しレベル(未実装)
90
90
  # part_secnolevel: 1
91
91
 
92
- # EPUB2標準の目次以外に物理目次ファイルを作成するか。省略した場合はnull (作成しない)
92
+ # 本文中に目次ページを作成するか。省略した場合はnull (作成しない)
93
+ # toc: true
94
+
95
+ # EPUB2標準の目次(NCX)以外に物理目次ファイルを作成するか。省略した場合はnull (作成しない)
93
96
  # ePUB3においてはこの設定によらず必ず作成される
94
97
  # mytoc: true
95
98
 
@@ -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
- Dir.mkdir("#{tmpdir}/META-INF") unless File.exist?("#{tmpdir}/META-INF")
393
+ FileUtils.mkdir_p("#{tmpdir}/META-INF")
393
394
  File.open("#{tmpdir}/META-INF/container.xml", "w") {|f| @producer.container(f) }
394
395
 
395
- Dir.mkdir("#{tmpdir}/OEBPS") unless File.exist?("#{tmpdir}/OEBPS")
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}")) unless File.exist?(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)
@@ -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 =~ /#{@producer.params["coverimage"]}\Z/
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
@@ -268,7 +268,7 @@ module EPUBMaker
268
268
  end
269
269
  end
270
270
 
271
- @params["htmlversion"] == 5 if @params["epubversion"] >= 3
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?
@@ -93,7 +93,7 @@ module ReVIEW
93
93
 
94
94
  private
95
95
  def on_FILE?(contents)
96
- contents.lines.map(&:strip).include?(id() + @book.ext())
96
+ contents.lines.map(&:strip).include?("#{id()}#{@book.ext()}")
97
97
  end
98
98
  end
99
99
  end
@@ -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
@@ -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 "#{chapter.number}"
347
+ return chapter.format_number(nil)
348
348
  end
349
349
  return nil
350
350
  end
@@ -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..1
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
@@ -18,20 +18,20 @@ module ReVIEW
18
18
  include REXML
19
19
 
20
20
  def initialize
21
- @epub = nil
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 unless @params["debug"].nil?
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
- @epub = Producer.new(@params)
33
- @epub.load(yamlfile)
34
- @params = @epub.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
- File.unlink("#{bookname}.epub") if File.exist?("#{bookname}.epub")
46
- FileUtils.rm_rf(booktmpname) if @params["debug"] && File.exist?(booktmpname)
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
- log("Call hook_beforeprocess. (#{@params["epubmaker"]["hook_beforeprocess"]})")
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
- log("Call hook_afterfrontmatter. (#{@params["epubmaker"]["hook_afterfrontmatter"]})")
59
- call_hook(@params["epubmaker"]["hook_afterfrontmatter"], basetmpdir)
58
+ call_hook("hook_afterfrontmatter", basetmpdir)
60
59
 
61
60
  build_body(basetmpdir, yamlfile)
62
- log("Call hook_afterbody. (#{@params["epubmaker"]["hook_afterbody"]})")
63
- call_hook(@params["epubmaker"]["hook_afterbody"], basetmpdir)
61
+ call_hook("hook_afterbody", basetmpdir)
64
62
 
65
63
  copy_backmatter(basetmpdir)
66
- log("Call hook_afterbackmatter. (#{@params["epubmaker"]["hook_afterbackmatter"]})")
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 !@params["epubmaker"]["verify_target_images"].nil?
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
- log("Call hook_aftercopyimage. (#{@params["epubmaker"]["hook_aftercopyimage"]})")
83
- call_hook(@params["epubmaker"]["hook_aftercopyimage"], basetmpdir)
80
+ call_hook("hook_aftercopyimage", basetmpdir)
84
81
 
85
- @epub.import_imageinfo("#{basetmpdir}/images", basetmpdir)
86
- @epub.import_imageinfo("#{basetmpdir}/fonts", basetmpdir, @params["font_ext"])
82
+ @producer.import_imageinfo("#{basetmpdir}/images", basetmpdir)
83
+ @producer.import_imageinfo("#{basetmpdir}/fonts", basetmpdir, @params["font_ext"])
87
84
 
88
- epubtmpdir = @params["debug"].nil? ? nil : "#{Dir.pwd}/#{booktmpname}"
89
- Dir.mkdir(booktmpname) unless @params["debug"].nil?
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
- @epub.produce("#{bookname}.epub", basetmpdir, epubtmpdir)
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(filename, *params)
99
- if !filename.nil? && File.exist?(filename) && FileTest.executable?(filename)
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
- @epub.contents.each do |content|
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) unless FileTest.directory?(destdir)
137
- if !@params["epubmaker"]["verify_target_images"].nil?
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}") unless FileTest.directory?("#{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) unless FileTest.directory?(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) unless File.exist?(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 !ispart.nil?
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 !ispart.nil?
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 !ispart.nil? && headline["level"] == 1
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
- unless custom.nil?
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
- @epub.contents.push(Content.new(hash))
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
- @epub.contents.push(Content.new("file" => sfile))
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 !@params["cover"].nil? && File.exist?(@params["cover"])
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#{@epub.res.v("titlepagetitle")}\tchaptype=pre")
389
+ write_tochtmltxt(basetmpdir, "1\ttitlepage.#{@params["htmlext"]}\t#{@producer.res.v("titlepagetitle")}\tchaptype=pre")
388
390
  end
389
391
 
390
- if !@params["originaltitlefile"].nil? && File.exist?(@params["originaltitlefile"])
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#{@epub.res.v("originaltitle")}\tchaptype=pre")
394
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["originaltitlefile"])}\t#{@producer.res.v("originaltitle")}\tchaptype=pre")
393
395
  end
394
396
 
395
- if !@params["creditfile"].nil? && File.exist?(@params["creditfile"])
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#{@epub.res.v("credittitle")}\tchaptype=pre")
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#{@epub.res.v("profiletitle")}\tchaptype=post")
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#{@epub.res.v("advtitle")}\tchaptype=post")
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| @epub.colophon(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#{@epub.res.v("colophontitle")}\tchaptype=post")
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#{@epub.res.v("backcovertitle")}\tchaptype=post")
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
- unless @level.nil?
520
+ if @level.present?
519
521
  raise "#{name}, #{attrs}"
520
522
  end
521
523
  @level = $1.to_i
522
- @id = attrs["id"] if !attrs["id"].nil?
524
+ @id = attrs["id"] if attrs["id"].present?
523
525
  elsif !@level.nil?
524
- if name == "img" && !attrs["alt"].nil?
526
+ if name == "img" && attrs["alt"].present?
525
527
  @content << attrs["alt"]
526
- elsif name == "a" && !attrs["id"].nil?
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}) unless @id.nil?
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
- unless @level.nil?
544
+ if @level.present?
543
545
  @content << text.gsub("\t", " ") # FIXME:区切り文字
544
546
  end
545
547
  end
@@ -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 = "「#{n} #{compile_inline(chap.headline(id).caption)}"
948
+ str = I18n.t("chapter_quote", "#{n} #{compile_inline(chap.headline(id).caption)}")
946
949
  else
947
- str = "「#{compile_inline(chap.headline(id).caption)}」"
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(/\./, "-")