review 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +1 -0
  4. data/ChangeLog +87 -0
  5. data/bin/review-check +2 -2
  6. data/bin/review-compile +15 -30
  7. data/bin/review-index +1 -1
  8. data/bin/review-init +12 -7
  9. data/bin/review-vol +9 -1
  10. data/doc/catalog.ja.md +53 -0
  11. data/doc/catalog.md +52 -0
  12. data/doc/format.ja.md +734 -0
  13. data/doc/format.md +746 -0
  14. data/doc/format_idg.ja.md +203 -0
  15. data/doc/{quickstart.rdoc → quickstart.ja.md} +138 -104
  16. data/doc/quickstart.md +252 -0
  17. data/doc/sample.yml +216 -48
  18. data/lib/epubmaker.rb +0 -1
  19. data/lib/epubmaker/content.rb +2 -2
  20. data/lib/epubmaker/epubcommon.rb +440 -0
  21. data/lib/epubmaker/epubv2.rb +8 -418
  22. data/lib/epubmaker/epubv3.rb +67 -61
  23. data/lib/epubmaker/producer.rb +60 -19
  24. data/lib/review/book.rb +1 -3
  25. data/lib/review/book/base.rb +18 -11
  26. data/lib/review/book/chapter.rb +5 -24
  27. data/lib/review/book/compilable.rb +5 -1
  28. data/lib/review/book/index.rb +48 -17
  29. data/lib/review/book/page_metric.rb +17 -8
  30. data/lib/review/book/part.rb +12 -2
  31. data/lib/review/book/volume.rb +3 -2
  32. data/lib/review/builder.rb +30 -10
  33. data/lib/review/compiler.rb +6 -4
  34. data/lib/review/configure.rb +3 -3
  35. data/lib/review/epubmaker.rb +56 -26
  36. data/lib/review/htmlbuilder.rb +33 -42
  37. data/lib/review/htmlutils.rb +12 -7
  38. data/lib/review/i18n.rb +77 -17
  39. data/lib/review/i18n.yml +80 -4
  40. data/lib/review/idgxmlbuilder.rb +27 -57
  41. data/lib/review/inaobuilder.rb +3 -3
  42. data/lib/review/latexbuilder.rb +90 -67
  43. data/lib/review/layout.tex.erb +54 -7
  44. data/lib/review/markdownbuilder.rb +21 -3
  45. data/lib/review/pdfmaker.rb +67 -38
  46. data/lib/review/sec_counter.rb +1 -1
  47. data/lib/review/tocparser.rb +9 -5
  48. data/lib/review/topbuilder.rb +6 -6
  49. data/lib/review/version.rb +1 -1
  50. data/review.gemspec +3 -1
  51. data/test/book_test_helper.rb +1 -1
  52. data/test/sample-book/README.md +2 -0
  53. data/test/sample-book/src/Rakefile +31 -0
  54. data/test/sample-book/src/_cover.html +0 -0
  55. data/test/sample-book/src/catalog.yml +10 -0
  56. data/test/sample-book/src/ch01.re +0 -0
  57. data/test/sample-book/src/ch02.re +0 -0
  58. data/test/sample-book/src/config.yml +160 -32
  59. data/test/sample-book/src/images/ch01-imgsample.jpg +0 -0
  60. data/test/sample-book/src/images/cover.jpg +0 -0
  61. data/test/sample-book/src/preface.re +0 -0
  62. data/test/sample-book/src/sty/jumoline.sty +0 -0
  63. data/test/sample-book/src/sty/reviewmacro.sty +18 -0
  64. data/test/sample-book/src/style.css +0 -0
  65. data/test/test_book.rb +25 -27
  66. data/test/test_book_chapter.rb +4 -73
  67. data/test/test_book_part.rb +5 -4
  68. data/test/test_builder.rb +3 -3
  69. data/test/test_epub3maker.rb +527 -0
  70. data/test/test_epubmaker.rb +6 -6
  71. data/test/test_htmlbuilder.rb +143 -6
  72. data/test/test_i18n.rb +95 -10
  73. data/test/test_idgxmlbuilder.rb +28 -2
  74. data/test/test_index.rb +109 -1
  75. data/test/test_latexbuilder.rb +51 -0
  76. data/test/test_markdownbuilder.rb +54 -1
  77. data/test/test_pdfmaker.rb +7 -6
  78. data/test/test_review_ext.rb +31 -0
  79. data/test/test_topbuilder.rb +3 -1
  80. metadata +46 -13
  81. data/doc/catalog.rdoc +0 -49
  82. data/doc/format.rdoc +0 -618
  83. data/doc/format_idg.rdoc +0 -180
  84. data/doc/libepubmaker/config.yml +0 -207
  85. data/lib/epubmaker/resource.rb +0 -82
  86. data/test/sample-book/src/CHAPS +0 -2
  87. data/test/sample-book/src/PREDEF +0 -1
@@ -59,7 +59,11 @@ module ReVIEW
59
59
  end
60
60
 
61
61
  def volume
62
- @volume ||= Volume.count_file(path())
62
+ if !@volume
63
+ @volume = Volume.count_file(path())
64
+ @volume.page_per_kbyte = @book.page_metric.page_per_kbyte
65
+ end
66
+ @volume
63
67
  end
64
68
 
65
69
  def open(&block)
@@ -12,6 +12,7 @@
12
12
  require 'review/extentions'
13
13
  require 'review/exception'
14
14
  require 'review/book/image_finder'
15
+ require 'review/i18n'
15
16
 
16
17
  module ReVIEW
17
18
  module Book
@@ -56,11 +57,21 @@ module ReVIEW
56
57
  def [](id)
57
58
  @index.fetch(id)
58
59
  rescue
60
+ if @index.keys.map{|i| i.split(/\|/) }.flatten. # unfold all ids
61
+ reduce(Hash.new(0)){|h, i| h[i] += 1; h}. # number of occurrences
62
+ select{|k, v| k == id && v > 1 }.present? # detect duplicated
63
+ raise KeyError, "key '#{id}' is ambiguous for #{self.class}"
64
+ end
65
+ @items.each do |i|
66
+ if i.id.split(/\|/).include?(id)
67
+ return i
68
+ end
69
+ end
59
70
  raise KeyError, "not found key '#{id}' for #{self.class}"
60
71
  end
61
72
 
62
73
  def number(id)
63
- @index.fetch(id).number.to_s
74
+ self[id].number.to_s
64
75
  end
65
76
 
66
77
  def each(&block)
@@ -92,7 +103,7 @@ module ReVIEW
92
103
  end
93
104
 
94
105
  def display_string(id)
95
- "#{number(id)}「#{title(id)}"
106
+ "#{number(id)}#{I18n.t("chapter_quote", title(id))}"
96
107
  end
97
108
  end
98
109
 
@@ -131,16 +142,35 @@ module ReVIEW
131
142
 
132
143
 
133
144
  class ImageIndex < Index
145
+ def self.parse(src, *args)
146
+ items = []
147
+ seq = 1
148
+ src.grep(%r<^//#{item_type()}>) do |line|
149
+ # ex. ["//image", "id", "", "caption"]
150
+ elements = line.split(/\[(.*?)\]/)
151
+ if elements[1].present?
152
+ items.push item_class().new(elements[1], seq, elements[3])
153
+ seq += 1
154
+ if elements[1] == ""
155
+ warn "warning: no ID of #{item_type()} in #{line}"
156
+ end
157
+ end
158
+ end
159
+ new(items, *args)
160
+ end
161
+
134
162
  class Item
135
163
 
136
- def initialize(id, number)
164
+ def initialize(id, number, caption = nil)
137
165
  @id = id
138
166
  @number = number
167
+ @caption = caption
139
168
  @path = nil
140
169
  end
141
170
 
142
171
  attr_reader :id
143
172
  attr_reader :number
173
+ attr_reader :caption
144
174
  attr_writer :index # internal use only
145
175
 
146
176
  def bound?
@@ -150,7 +180,6 @@ module ReVIEW
150
180
  def path
151
181
  @path ||= @index.find_path(id)
152
182
  end
153
-
154
183
  end
155
184
 
156
185
  def ImageIndex.item_type
@@ -175,7 +204,6 @@ module ReVIEW
175
204
  def find_path(id)
176
205
  @image_finder.find_path(id)
177
206
  end
178
-
179
207
  end
180
208
 
181
209
  class IconIndex < ImageIndex
@@ -251,11 +279,6 @@ module ReVIEW
251
279
 
252
280
  class NumberlessImageIndex < ImageIndex
253
281
  class Item < ImageIndex::Item
254
- def initialize(id, number)
255
- @id = id
256
- @number = ""
257
- @path = nil
258
- end
259
282
  end
260
283
 
261
284
  def NumberlessImageIndex.item_type
@@ -269,11 +292,6 @@ module ReVIEW
269
292
 
270
293
  class IndepImageIndex < ImageIndex
271
294
  class Item < ImageIndex::Item
272
- def initialize(id, number)
273
- @id = id
274
- @number = ""
275
- @path = nil
276
- end
277
295
  end
278
296
 
279
297
  def IndepImageIndex.item_type
@@ -309,7 +327,7 @@ module ReVIEW
309
327
  inside_column = false
310
328
  next
311
329
  end
312
- if indexs.present? and indexs[-1] <= index
330
+ if indexs.blank? || index <= indexs[-1]
313
331
  inside_column = false
314
332
  end
315
333
  if inside_column
@@ -344,7 +362,20 @@ module ReVIEW
344
362
  end
345
363
 
346
364
  def number(id)
347
- return ([@chap.number] + @index.fetch(id).number).join(".")
365
+ n = @chap.number
366
+ if @chap.on_APPENDIX? && @chap.number > 0 && @chap.number < 28
367
+ type = @chap.book.config["appendix_format"].blank? ? "arabic" : @chap.book.config["appendix_format"].downcase.strip
368
+ n = case type
369
+ when "roman"
370
+ ROMAN[@chap.number]
371
+ when "alphabet", "alpha"
372
+ ALPHA[@chap.number]
373
+ else
374
+ # nil, "arabic", etc...
375
+ "#{@chap.number}"
376
+ end
377
+ end
378
+ return ([n] + self[id].number).join(".")
348
379
  end
349
380
  end
350
381
 
@@ -15,24 +15,33 @@ module ReVIEW
15
15
 
16
16
  MetricData = Struct.new(:n_lines, :n_columns)
17
17
 
18
- def PageMetric.a5
19
- new(46, 80, 30, 74, 1)
20
- end
21
-
22
- def PageMetric.b5
23
- new(46, 80, 30, 74, 2)
24
- end
25
-
26
18
  def initialize(list_lines, list_columns, text_lines, text_columns, page_per_kbyte)
27
19
  @list = MetricData.new(list_lines, list_columns)
28
20
  @text = MetricData.new(text_lines, text_columns)
29
21
  @page_per_kbyte = page_per_kbyte
30
22
  end
31
23
 
24
+ A5 = PageMetric.new(46, 80, 30, 74, 1)
25
+ B5 = PageMetric.new(46, 80, 30, 74, 2)
26
+
27
+ # backward compatible
28
+ def PageMetric.a5
29
+ ReVIEW::Book::PageMetric::A5
30
+ end
31
+
32
+ # backward compatible
33
+ def PageMetric.b5
34
+ ReVIEW::Book::PageMetric::B5
35
+ end
36
+
32
37
  attr_reader :list
33
38
  attr_reader :text
34
39
  attr_reader :page_per_kbyte
35
40
 
41
+ def ==(other)
42
+ self.list == other.list && self.text == other.text && self.page_per_kbyte == other.page_per_kbyte
43
+ end
44
+
36
45
  end
37
46
  end
38
47
  end
@@ -2,7 +2,7 @@
2
2
  # $Id: book.rb 4315 2009-09-02 04:15:24Z kmuto $
3
3
  #
4
4
  # Copyright (c) 2002-2008 Minero Aoki
5
- # 2009 Minero Aoki, Kenshi Muto
5
+ # 2009-2014 Minero Aoki, Kenshi Muto
6
6
  #
7
7
  # This program is free software.
8
8
  # You can distribute or modify this program under the terms of
@@ -32,13 +32,23 @@ module ReVIEW
32
32
  end
33
33
 
34
34
  def volume
35
- Volume.sum(@chapters.map {|chap| chap.volume })
35
+ vol = Volume.sum(@chapters.map {|chap| chap.volume })
36
+ vol.page_per_kbyte = @book.page_metric.page_per_kbyte
37
+ vol
36
38
  end
37
39
 
38
40
  def file?
39
41
  (name.present? and path =~ /\.re\z/) ? true : false
40
42
  end
41
43
 
44
+ def format_number(heading = true)
45
+ if heading
46
+ "#{I18n.t("part", @number)}"
47
+ else
48
+ "#{@number}"
49
+ end
50
+ end
51
+
42
52
  end
43
53
  end
44
54
  end
@@ -36,19 +36,20 @@ module ReVIEW
36
36
  @bytes = bytes
37
37
  @chars = chars
38
38
  @lines = lines
39
- @book = ReVIEW::Book::Base.load_default
39
+ @page_per_kbyte = nil
40
40
  end
41
41
 
42
42
  attr_reader :bytes
43
43
  attr_reader :chars
44
44
  attr_accessor :lines
45
+ attr_accessor :page_per_kbyte
45
46
 
46
47
  def kbytes
47
48
  (@bytes.to_f / 1024).ceil
48
49
  end
49
50
 
50
51
  def page
51
- (kbytes.to_f/@book.page_metric.page_per_kbyte).ceil
52
+ (kbytes.to_f/@page_per_kbyte).ceil
52
53
  end
53
54
 
54
55
  def to_s
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # Copyright (c) 2002-2009 Minero Aoki
3
+ # Copyright (c) 2002-2014 Minero Aoki, Kenshi Muto
4
4
  #
5
5
  # This program is free software.
6
6
  # You can distribute or modify this program under the terms of
@@ -11,6 +11,7 @@ require 'review/book/index'
11
11
  require 'review/exception'
12
12
  require 'review/textutils'
13
13
  require 'review/compiler'
14
+ require 'review/sec_counter'
14
15
  require 'stringio'
15
16
  require 'cgi'
16
17
 
@@ -51,6 +52,7 @@ module ReVIEW
51
52
  end
52
53
 
53
54
  def builder_init_file
55
+ @sec_counter = SecCounter.new(5, @chapter)
54
56
  end
55
57
  private :builder_init_file
56
58
 
@@ -76,22 +78,30 @@ module ReVIEW
76
78
  self.class.to_s.gsub(/ReVIEW::/, '').gsub(/Builder/, '').downcase
77
79
  end
78
80
 
79
- def list(lines, id, caption)
81
+ def headline_prefix(level)
82
+ @sec_counter.inc(level)
83
+ anchor = @sec_counter.anchor(level)
84
+ prefix = @sec_counter.prefix(level, @book.config["secnolevel"])
85
+ [prefix, anchor]
86
+ end
87
+ private :headline_prefix
88
+
89
+ def list(lines, id, caption, lang = nil)
80
90
  begin
81
- list_header id, caption
91
+ list_header id, caption, lang
82
92
  rescue KeyError
83
93
  error "no such list: #{id}"
84
94
  end
85
- list_body id, lines
95
+ list_body id, lines, lang
86
96
  end
87
97
 
88
- def listnum(lines, id, caption)
98
+ def listnum(lines, id, caption, lang = nil)
89
99
  begin
90
- list_header id, caption
100
+ list_header id, caption, lang
91
101
  rescue KeyError
92
102
  error "no such list: #{id}"
93
103
  end
94
- listnum_body lines
104
+ listnum_body lines, lang
95
105
  end
96
106
 
97
107
  def source(lines, caption)
@@ -176,21 +186,21 @@ module ReVIEW
176
186
  end
177
187
 
178
188
  def inline_chapref(id)
179
- compile_inline @chapter.env.chapter_index.display_string(id)
189
+ compile_inline @book.chapter_index.display_string(id)
180
190
  rescue KeyError
181
191
  error "unknown chapter: #{id}"
182
192
  nofunc_text("[UnknownChapter:#{id}]")
183
193
  end
184
194
 
185
195
  def inline_chap(id)
186
- @chapter.env.chapter_index.number(id)
196
+ @book.chapter_index.number(id)
187
197
  rescue KeyError
188
198
  error "unknown chapter: #{id}"
189
199
  nofunc_text("[UnknownChapter:#{id}]")
190
200
  end
191
201
 
192
202
  def inline_title(id)
193
- compile_inline @chapter.env.chapter_index.title(id)
203
+ compile_inline @book.chapter_index.title(id)
194
204
  rescue KeyError
195
205
  error "unknown chapter: #{id}"
196
206
  nofunc_text("[UnknownChapter:#{id}]")
@@ -210,6 +220,16 @@ module ReVIEW
210
220
  nofunc_text("[UnknownImage:#{id}]")
211
221
  end
212
222
 
223
+ def inline_imgref(id)
224
+ img = inline_img(id)
225
+
226
+ if @chapter.image(id).caption
227
+ "#{img}#{I18n.t('image_quote', @chapter.image(id).caption)}"
228
+ else
229
+ img
230
+ end
231
+ end
232
+
213
233
  def inline_table(id)
214
234
  "#{I18n.t("table")}#{@chapter.table(id).number}"
215
235
  rescue KeyError
@@ -12,6 +12,7 @@ require 'review/extentions'
12
12
  require 'review/preprocessor'
13
13
  require 'review/exception'
14
14
  require 'lineinput'
15
+ require 'strscan'
15
16
 
16
17
  module ReVIEW
17
18
 
@@ -130,15 +131,15 @@ module ReVIEW
130
131
 
131
132
  defblock :read, 0
132
133
  defblock :lead, 0
133
- defblock :list, 2
134
- defblock :emlist, 0..1
134
+ defblock :list, 2..3
135
+ defblock :emlist, 0..2
135
136
  defblock :cmd, 0..1
136
137
  defblock :table, 0..2
137
138
  defblock :quote, 0
138
139
  defblock :image, 2..3, true
139
140
  defblock :source, 0..1
140
- defblock :listnum, 2
141
- defblock :emlistnum, 0..1
141
+ defblock :listnum, 2..3
142
+ defblock :emlistnum, 0..2
142
143
  defblock :bibpaper, 2..3, true
143
144
  defblock :doorquote, 1
144
145
  defblock :talk, 0
@@ -172,6 +173,7 @@ module ReVIEW
172
173
  definline :chap
173
174
  definline :title
174
175
  definline :img
176
+ definline :imgref
175
177
  definline :icon
176
178
  definline :list
177
179
  definline :table
@@ -5,7 +5,7 @@ module ReVIEW
5
5
  Configure[
6
6
  # These parameters can be overridden by YAML file.
7
7
  "bookname"=> "example", # it defines epub file name also
8
- "booktitle" => "Re:VIEW EPUBサンプル",
8
+ "booktitle" => "Re:VIEW Sample Book",
9
9
  "title" => nil,
10
10
  "aut" => nil, # author
11
11
  "prt" => nil, # printer(publisher)
@@ -27,13 +27,13 @@ module ReVIEW
27
27
  "params" => "", # specify review2html parameters
28
28
  "toclevel" => 3, # level of toc
29
29
  "secnolevel" => 2, # level of section #
30
- "posthook" => nil, # command path of post hook
31
30
  "epubversion" => 2,
32
31
  "titlepage" => true, # Use title page
33
- "toc" => true, # Use table of contents
32
+ "toc" => nil, # Use table of contents in body
34
33
  "colophon" => nil, # Use colophon
35
34
  "debug" => nil, # debug flag
36
35
  "catalogfile" => 'catalog.yml',
36
+ "language" => 'ja', # XXX default language should be JA??
37
37
 
38
38
  "chapter_file" => 'CHAPS',
39
39
  "part_file" => 'PART',
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # Copyright (c) 2010-2014 Kenshi Muto and Masayoshi Takahashi
3
+ # Copyright (c) 2010-2015 Kenshi Muto and Masayoshi Takahashi
4
4
  #
5
5
  # This program is free software.
6
6
  # You can distribute or modify this program under the terms of
@@ -36,6 +36,7 @@ module ReVIEW
36
36
 
37
37
  def produce(yamlfile, bookname=nil)
38
38
  load_yaml(yamlfile)
39
+ I18n.setup(@params["language"])
39
40
  bookname = @params["bookname"] if bookname.nil?
40
41
  booktmpname = "#{bookname}-epub"
41
42
 
@@ -48,26 +49,26 @@ module ReVIEW
48
49
  begin
49
50
  log("Created first temporary directory as #{basetmpdir}.")
50
51
 
51
- log("Call hook_beforeprocess. (#{@params["hook_beforeprocess"]})")
52
- call_hook(@params["hook_beforeprocess"], basetmpdir)
52
+ log("Call hook_beforeprocess. (#{@params["epubmaker"]["hook_beforeprocess"]})")
53
+ call_hook(@params["epubmaker"]["hook_beforeprocess"], basetmpdir)
53
54
 
54
55
  copy_stylesheet(basetmpdir)
55
56
 
56
57
  copy_frontmatter(basetmpdir)
57
- log("Call hook_afterfrontmatter. (#{@params["hook_afterfrontmatter"]})")
58
- call_hook(@params["hook_afterfrontmatter"], basetmpdir)
58
+ log("Call hook_afterfrontmatter. (#{@params["epubmaker"]["hook_afterfrontmatter"]})")
59
+ call_hook(@params["epubmaker"]["hook_afterfrontmatter"], basetmpdir)
59
60
 
60
61
  build_body(basetmpdir, yamlfile)
61
- log("Call hook_afterbody. (#{@params["hook_afterbody"]})")
62
- call_hook(@params["hook_afterbody"], basetmpdir)
62
+ log("Call hook_afterbody. (#{@params["epubmaker"]["hook_afterbody"]})")
63
+ call_hook(@params["epubmaker"]["hook_afterbody"], basetmpdir)
63
64
 
64
65
  copy_backmatter(basetmpdir)
65
- log("Call hook_afterbackmatter. (#{@params["hook_afterbackmatter"]})")
66
- call_hook(@params["hook_afterbackmatter"], basetmpdir)
66
+ log("Call hook_afterbackmatter. (#{@params["epubmaker"]["hook_afterbackmatter"]})")
67
+ call_hook(@params["epubmaker"]["hook_afterbackmatter"], basetmpdir)
67
68
 
68
69
  push_contents(basetmpdir)
69
70
 
70
- if !@params["verify_target_images"].nil?
71
+ if !@params["epubmaker"]["verify_target_images"].nil?
71
72
  verify_target_images(basetmpdir)
72
73
  copy_images(@params["imagedir"], basetmpdir)
73
74
  else
@@ -78,8 +79,8 @@ module ReVIEW
78
79
  copy_resources("adv", "#{basetmpdir}/images")
79
80
  copy_resources(@params["fontdir"], "#{basetmpdir}/fonts", @params["font_ext"])
80
81
 
81
- log("Call hook_aftercopyimage. (#{@params["hook_aftercopyimage"]})")
82
- call_hook(@params["hook_aftercopyimage"], basetmpdir)
82
+ log("Call hook_aftercopyimage. (#{@params["epubmaker"]["hook_aftercopyimage"]})")
83
+ call_hook(@params["epubmaker"]["hook_aftercopyimage"], basetmpdir)
83
84
 
84
85
  @epub.import_imageinfo("#{basetmpdir}/images", basetmpdir)
85
86
  @epub.import_imageinfo("#{basetmpdir}/fonts", basetmpdir, @params["font_ext"])
@@ -110,7 +111,7 @@ module ReVIEW
110
111
 
111
112
  File.open("#{basetmpdir}/#{content.file}") do |f|
112
113
  Document.new(File.new(f)).each_element("//img") do |e|
113
- @params["force_include_images"].push(e.attributes["src"])
114
+ @params["epubmaker"]["force_include_images"].push(e.attributes["src"])
114
115
  if e.attributes["src"] =~ /svg\Z/i
115
116
  content.properties.push("svg")
116
117
  end
@@ -120,21 +121,21 @@ module ReVIEW
120
121
  File.open("#{basetmpdir}/#{content.file}") do |f|
121
122
  f.each_line do |l|
122
123
  l.scan(/url\((.+?)\)/) do |m|
123
- @params["force_include_images"].push($1.strip)
124
+ @params["epubmaker"]["force_include_images"].push($1.strip)
124
125
  end
125
126
  end
126
127
  end
127
128
  end
128
129
  end
129
- @params["force_include_images"] = @params["force_include_images"].sort.uniq
130
+ @params["epubmaker"]["force_include_images"] = @params["epubmaker"]["force_include_images"].sort.uniq
130
131
  end
131
132
 
132
133
  def copy_images(resdir, destdir, allow_exts=nil)
133
134
  return nil unless File.exist?(resdir)
134
135
  allow_exts = @params["image_ext"] if allow_exts.nil?
135
136
  FileUtils.mkdir_p(destdir) unless FileTest.directory?(destdir)
136
- if !@params["verify_target_images"].nil?
137
- @params["force_include_images"].each do |file|
137
+ if !@params["epubmaker"]["verify_target_images"].nil?
138
+ @params["epubmaker"]["force_include_images"].each do |file|
138
139
  unless File.exist?(file)
139
140
  warn "#{file} is not found, skip." if file !~ /\Ahttp[s]?:/
140
141
  next
@@ -164,7 +165,7 @@ module ReVIEW
164
165
  recursive_copy_files("#{resdir}/#{fname}", "#{destdir}/#{fname}", allow_exts)
165
166
  else
166
167
  if fname =~ /\.(#{allow_exts.join("|")})\Z/i
167
- Dir.mkdir(destdir) unless File.exist?(destdir)
168
+ FileUtils.mkdir_p(destdir) unless File.exist?(destdir)
168
169
  log("Copy #{resdir}/#{fname} to the temporary directory.")
169
170
  FileUtils.cp("#{resdir}/#{fname}", destdir)
170
171
  end
@@ -185,7 +186,9 @@ module ReVIEW
185
186
 
186
187
  basedir = Dir.pwd
187
188
  base_path = Pathname.new(basedir)
188
- ReVIEW::Book.load(basedir).parts.each do |part|
189
+ book = ReVIEW::Book.load(basedir)
190
+ book.load_config(yamlfile)
191
+ book.parts.each do |part|
189
192
  htmlfile = nil
190
193
  if part.name.present?
191
194
  if part.file?
@@ -247,7 +250,7 @@ EOT
247
250
  end
248
251
  id = filename.sub(/\.re\Z/, "")
249
252
 
250
- if @params["rename_for_legacy"] && ispart.nil?
253
+ if @params["epubmaker"]["rename_for_legacy"] && ispart.nil?
251
254
  if chap.on_PREDEF?
252
255
  @precount += 1
253
256
  id = sprintf("pre%02d", @precount)
@@ -281,22 +284,43 @@ EOT
281
284
  stylesheet = "--stylesheet=#{@params["stylesheet"].join(",")}"
282
285
  end
283
286
 
287
+ ENV["REVIEWFNAME"] = filename
284
288
  system("#{ReVIEW::MakerHelper.bindir}/review-compile --yaml=#{yamlfile} --target=html --level=#{level} --htmlversion=#{@params["htmlversion"]} --epubversion=#{@params["epubversion"]} #{stylesheet} #{@params["params"]} #{filename} > \"#{basetmpdir}/#{htmlfile}\"")
285
289
 
286
290
  write_info_body(basetmpdir, id, htmlfile, ispart, chaptype)
287
291
  end
288
292
 
293
+ def detect_properties(path)
294
+ properties = []
295
+ File.open(path) do |f|
296
+ doc = REXML::Document.new(f)
297
+ if REXML::XPath.first(doc, "//m:math", {'m' => 'http://www.w3.org/1998/Math/MathML'})
298
+ properties<< "mathml"
299
+ end
300
+ if REXML::XPath.first(doc, "//s:svg", {'s' => 'http://www.w3.org/2000/svg'})
301
+ properties<< "svg"
302
+ end
303
+ end
304
+ properties
305
+ end
306
+
289
307
  def write_info_body(basetmpdir, id, filename, ispart=nil, chaptype=nil)
290
308
  headlines = []
291
309
  # FIXME:nonumを修正する必要あり
292
- Document.parse_stream(File.new("#{basetmpdir}/#{filename}"), ReVIEWHeaderListener.new(headlines))
310
+ path = File.join(basetmpdir, filename)
311
+ Document.parse_stream(File.new(path), ReVIEWHeaderListener.new(headlines))
312
+ properties = detect_properties(path)
313
+ prop_str = ""
314
+ if properties.present?
315
+ prop_str = ",properties="+properties.join(" ")
316
+ end
293
317
  first = true
294
318
  headlines.each do |headline|
295
319
  headline["level"] = 0 if !ispart.nil? && headline["level"] == 1
296
320
  if first.nil?
297
321
  write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}##{headline["id"]}\t#{headline["title"]}\tchaptype=#{chaptype}")
298
322
  else
299
- write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}\t#{headline["title"]}\tforce_include=true,chaptype=#{chaptype}")
323
+ write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}\t#{headline["title"]}\tforce_include=true,chaptype=#{chaptype}#{prop_str}")
300
324
  first = nil
301
325
  end
302
326
  end
@@ -308,6 +332,7 @@ EOT
308
332
  force_include = nil
309
333
  customid = nil
310
334
  chaptype = nil
335
+ properties = nil
311
336
  level, file, title, custom = l.chomp.split("\t")
312
337
  unless custom.nil?
313
338
  # custom setting
@@ -321,17 +346,22 @@ EOT
321
346
  force_include = true
322
347
  when "chaptype"
323
348
  chaptype = v
349
+ when "properties"
350
+ properties = v
324
351
  end
325
352
  end
326
353
  end
327
354
  next if level.to_i > @params["toclevel"] && force_include.nil?
328
355
  log("Push #{file} to ePUB contents.")
329
356
 
330
- if customid.nil?
331
- @epub.contents.push(Content.new("file" => file, "level" => level.to_i, "title" => title, "chaptype" => chaptype))
332
- else
333
- @epub.contents.push(Content.new("id" => customid, "file" => file, "level" => level.to_i, "title" => title, "chaptype" => chaptype))
357
+ hash = {"file" => file, "level" => level.to_i, "title" => title, "chaptype" => chaptype}
358
+ if customid.present?
359
+ hash["id"] = customid
360
+ end
361
+ if properties.present?
362
+ hash["properties"] = properties.split(" ")
334
363
  end
364
+ @epub.contents.push(Content.new(hash))
335
365
  end
336
366
  end
337
367
  end