review 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/.travis.yml +1 -2
  2. data/ChangeLog +65 -0
  3. data/Gemfile +5 -0
  4. data/README.rdoc +6 -1
  5. data/Rakefile +14 -28
  6. data/bin/review-check +9 -21
  7. data/bin/review-compile +45 -12
  8. data/bin/review-epubmaker +477 -220
  9. data/bin/review-epubmaker-ng +5 -14
  10. data/bin/review-index +4 -2
  11. data/bin/review-init +94 -0
  12. data/bin/review-pdfmaker +70 -287
  13. data/bin/review-preproc +5 -2
  14. data/bin/review-vol +4 -11
  15. data/debian/changelog +3 -3
  16. data/debian/copyright +5 -3
  17. data/debian/docs +1 -0
  18. data/doc/format.rdoc +57 -11
  19. data/doc/quickstart.rdoc +4 -4
  20. data/doc/sample.yaml +11 -7
  21. data/lib/epubmaker.rb +1 -1
  22. data/lib/epubmaker/epubv2.rb +26 -27
  23. data/lib/epubmaker/epubv3.rb +13 -13
  24. data/lib/epubmaker/producer.rb +1 -1
  25. data/lib/review.rb +3 -4
  26. data/lib/review/book.rb +17 -581
  27. data/lib/review/book/base.rb +247 -0
  28. data/lib/review/book/chapter.rb +81 -0
  29. data/lib/review/book/compilable.rb +163 -0
  30. data/lib/review/book/index.rb +339 -0
  31. data/lib/review/book/page_metric.rb +38 -0
  32. data/lib/review/book/parameters.rb +97 -0
  33. data/lib/review/book/part.rb +44 -0
  34. data/lib/review/book/volume.rb +65 -0
  35. data/lib/review/builder.rb +34 -40
  36. data/lib/review/compiler.rb +32 -13
  37. data/lib/review/configure.rb +38 -0
  38. data/lib/review/ewbbuilder.rb +23 -21
  39. data/lib/review/extentions.rb +3 -0
  40. data/lib/review/extentions/object.rb +9 -0
  41. data/lib/review/{compat.rb → extentions/string.rb} +11 -0
  42. data/lib/review/htmlbuilder.rb +162 -74
  43. data/lib/review/htmlutils.rb +28 -1
  44. data/lib/review/i18n.yaml +11 -0
  45. data/lib/review/idgxmlbuilder.rb +119 -35
  46. data/lib/review/inaobuilder.rb +355 -0
  47. data/lib/review/latexbuilder.rb +133 -59
  48. data/lib/review/latexutils.rb +15 -6
  49. data/lib/review/makerhelper.rb +59 -0
  50. data/lib/review/markdownbuilder.rb +129 -0
  51. data/lib/review/preprocessor.rb +20 -7
  52. data/lib/review/review.tex.erb +250 -0
  53. data/lib/review/textutils.rb +28 -3
  54. data/lib/review/tocparser.rb +20 -12
  55. data/lib/review/tocprinter.rb +7 -3
  56. data/lib/review/topbuilder.rb +44 -27
  57. data/lib/review/version.rb +3 -0
  58. data/review.gemspec +20 -117
  59. data/test/book_test_helper.rb +35 -0
  60. data/test/sample-book/README.md +5 -0
  61. data/test/sample-book/src/CHAPS +2 -0
  62. data/test/sample-book/src/PREDEF +1 -0
  63. data/test/sample-book/src/Rakefile +26 -0
  64. data/test/sample-book/src/_cover.html +3 -0
  65. data/test/sample-book/src/ch01.re +71 -0
  66. data/test/sample-book/src/ch02.re +3 -0
  67. data/test/sample-book/src/config.yml +55 -0
  68. data/test/sample-book/src/images/ch01-imgsample.jpg +0 -0
  69. data/test/sample-book/src/images/cover.jpg +0 -0
  70. data/test/sample-book/src/main.css +251 -0
  71. data/test/sample-book/src/preface.re +15 -0
  72. data/test/sample-book/src/sty/jumoline.sty +310 -0
  73. data/test/sample-book/src/sty/samplemacro.sty +21 -0
  74. data/test/sample-book/src/vendor/jumoline/README +29 -0
  75. data/test/sample-book/src/vendor/jumoline/jumoline.dtx +2988 -0
  76. data/test/sample-book/src/vendor/jumoline/jumoline.ins +6 -0
  77. data/test/test_book.rb +26 -646
  78. data/test/test_book_chapter.rb +418 -0
  79. data/test/test_book_parameter.rb +42 -0
  80. data/test/test_book_part.rb +53 -0
  81. data/test/test_builder.rb +17 -10
  82. data/test/test_compiler.rb +46 -0
  83. data/test/test_epubmaker.rb +1 -1
  84. data/test/test_epubmaker_cmd.rb +36 -0
  85. data/test/test_helper.rb +17 -0
  86. data/test/test_htmlbuilder.rb +156 -24
  87. data/test/test_htmlutils.rb +4 -0
  88. data/test/test_i18n.rb +6 -2
  89. data/test/test_idgxmlbuilder.rb +33 -11
  90. data/test/test_inaobuilder.rb +247 -0
  91. data/test/test_index.rb +31 -0
  92. data/test/test_latexbuilder.rb +115 -35
  93. data/test/test_makerhelper.rb +50 -0
  94. data/test/test_pdfmaker_cmd.rb +36 -0
  95. data/test/test_preprocessor.rb +7 -7
  96. data/test/test_topbuilder.rb +6 -7
  97. data/test/test_uuid.rb +1 -0
  98. metadata +117 -12
  99. data/lib/review/index.rb +0 -323
  100. data/lib/review/volume.rb +0 -66
@@ -1,8 +1,7 @@
1
1
  rvm:
2
2
  - 1.8.7
3
- - 1.9.2
4
3
  - 1.9.3
5
- - ruby-head
4
+ - 2.0.0
6
5
 
7
6
  branches:
8
7
  only:
data/ChangeLog CHANGED
@@ -1,3 +1,68 @@
1
+ Thu Aug 29 21:33:19 2013 Masayoshi Takahashi <takahashimm@gmail.com>
2
+
3
+ * Version bump to 1.1.0.
4
+
5
+ Sat Jun 29 01:34:14 2013 Masayoshi Takahashi <takahashimm@gmail.com>
6
+
7
+ * lib/review/htmlbuilder.rb, lib/review/latexbuilder.rb:
8
+
9
+ use split_paragraph for //bibpaper block.
10
+
11
+ Sat Mar 30 03:15:43 2013 Masayoshi Takahashi <takahashimm@gmail.com>
12
+
13
+ * lib/review/latexbuilder.rb, lib/review/review.tex.erb,
14
+ test/test_latexbuilder.rb:
15
+
16
+ move alltt environment into ReVIEW macros
17
+ (reviewbox, reviewemlist, reviewlist, reviewcmd,
18
+ reviewdummyimage.)
19
+
20
+ If you redefine these macros, you should add \begin{alltt}
21
+ and \end{alltt} in your definitions.
22
+
23
+ Sun Mar 24 15:55:43 2013 Kenshi Muto <kmuto@debian.org>
24
+
25
+ * lib/review/idgxmlbuilder.rb, test/test_idgxmlbuilder.rb:
26
+ support PART.
27
+
28
+ Mon Aug 27 20:27:11 2012 Kenshi Muto <kmuto@debian.org>
29
+
30
+ * lib/review/compiler.rb, lib/review/htmlbuilder.rb,
31
+ lib/review/idgxmlbuilder.rb, lib/review/latexbuilder.rb,
32
+ lib/review/topbuilder.rb, test/test_htmlbuilder.rb,
33
+ test/test_idgxmlbuilder.rb, test/test_latexbuilder.rb:
34
+ Add //centering to centerize contents.
35
+
36
+ Wed Aug 8 18:47:33 2012 Kenshi Muto <kmuto@debian.org>
37
+
38
+ * bin/review-compile, lib/review/idgxmlbuilder.rb:
39
+ Add --structuredxml option to produce structured XML for sections.
40
+
41
+ Sat Jul 14 16:07:54 2012 Masayoshi Takahashi <takahashimm@gmail.com>
42
+
43
+ * lib/review/review.tex.erb: \usepackage{jumoline} is optional
44
+
45
+ Sat Jun 16 00:57:14 2012 Masayoshi Takahashi <takahashimm@gmail.com>
46
+
47
+ * bin/review-compile, lib/review/builder.rb:
48
+ support --tabwidth=WIDTH option in review-compile
49
+
50
+ Fri Apr 20 16:07:35 2012 Kenshi Muto <kmuto@debian.org>
51
+
52
+ * lib/epubmaker/epubv*.rb: escape entity strings in meta informations.
53
+
54
+ Tue Mar 13 02:58:41 2012 Masayoshi Takahashi <takahashimm@gmail.com>
55
+
56
+ * lib/review/htmlbuilder.rb: support @<bou> in HTMLBuilder
57
+
58
+ Tue Mar 13 02:57:24 2012 Masayoshi Takahashi <takahashimm@gmail.com>
59
+
60
+ * lib/review/latexbuilder.rb: support @<ami> in LATEXBuilder
61
+
62
+ Sun Feb 12 16:06:52 2012 Masayoshi Takahashi <takahashimm@gmail.com>
63
+
64
+ * bin/review-pdfmaker: fix ebb and extractbb options for PDF as images
65
+
1
66
  Mon Jan 30 20:39:17 2012 Masayoshi Takahashi <takahashimm@gmail.com>
2
67
 
3
68
  * Version bump to 1.0.0.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in review.gemspec
4
+ gemspec
5
+
@@ -12,6 +12,7 @@ Output formats ReVIEW supports are:
12
12
  * LaTeX(ptexlive)
13
13
  * InDesign(IDGXML)
14
14
  * plain text(TOPBuilder Markup Lang.)
15
+ * Inao(gihyo.jp original markup)
15
16
 
16
17
  == Commands
17
18
 
@@ -37,10 +38,14 @@ And some useful commands.
37
38
  (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
38
39
  * Send me a pull request. Bonus points for topic branches.
39
40
 
41
+ == Build status
42
+
43
+ * {<img src="https://secure.travis-ci.org/kmuto/review.png"/>}[http://travis-ci.org/kmuto/review]
44
+
40
45
  == License
41
46
 
42
47
  LGPL. See COPYING file.
43
48
 
44
49
  == Copyright
45
50
 
46
- Copyright (c) 2006-2010 Minero Aoki, Kenshi Muto, Masayoshi Takahashi.
51
+ Copyright (c) 2006-2012 Minero Aoki, Kenshi Muto, Masayoshi Takahashi.
data/Rakefile CHANGED
@@ -1,31 +1,15 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
1
4
  require 'rubygems'
2
- require 'rake'
3
5
  require 'rake/testtask'
4
6
  require 'rake/clean'
5
7
 
6
- begin
7
- require 'jeweler'
8
- Jeweler::Tasks.new do |gem|
9
- gem.name = "review"
10
- gem.summary = %Q{ReVIEW: a easy-to-use digital publishing system}
11
- gem.description = %Q{ReVIEW is a digital publishing system for books and ebooks. It supports InDesign, EPUB and LaTeX.}
12
- gem.email = "kmuto@debian.org"
13
- gem.homepage = "http://github.com/kmuto/review"
14
- gem.authors = ["kmuto", "takahashim"]
15
- # gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
16
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
- end
18
- Jeweler::GemcutterTasks.new
19
- rescue LoadError
20
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
- end
22
-
23
-
24
8
  task :default => [:test]
25
9
 
26
10
  Rake::TestTask.new("test") do |t|
27
11
  t.libs << "test"
28
- t.pattern = "test/test_*.rb"
12
+ t.test_files = Dir.glob("test/**/test_*.rb")
29
13
  t.verbose = true
30
14
  end
31
15
 
@@ -41,12 +25,14 @@ begin
41
25
  rescue LoadError
42
26
  end
43
27
 
44
- require 'rake/rdoctask'
45
- Rake::RDocTask.new do |rdoc|
46
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
-
48
- rdoc.rdoc_dir = 'rdoc'
49
- rdoc.title = "review #{version}"
50
- rdoc.rdoc_files.include('README*')
51
- rdoc.rdoc_files.include('lib/**/*.rb')
28
+ begin
29
+ require 'rdoc/task'
30
+ Rake::RDocTask.new do |rdoc|
31
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
32
+ rdoc.rdoc_dir = 'rdoc'
33
+ rdoc.title = "review #{version}"
34
+ rdoc.rdoc_files.include('README*')
35
+ rdoc.rdoc_files.include('lib/**/*.rb')
36
+ end
37
+ rescue LoadError
52
38
  end
@@ -15,13 +15,16 @@ require 'pathname'
15
15
  bindir = Pathname.new(__FILE__).realpath.dirname
16
16
  $LOAD_PATH.unshift((bindir + '../lib').realpath)
17
17
 
18
- require 'review/book'
18
+ require 'review'
19
19
  require 'optparse'
20
- require 'nkf'
20
+
21
+ include ReVIEW::TextUtils
21
22
 
22
23
  def sigmain
23
24
  Signal.trap(:INT) { exit 1 }
24
- Signal.trap(:PIPE, 'IGNORE')
25
+ if RUBY_PLATFORM !~ /mswin(?!ce)|mingw|cygwin|bccwin/
26
+ Signal.trap(:PIPE, 'IGNORE')
27
+ end
25
28
  main
26
29
  rescue Errno::EPIPE
27
30
  exit 0
@@ -92,15 +95,7 @@ def check_text(files)
92
95
  next if neg and neg =~ s
93
96
  str, offset = find_line(para, re)
94
97
  out = sprintf("%s:%d: %s\n", path, lineno + offset, str)
95
- if @param["outencoding"] =~ /^EUC$/
96
- print NKF.nkf("-e", out)
97
- elsif @param["outencoding"] =~ /^SJIS$/
98
- print NKF.nkf("-s", out)
99
- elsif @param["outencoding"] =~ /^JIS$/
100
- print NKF.nkf("-j", out)
101
- else
102
- print out
103
- end
98
+ print convert_outencoding(out, @param["outencoding"])
104
99
  end
105
100
  end
106
101
  }
@@ -142,15 +137,8 @@ end
142
137
  def each_paragraph(f)
143
138
  $ReVIEW_utils_word_ok = nil
144
139
  while line = f.gets
145
- if @param["inencoding"] =~ /^EUC$/
146
- line = NKF.nkf("-E -w", line)
147
- elsif @param["inencoding"] =~ /SJIS$/
148
- line = NKF.nkf("-S -w", line)
149
- elsif @param["inencoding"] =~ /^JIS$/
150
- line = NKF.nkf("-J -w", line)
151
- else
152
- line = NKF.nkf("-w", line)
153
- end
140
+ line = convert_inencoding(line, @param["inencoding"])
141
+
154
142
  case line
155
143
  when /\A\#@ok\((.*)\)/
156
144
  $ReVIEW_utils_word_ok = $1
@@ -23,7 +23,9 @@ require 'optparse'
23
23
 
24
24
  def main
25
25
  Signal.trap(:INT) { exit 1 }
26
- Signal.trap(:PIPE, "IGNORE")
26
+ if RUBY_PLATFORM !~ /mswin(?!ce)|mingw|cygwin|bccwin/
27
+ Signal.trap(:PIPE, 'IGNORE')
28
+ end
27
29
  _main
28
30
  rescue Errno::EPIPE
29
31
  exit 0
@@ -40,12 +42,14 @@ def _main
40
42
  target = nil
41
43
  end
42
44
  check_only = false
45
+ output_filename = nil
43
46
 
44
47
  param = {
45
48
  "secnolevel" => 2, # for IDGXML and HTML
46
49
  "tableopt" => nil, # for IDGXML
47
50
  "nolf" => nil, # for IDGXML
48
51
  "chapref" => nil, # for IDGXML
52
+ "structuredxml" => nil, # for IDGXML
49
53
  "inencoding" => "UTF-8",
50
54
  "outencoding" => "UTF-8",
51
55
  "subdirmode" => nil,
@@ -69,7 +73,9 @@ def _main
69
73
  parser.on('--outencoding=ENCODING', 'Set output encoding. (UTF-8[default], EUC, JIS, and SJIS)') {|enc| param["outencoding"] = enc }
70
74
  parser.on('-c', '--check', 'Check manuscript') { check_only = true }
71
75
  parser.on('--level=LVL', 'Section level to append number.') {|lvl| param["secnolevel"] = lvl.to_i }
76
+ parser.on('--toclevel=LVL', 'Section level to append number.') {|lvl| param["toclevel"] = lvl.to_i }
72
77
  parser.on('--nolfinxml', 'Do not insert LF in XML. (idgxml)') { param["nolf"] = true }
78
+ parser.on('--structuredxml', 'Produce XML with structured sections. (idgxml)') { param["structuredxml"] = true }
73
79
  parser.on('--table=WIDTH', 'Default table width. (idgxml)') {|tbl| param["tableopt"] = tbl }
74
80
  parser.on('--listinfo', 'Append listinfo tag to lists to indicate begin/end. (idgxml)') { param["listinfo"] = true }
75
81
  parser.on('--chapref="before,middle,after"', 'Chapref decoration.') {|cdec| param["chapref"] = cdec }
@@ -101,6 +107,10 @@ def _main
101
107
  mode = :dir
102
108
  basedir = path
103
109
  end
110
+ parser.on('--output-file=FILENAME', 'Write all results into file instead of stdout.') do |filename|
111
+ output_filename = filename
112
+ end
113
+ parser.on('--tabwidth=WIDTH', 'tab width') {|width| param["tabwidth"] = width.to_i }
104
114
  parser.on('--help', 'Prints this message and quit.') do
105
115
  puts parser.help
106
116
  exit 0
@@ -120,25 +130,40 @@ def _main
120
130
  exit 1
121
131
  end
122
132
 
123
- # array parameter
124
- ["stylesheet"].each do |k|
125
- if param["k"].instance_of?(String)
126
- param["k"] = [param["k"]]
127
- end
128
- end
129
-
130
133
  begin
131
- compiler = ReVIEW::Compiler.new(load_strategy_class(target, check_only))
132
134
  ReVIEW.book.param = param
135
+ compiler = ReVIEW::Compiler.new(load_strategy_class(target, check_only))
133
136
  case mode
134
137
  when :files
135
138
  if ARGV.empty?
136
139
  error 'no input'
137
140
  exit 1
138
141
  end
139
- ReVIEW::Chapter.intern_pathes(ARGV).each do |chap|
140
- result = compiler.compile(chap)
141
- puts result unless check_only
142
+
143
+ begin
144
+ ReVIEW::Book::Chapter.intern_pathes(ARGV).each do |chap|
145
+ result = compiler.compile(chap)
146
+ if output_filename
147
+ write output_filename, result
148
+ else
149
+ puts result unless check_only
150
+ end
151
+ end
152
+ rescue => e
153
+ # PART
154
+ part = ReVIEW.book.parts_in_file.select do |part|
155
+ ARGV.map{|path| File.basename path}.include? part.path
156
+ end
157
+ if part.present?
158
+ result = compiler.compile(part.first)
159
+ if output_filename
160
+ write output_filename, result
161
+ else
162
+ puts result unless check_only
163
+ end
164
+ else
165
+ raise e
166
+ end
142
167
  end
143
168
  when :dir
144
169
  book = basedir ? ReVIEW::Book.load(basedir) : ReVIEW.book
@@ -146,6 +171,14 @@ def _main
146
171
  str = compiler.compile(chap)
147
172
  write "#{chap.name}#{compiler.strategy.extname}", str unless check_only
148
173
  end
174
+ # PART
175
+ book.parts_in_file.each do |part|
176
+ str = compiler.compile(part)
177
+ if compiler.strategy.extname == ".tex"
178
+ str.gsub!(/\A\\chapter\{/, '\part{') # FIXME: UGLY...
179
+ end
180
+ write "#{part.name}#{compiler.strategy.extname}", str unless check_only
181
+ end
149
182
  else
150
183
  raise "must not happen: #{mode}"
151
184
  end
@@ -14,6 +14,7 @@ require 'fileutils'
14
14
  require 'yaml'
15
15
  require 'optparse'
16
16
  require 'rexml/document'
17
+ require 'time'
17
18
 
18
19
  require 'pathname'
19
20
 
@@ -21,61 +22,48 @@ bindir = Pathname.new(__FILE__).realpath.dirname
21
22
  $LOAD_PATH.unshift((bindir + '../lib').realpath)
22
23
 
23
24
  require 'uuid'
25
+ require 'review'
26
+ require 'review/i18n'
24
27
 
28
+ require 'review/htmlutils'
29
+ include ReVIEW::HTMLUtils
30
+
31
+ $essential_files = ['top', 'toc', 'colophon']
25
32
  def main
26
- values = { # These parameters can be overridden by YAML file.
27
- "bookname"=> nil, # it defines epub file name also
28
- "booktitle" => "ReVIEW EPUBサンプル",
29
- "aut" => nil, # author
30
- "prt" => nil, # printer(publisher)
31
- "asn" => nil, # associated name
32
- "ant" => nil, # bibliographic antecedent
33
- "clb" => nil, # Collaborator
34
- "edt" => nil, # Editor
35
- "dsr" => nil, # Designer
36
- "ill" => nil, # Illustrator
37
- "pht" => nil, # Photographer
38
- "trl" => nil, # Translator
39
- "date" => nil, # publishing date
40
- "rights" => nil, # Copyright messages
41
- "description" => nil, # Description
42
- "urnid" => nil, # Identifier (nil makes random uuid)
43
- "stylesheet" => "stylesheet.css", # stylesheet file
44
- "coverfile" => nil, # content file of body of cover page
45
- "mytoc" => nil, # whether make own table of contents or not
46
- "params" => "", # specify review2html parameters
47
- "toclevel" => 3, # level of toc
48
- "secnolevel" => 2, # level of section #
49
- "posthook" => nil, # command path of post hook
50
- "debug" => nil, # debug flag
51
- }
52
33
  if ARGV.size != 1
53
34
  puts "Usage: #{$0} configfile"
54
35
  exit 0
55
36
  end
56
-
37
+
57
38
  yamlfile = ARGV[0]
58
- values = values.merge(YAML.load_file(yamlfile))
39
+ values = ReVIEW::Configure.values.merge(YAML.load_file(yamlfile))
59
40
  bookname = values["bookname"]
41
+ $essential_files <<= bookname
42
+ tmp = values["debug"].nil? ? Dir.mktmpdir : "."
43
+ @bookdir = "#{tmp}/#{bookname}-epub"
44
+ @epubversion = values["epubversion"] || 2
45
+ @htmlversion = values["htmlversion"] || 4
46
+ if @epubversion == 3
47
+ ## if epubversion is 3, htmlversion should be 5
48
+ @htmlversion = 5
49
+ end
60
50
 
61
51
  if File.exist?("#{bookname}.epub")
62
52
  STDERR.puts "#{bookname}.epub exists. Please remove or rename first."
63
53
  exit 1
64
54
  end
65
- if File.exist?("#{bookname}")
66
- STDERR.puts "#{bookname} directory exists. Please remove or rename first."
55
+ if File.exist?(@bookdir)
56
+ STDERR.puts "#{@bookdir} directory exists. Please remove or rename first."
67
57
  exit 1
68
58
  end
69
59
 
70
- identifier = values["urnid"].nil? ? "urn:uuid:#{UUID.create}" : values["urnid"]
60
+ @identifier = values["urnid"].nil? ? "urn:uuid:#{UUID.create}" : values["urnid"]
71
61
 
72
- tmp = values["debug"].nil? ? Dir.mktmpdir : "."
73
- @bookdir = "#{tmp}/#{bookname}"
74
62
  Dir.mkdir(@bookdir)
75
63
 
76
64
  # MIME type
77
65
  File.open("#{@bookdir}/mimetype", "w") {|f|
78
- f.puts "application/epub+zip"
66
+ f.write "application/epub+zip"
79
67
  }
80
68
 
81
69
  Dir.mkdir("#{@bookdir}/OEBPS")
@@ -83,21 +71,57 @@ def main
83
71
  @manifeststr = ""
84
72
  @ncxstr = ""
85
73
  @tocdesc = Array.new
86
-
87
- if File.exists?("PREDEF")
88
- output_chaps("PREDEF", values)
89
- end
90
- if File.exists?("CHAPS")
91
- output_chaps("CHAPS", values)
92
- end
93
- if File.exists?("POSTDEF")
94
- output_chaps("POSTDEF", values)
74
+
75
+ basedir = Dir.pwd
76
+ base_path = Pathname.new(basedir)
77
+ ReVIEW::Book.load(basedir).parts.each do |part|
78
+ if part.name.present?
79
+ if part.file?
80
+ filename = (base_path + part.path).to_s
81
+ output_chaps_by_file(filename, values)
82
+ htmlfile = File.basename(filename.chomp.strip,".*")+".html"
83
+ else
84
+ htmlfile = "part_#{part.number}.html"
85
+ make_part_page(part, htmlfile, values)
86
+ end
87
+ file_id = "part_#{part.number}"
88
+ part_name = "#{ReVIEW::I18n.t("part", part.number)} #{part.name.strip}"
89
+ @tocdesc << [1, htmlfile, nil, part_name]
90
+ @manifeststr << %Q(<item id="#{file_id}" href="#{htmlfile}" media-type="application/xhtml+xml" />\n)
91
+ @ncxstr << %Q(<itemref idref="#{file_id}" />\n)
92
+ end
93
+
94
+ part.chapters.each do |chap|
95
+ filename = Pathname.new(chap.path).relative_path_from(base_path).to_s
96
+ output_chaps_by_file(filename, values)
97
+ end
95
98
  end
99
+
96
100
  if File.exist?("images")
97
101
  Dir.mkdir("#{@bookdir}/OEBPS/images")
98
- copyImagesToDir("images", "#{@bookdir}/OEBPS/images")
102
+ image_files = ReVIEW::MakerHelper.copy_images_to_dir("images", "#{@bookdir}/OEBPS/images")
103
+ image_files.each do |image_file|
104
+ dirname = File.dirname(image_file)
105
+ fname = File.basename(image_file)
106
+ figid = getFigId(dirname.gsub(%r|/|,'-')+"-"+fname)
107
+ mime = nil
108
+ next unless fname =~ /\.(png|gif|jpg|jpeg|svg)$/i
109
+ case fname.downcase.match(/\.(png|gif|jpg|jpeg|svg)$/)[1]
110
+ when "png"
111
+ mime = "image/png"
112
+ when "gif"
113
+ mime = "image/gif"
114
+ when "jpg", "jpeg"
115
+ mime = "image/jpeg"
116
+ when "svg"
117
+ mime = "image/svg+xml"
118
+ else
119
+ raise "unsupported type #{fname}"
120
+ end
121
+ @manifeststr << %Q(<item id="#{figid}" href="#{image_file}" media-type="#{mime}" />\n)
122
+ end
99
123
  end
100
-
124
+
101
125
  # container
102
126
  Dir.mkdir("#{@bookdir}/META-INF")
103
127
  File.open("#{@bookdir}/META-INF/container.xml", "w") {|f|
@@ -111,102 +135,21 @@ def main
111
135
  EOT
112
136
  }
113
137
 
114
- # opf (meta info)
115
- File.open("#{@bookdir}/OEBPS/#{bookname}.opf", "w") {|f|
116
- f.puts <<EOT
117
- <?xml version="1.0" encoding="UTF-8"?>
118
- <package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
119
- <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
120
- <dc:title>#{values["booktitle"]}</dc:title>
121
- EOT
122
-
123
- f.puts %Q(<dc:creator opf:role="aut">#{values["aut"]}</dc:creator>) unless values["aut"].nil? # FIXME: support multiple members
124
-
125
- f.puts %Q(<dc:publisher>#{values["prt"]}</dc:publisher>) unless values["prt"].nil?
126
-
127
- f.puts %Q(<dc:date>#{values["date"]}</dc:date>) unless values["date"].nil?
128
- f.puts %Q(<dc:rights>#{values["rights"]}</dc:rights>) unless values["rights"].nil?
129
-
130
- f.puts %Q(<dc:contributor opf:role="asn">#{values["asn"]}</dc:contributor>) unless values["asn"].nil?
131
- f.puts %Q(<dc:contributor opf:role="ant">#{values["ant"]}</dc:contributor>) unless values["ant"].nil?
132
- f.puts %Q(<dc:contributor opf:role="clb">#{values["clb"]}</dc:contributor>) unless values["clb"].nil?
133
- f.puts %Q(<dc:contributor opf:role="edt">#{values["edt"]}</dc:contributor>) unless values["edt"].nil?
134
- f.puts %Q(<dc:contributor opf:role="dsr">#{values["dsr"]}</dc:contributor>) unless values["dsr"].nil?
135
- f.puts %Q(<dc:contributor opf:role="ill">#{values["ill"]}</dc:contributor>) unless values["ill"].nil?
136
- f.puts %Q(<dc:contributor opf:role="pht">#{values["pht"]}</dc:contributor>) unless values["pht"].nil?
137
- f.puts %Q(<dc:contributor opf:role="trl">#{values["trl"]}</dc:contributor>) unless values["trl"].nil?
138
-
139
- f.puts %Q(<dc:description>#{values["description"]}</dc:description>) unless values["description"].nil?
140
-
141
- if values["coverimage"]
142
- f.puts %Q(<meta name="cover" content="#{getFigId(values["coverimage"])}"/>)
143
- end
144
- f.puts <<EOT
145
- <dc:language>ja</dc:language>
146
- <dc:identifier id="BookId">#{identifier}</dc:identifier>
147
- </metadata>
148
- <manifest>
149
- <item id="ncx" href="#{bookname}.ncx" media-type="application/x-dtbncx+xml" />
150
- <item id="style" href="#{values["stylesheet"]}" media-type="text/css" />
151
- <item id="#{bookname}" href="#{bookname}.html" media-type="application/xhtml+xml" />
152
- <item id="top" href="top.html" media-type="application/xhtml+xml" />
153
- EOT
154
-
155
- unless values["mytoc"].nil?
156
- f.puts <<EOT
157
- <item id="toc" href="toc.html" media-type="application/xhtml+xml" />
158
- EOT
159
- end
160
-
161
- f.puts @manifeststr
162
- unless values["colophon"].nil?
163
- f.puts <<EOT
164
- <item id="colophon" href="colophon.html" media-type="application/xhtml+xml" />
165
- EOT
166
- end
167
- cover_linear = values["cover_linear"] || "no"
168
- f.puts <<EOT
169
- </manifest>
170
- <spine toc="ncx">
171
- <itemref idref="#{bookname}" linear="#{cover_linear}" />
172
- <itemref idref="top" />
173
- EOT
174
- unless values["mytoc"].nil?
175
- f.puts <<EOT
176
- <itemref idref="toc" />
177
- EOT
178
- end
179
-
180
- f.puts @ncxstr
181
- unless values["colophon"].nil?
182
- f.puts <<EOT
183
- <itemref idref="colophon" />
184
- EOT
185
- end
186
- f.puts <<EOT
187
- </spine>
188
- <guide>
189
- <reference type="cover" title="表紙" href="#{bookname}.html"/>
190
- <reference type="title-page" title="Title Page" href="top.html"/>
191
- EOT
192
- unless values["mytoc"].nil?
193
- f.puts <<EOT
194
- <reference type="toc" title="目次" href="toc.html"/>
195
- EOT
196
- end
197
- f.puts <<EOT
198
- </guide>
199
- </package>
200
- EOT
201
- }
138
+ # opf (meta info)
139
+ if @epubversion == 3
140
+ make_opf_filev3(values, bookname)
141
+ else
142
+ make_opf_file(values, bookname)
143
+ end
202
144
 
203
145
  # ncx (toc)
204
- File.open("#{@bookdir}/OEBPS/#{bookname}.ncx", "w") {|f|
205
- f.puts <<EOT
146
+ if values["toc"]
147
+ File.open("#{@bookdir}/OEBPS/#{bookname}.ncx", "w") {|f|
148
+ f.puts <<EOT
206
149
  <?xml version="1.0" encoding="UTF-8"?>
207
150
  <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
208
151
  <head>
209
- <meta name="dtb:uid" content="#{identifier}"/>
152
+ <meta name="dtb:uid" content="#{@identifier}"/>
210
153
  <meta name="dtb:depth" content="1"/>
211
154
  <meta name="dtb:totalPageCount" content="0"/>
212
155
  <meta name="dtb:maxPageNumber" content="0"/>
@@ -226,10 +169,10 @@ EOT
226
169
  </navPoint>
227
170
  EOT
228
171
 
229
- nav_count = 2
172
+ nav_count = 2
230
173
 
231
- unless values["mytoc"].nil?
232
- f.puts <<EOT
174
+ if values["mytoc"]
175
+ f.puts <<EOT
233
176
  <navPoint id="toc" playOrder="2">
234
177
  <navLabel>
235
178
  <text>目次</text>
@@ -237,44 +180,61 @@ EOT
237
180
  <content src="toc.html"/>
238
181
  </navPoint>
239
182
  EOT
240
- nav_count = 3
241
- end
242
-
243
- @tocdesc.each {|item|
244
- level, file, id, content = item
245
- # values["level"]
246
- next if level > values["toclevel"].to_i
247
- indent = ""
248
- if level > values["secnolevel"].to_i
249
- indent = "- "
183
+ nav_count = 3
250
184
  end
251
- f.puts <<EOT
185
+
186
+ @tocdesc.each {|item|
187
+ level, file, id, content = item
188
+ # values["level"]
189
+ next if level > values["toclevel"].to_i
190
+ indent = ""
191
+ if level > values["secnolevel"].to_i
192
+ indent = "- "
193
+ end
194
+ fragment_id = (id ? '#'+id : '')
195
+ f.puts <<EOT
252
196
  <navPoint id="navPoint-#{nav_count}" playOrder="#{nav_count}">
253
197
  <navLabel>
254
- <text>#{indent}#{content}</text>
198
+ <text>#{indent}#{strip_html(content)}</text>
255
199
  </navLabel>
256
- <content src="#{file}##{id}"/>
200
+ <content src="#{file}#{fragment_id}"/>
257
201
  </navPoint>
258
202
  EOT
259
- nav_count += 1
260
- }
261
- f.puts <<EOT
203
+ nav_count += 1
204
+ }
205
+ f.puts <<EOT
262
206
  </navMap>
263
207
  </ncx>
264
208
  EOT
265
- }
266
-
209
+ }
210
+ end
211
+
267
212
  # Cover page
268
213
  File.open("#{@bookdir}/OEBPS/#{bookname}.html", "w") {|f|
269
214
  f.puts <<EOT
270
215
  <?xml version="1.0" encoding="UTF-8"?>
271
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
272
- <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
216
+ EOT
217
+ doctype = make_doctype()
218
+ f.puts doctype
219
+ f.puts <<EOT
220
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
273
221
  <head>
222
+ EOT
223
+ if @htmlversion == 4
224
+ f.puts <<EOT
274
225
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
275
226
  <meta http-equiv="Content-Style-Type" content="text/css"/>
276
227
  <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
277
- <meta name="generator" content="ReVIEW"/>
228
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
229
+ EOT
230
+ else
231
+ f.puts <<EOT
232
+ <meta charset="UTF-8" />
233
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
234
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
235
+ EOT
236
+ end
237
+ f.puts <<EOT
278
238
  <title>#{values["booktitle"]}</title>
279
239
  </head>
280
240
  <body>
@@ -302,13 +262,28 @@ EOT
302
262
  File.open("#{@bookdir}/OEBPS/top.html", "w") {|f|
303
263
  f.puts <<EOT
304
264
  <?xml version="1.0" encoding="UTF-8"?>
305
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
306
- <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
265
+ EOT
266
+ doctype = make_doctype()
267
+ f.puts doctype
268
+ f.puts <<EOT
269
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
307
270
  <head>
271
+ EOT
272
+ if @htmlversion == 4
273
+ f.puts <<EOT
308
274
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
309
275
  <meta http-equiv="Content-Style-Type" content="text/css"/>
310
276
  <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
311
277
  <meta name="generator" content="ReVIEW EPUB Maker"/>
278
+ EOT
279
+ else
280
+ f.puts <<EOT
281
+ <meta charset="UTF-8" />
282
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
283
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
284
+ EOT
285
+ end
286
+ f.puts <<EOT
312
287
  <title>#{values["booktitle"]}</title>
313
288
  </head>
314
289
  <body>
@@ -352,24 +327,46 @@ EOT
352
327
  }
353
328
 
354
329
  # Additional toc page
355
- unless values["mytoc"].nil?
330
+ if values["toc"] && values["mytoc"]
356
331
  File.open("#{@bookdir}/OEBPS/toc.html", "w") {|f|
332
+ if @epubversion == 3
333
+ listelm = "ol"
334
+ else
335
+ listelm = "ul"
336
+ end
357
337
  f.puts <<EOT
358
338
  <?xml version="1.0" encoding="UTF-8"?>
359
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
360
- <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
339
+ EOT
340
+ doctype = make_doctype()
341
+ f.puts doctype
342
+ f.puts <<EOT
343
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
361
344
  <head>
345
+ EOT
346
+ if @htmlversion == 4
347
+ f.puts <<EOT
362
348
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
363
349
  <meta http-equiv="Content-Style-Type" content="text/css"/>
364
350
  <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
365
351
  <meta name="generator" content="ReVIEW EPUB Maker"/>
352
+ EOT
353
+ else
354
+ f.puts <<EOT
355
+ <meta charset="UTF-8" />
356
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
357
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
358
+ EOT
359
+ end
360
+ f.puts <<EOT
366
361
  <title>目次</title>
367
362
  </head>
368
363
  <body>
364
+ EOT
365
+ f.puts %q(<nav epub:type="toc" id="toc">) if @epubversion == 3
366
+ f.puts <<EOT
369
367
  <h1>目次</h1>
370
- <ul class=\"toc-h1\">
368
+ <#{listelm} class=\"toc-h1\">
371
369
  EOT
372
-
373
370
  current = 1
374
371
  init_item = true
375
372
  @tocdesc.each {|item|
@@ -379,20 +376,20 @@ EOT
379
376
  if level > current
380
377
  current += 1
381
378
  f.puts ""
382
- f.puts "<ul class=\"toc-h#{current}\">"
379
+ f.puts "<#{listelm} class=\"toc-h#{current}\">"
383
380
  while current < level
384
381
  current += 1
385
382
  f.puts "<li>"
386
- f.puts "<ul class=\"toc-h#{current}\">"
383
+ f.puts "<#{listelm} class=\"toc-h#{current}\">"
387
384
  end
388
385
  elsif level < current
389
386
  current -= 1
390
387
  f.puts "</li>"
391
- f.puts "</ul>"
388
+ f.puts "</#{listelm}>"
392
389
  f.puts "</li>"
393
390
  while current > level
394
391
  current -= 1
395
- f.puts "</ul>"
392
+ f.puts "</#{listelm}>"
396
393
  f.puts "</li>"
397
394
  end
398
395
  elsif init_item
@@ -400,20 +397,22 @@ EOT
400
397
  else
401
398
  f.puts "</li>"
402
399
  end
403
- f.write "<li><a href=\"#{file}##{id}\">#{content}</a>"
400
+ fragment_id = (id ? '#'+id : '')
401
+ f.write "<li><a href=\"#{file}#{fragment_id}\">#{content}</a>"
404
402
  init_item = false
405
403
  }
406
404
 
407
405
  (current - 1).downto(1) {|n|
408
406
  f.puts "</li>"
409
- f.puts "</ul>"
407
+ f.puts "</#{listelm}>"
410
408
  }
411
409
  if !init_item
412
410
  f.puts "</li>"
413
411
  end
414
412
 
413
+ f.puts "</#{listelm}>"
414
+ f.puts %q(</nav>) if @epubversion == 3
415
415
  f.puts <<EOT
416
- </ul>
417
416
  </body>
418
417
  </html>
419
418
  EOT
@@ -436,7 +435,7 @@ EOT
436
435
  end
437
436
 
438
437
  # Colophon page
439
- if !values["colophon"].nil?
438
+ if values["colophon"]
440
439
  make_colophon_page(tmp, bookname, values)
441
440
  end
442
441
 
@@ -452,69 +451,279 @@ EOT
452
451
  fork {
453
452
  basedir = Dir.pwd
454
453
  Dir.chdir(@bookdir) {|d|
455
- exec("zip -0X #{basedir}/#{bookname}.epub mimetype")
454
+ exec("zip", "-0X", "#{basedir}/#{bookname}.epub", "mimetype")
456
455
  }
457
456
  }
458
457
  Process.waitall
459
458
  fork {
460
459
  basedir = Dir.pwd
461
460
  Dir.chdir(@bookdir) {|d|
462
- exec("zip -Xr9D #{basedir}/#{bookname}.epub META-INF OEBPS")
461
+ exec("zip", "-Xr9D", "#{basedir}/#{bookname}.epub", "META-INF", "OEBPS")
463
462
  }
464
463
  }
465
464
  Process.waitall
466
-
465
+
467
466
  FileUtils.rm_r(tmp) if values["debug"].nil?
468
467
  end
469
468
 
469
+ def make_doctype
470
+ if @htmlversion == 5
471
+ %q(<!DOCTYPE html>)
472
+ else
473
+ %q(<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">)
474
+ end
475
+ end
476
+
477
+
478
+ def make_opf_file(values, bookname)
479
+ File.open("#{@bookdir}/OEBPS/#{bookname}.opf", "w") {|f|
480
+ f.puts <<EOT
481
+ <?xml version="1.0" encoding="UTF-8"?>
482
+ <package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
483
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
484
+ <dc:title>#{values["booktitle"]}</dc:title>
485
+ EOT
486
+
487
+ f.puts %Q(<dc:creator opf:role="aut">#{values["aut"]}</dc:creator>) unless values["aut"].nil? # FIXME: support multiple members
488
+
489
+ f.puts %Q(<dc:publisher>#{values["prt"]}</dc:publisher>) unless values["prt"].nil?
490
+
491
+ f.puts %Q(<dc:date>#{values["date"]}</dc:date>) unless values["date"].nil?
492
+ f.puts %Q(<dc:rights>#{values["rights"]}</dc:rights>) unless values["rights"].nil?
493
+
494
+ f.puts %Q(<dc:contributor opf:role="asn">#{values["asn"]}</dc:contributor>) unless values["asn"].nil?
495
+ f.puts %Q(<dc:contributor opf:role="ant">#{values["ant"]}</dc:contributor>) unless values["ant"].nil?
496
+ f.puts %Q(<dc:contributor opf:role="clb">#{values["clb"]}</dc:contributor>) unless values["clb"].nil?
497
+ f.puts %Q(<dc:contributor opf:role="edt">#{values["edt"]}</dc:contributor>) unless values["edt"].nil?
498
+ f.puts %Q(<dc:contributor opf:role="dsr">#{values["dsr"]}</dc:contributor>) unless values["dsr"].nil?
499
+ f.puts %Q(<dc:contributor opf:role="ill">#{values["ill"]}</dc:contributor>) unless values["ill"].nil?
500
+ f.puts %Q(<dc:contributor opf:role="pht">#{values["pht"]}</dc:contributor>) unless values["pht"].nil?
501
+ f.puts %Q(<dc:contributor opf:role="trl">#{values["trl"]}</dc:contributor>) unless values["trl"].nil?
502
+
503
+ f.puts %Q(<dc:description>#{values["description"]}</dc:description>) unless values["description"].nil?
504
+
505
+ if values["coverimage"]
506
+ f.puts %Q(<meta name="cover" content="#{getFigId("images-"+values["coverimage"])}"/>)
507
+ end
508
+ f.puts <<EOT
509
+ <dc:language>ja</dc:language>
510
+ <dc:identifier id="BookId">#{@identifier}</dc:identifier>
511
+ </metadata>
512
+ <manifest>
513
+ EOT
514
+
515
+ if values["toc"]
516
+ f.puts <<EOT
517
+ <item id="ncx" href="#{bookname}.ncx" media-type="application/x-dtbncx+xml" />
518
+ EOT
519
+ end
520
+
521
+ f.puts <<EOT
522
+ <item id="style" href="#{values["stylesheet"]}" media-type="text/css" />
523
+ <item id="#{bookname}" href="#{bookname}.html" media-type="application/xhtml+xml" />
524
+ <item id="top" href="top.html" media-type="application/xhtml+xml" />
525
+ EOT
526
+
527
+ if values["toc"] && values["mytoc"]
528
+ f.puts <<EOT
529
+ <item id="toc" href="toc.html" media-type="application/xhtml+xml" />
530
+ EOT
531
+ end
532
+
533
+ f.puts @manifeststr
534
+ if values["colophon"]
535
+ f.puts <<EOT
536
+ <item id="colophon" href="colophon.html" media-type="application/xhtml+xml" />
537
+ EOT
538
+ end
539
+
540
+ if values["cover_linear"] && values["cover_linear"] != "no"
541
+ cover_linear = "yes"
542
+ else
543
+ cover_linear = "no"
544
+ end
545
+
546
+ f.puts <<EOT
547
+ </manifest>
548
+ <spine toc="ncx">
549
+ <itemref idref="#{bookname}" linear="#{cover_linear}" />
550
+ <itemref idref="top" />
551
+ EOT
552
+
553
+ if values["toc"] && values["mytoc"]
554
+ f.puts <<EOT
555
+ <itemref idref="toc" />
556
+ EOT
557
+ end
558
+
559
+ f.puts @ncxstr
560
+ if values["colophon"]
561
+ f.puts <<EOT
562
+ <itemref idref="colophon" />
563
+ EOT
564
+ end
565
+ f.puts <<EOT
566
+ </spine>
567
+ <guide>
568
+ EOT
569
+
570
+ if values["titlepage"]
571
+ f.puts <<EOT
572
+ <reference type="cover" title="表紙" href="#{bookname}.html"/>
573
+ <reference type="title-page" title="Title Page" href="top.html"/>
574
+ EOT
575
+ end
576
+
577
+ if values["toc"] && values["mytoc"]
578
+ f.puts <<EOT
579
+ <reference type="toc" title="目次" href="toc.html"/>
580
+ EOT
581
+ end
582
+ f.puts <<EOT
583
+ </guide>
584
+ </package>
585
+ EOT
586
+ }
587
+ end
588
+
589
+ def make_opf_filev3(values, bookname)
590
+ File.open("#{@bookdir}/OEBPS/#{bookname}.opf", "w") {|f|
591
+ f.puts <<EOT
592
+ <?xml version="1.0" encoding="UTF-8"?>
593
+ <package version="3.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
594
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
595
+ <dc:title>#{values["booktitle"]}</dc:title>
596
+ EOT
597
+ unless values["aut"].nil? # FIXME: support multiple members
598
+ f.puts %Q(<dc:creator id="author">#{values["aut"]}</dc:creator>)
599
+ f.puts %Q(<meta refines="#author" property="role" scheme="marc:relators" id="role">aut</meta>)
600
+ end
601
+ f.puts %Q(<dc:publisher id="publisher">#{values["prt"]}</dc:publisher>) unless values["prt"].nil?
602
+
603
+ f.puts %Q(<dc:date>#{values["date"]}</dc:date>) unless values["date"].nil?
604
+ f.puts %Q(<dc:rights>#{values["rights"]}</dc:rights>) unless values["rights"].nil?
605
+
606
+ %w(asn ant clb edt dsr ill pht trl).each do |attr|
607
+ unless values[attr].nil?
608
+ f.puts %Q(<dc:contributor id="#{attr}">#{values[attr]}</dc:contributor>)
609
+ f.puts %Q(<meta refines='##{attr}' property='role' scheme='marc:relators'>#{attr}</meta>)
610
+ end
611
+ end
612
+ f.puts %Q(<dc:description>#{values["description"]}</dc:description>) unless values["description"].nil?
613
+ f.puts %Q(<meta property="dcterms:modified">#{Time.now.utc.iso8601(0)}</meta>)
614
+ if values["coverimage"]
615
+ f.puts %Q(<meta name="cover" content="#{getFigId("images-"+values["coverimage"])}"/>)
616
+ end
617
+ f.puts <<EOT
618
+ <dc:language>ja</dc:language>
619
+ <dc:identifier id="BookId">#{@identifier}</dc:identifier>
620
+ </metadata>
621
+ <manifest>
622
+ EOT
623
+
624
+ if values["toc"]
625
+ f.puts <<EOT
626
+ <item id="ncx" href="#{bookname}.ncx" media-type="application/x-dtbncx+xml" />
627
+ EOT
628
+ end
629
+
630
+ f.puts <<EOT
631
+ <item id="style" href="#{values["stylesheet"]}" media-type="text/css" />
632
+ <item id="#{bookname}" href="#{bookname}.html" media-type="application/xhtml+xml" />
633
+ <item id="top" href="top.html" media-type="application/xhtml+xml" />
634
+ EOT
635
+
636
+ if values["toc"] && values["mytoc"]
637
+ f.puts <<EOT
638
+ <item id="toc" href="toc.html" properties="nav" media-type="application/xhtml+xml" />
639
+ EOT
640
+ end
641
+
642
+ f.puts @manifeststr
643
+ if values["colophon"]
644
+ f.puts <<EOT
645
+ <item id="colophon" href="colophon.html" media-type="application/xhtml+xml" />
646
+ EOT
647
+ end
648
+
649
+ if values["cover_linear"] && values["cover_linear"] != "no"
650
+ cover_linear = "yes"
651
+ else
652
+ cover_linear = "no"
653
+ end
654
+
655
+ f.puts <<EOT
656
+ </manifest>
657
+ <spine toc="ncx">
658
+ <itemref idref="#{bookname}" linear="#{cover_linear}" />
659
+ <itemref idref="top" />
660
+ EOT
661
+
662
+ if values["toc"] && values["mytoc"]
663
+ f.puts <<EOT
664
+ <itemref idref="toc" />
665
+ EOT
666
+ end
667
+
668
+ f.puts @ncxstr
669
+ if values["colophon"]
670
+ f.puts <<EOT
671
+ <itemref idref="colophon" />
672
+ EOT
673
+ end
674
+ f.puts <<EOT
675
+ </spine>
676
+ <guide>
677
+ EOT
678
+
679
+ if values["titlepage"]
680
+ f.puts <<EOT
681
+ <reference type="cover" title="表紙" href="#{bookname}.html"/>
682
+ <reference type="title-page" title="Title Page" href="top.html"/>
683
+ EOT
684
+ end
685
+
686
+ if values["toc"] && values["mytoc"]
687
+ f.puts <<EOT
688
+ <reference type="toc" title="目次" href="toc.html"/>
689
+ EOT
690
+ end
691
+ f.puts <<EOT
692
+ </guide>
693
+ </package>
694
+ EOT
695
+ }
696
+ end
697
+
698
+
470
699
  def output_chaps(chapsfile, values)
471
700
  File.open(chapsfile) {|chaps|
472
701
  chaps.each_line {|l|
473
702
  next if l =~ /^#/
474
- file_id = File.basename(l.chomp.strip,".*")
475
- filename = "#{file_id}.html"
476
- fork {
477
- STDOUT.reopen("#{@bookdir}/OEBPS/#{filename}")
478
- exec("review-compile --target=html --level=#{values["secnolevel"]} #{values["params"]} #{l}")
479
- }
480
- Process.waitall
481
- getanchors("#{@bookdir}/OEBPS/#{filename}")
482
- @manifeststr << %Q(<item id="#{file_id}" href="#{filename}" media-type="application/xhtml+xml" />\n)
483
- @ncxstr << %Q(<itemref idref="#{file_id}" />\n)
703
+ output_chaps_by_file(l, values)
484
704
  }
485
705
  }
486
706
  end
487
707
 
488
-
489
- def copyImagesToDir(dirname, copybase)
490
- Dir.open(dirname) {|dir|
491
- dir.each {|fname|
492
- next if fname =~ /^\./
493
- if FileTest.directory?("#{dirname}/#{fname}")
494
- copyImagesToDir("#{dirname}/#{fname}", "#{copybase}/#{fname}")
495
- else
496
- if fname =~ /\.(png|gif|jpg|jpeg|svg)$/i
497
- Dir.mkdir(copybase) unless File.exist?(copybase)
498
- FileUtils.cp "#{dirname}/#{fname}", copybase
499
- figid = getFigId(fname)
500
- mime = nil
501
- case fname.downcase.match(/\.(png|gif|jpg|jpeg|svg)$/)[1]
502
- when "png"
503
- mime = "image/png"
504
- when "gif"
505
- mime = "image/gif"
506
- when "jpg", "jpeg"
507
- mime = "image/jpeg"
508
- when "svg"
509
- mime = "image/svg+xml"
510
- else
511
- raise "unsupported type #{fname}"
512
- end
513
- @manifeststr << %Q(<item id="#{figid}" href="#{dirname}/#{fname}" media-type="#{mime}" />\n)
514
- end
515
- end
516
- }
708
+ def output_chaps_by_file(l, values)
709
+ file_id = File.basename(l.chomp.strip,".*")
710
+ if (idx = $essential_files.index(file_id))
711
+ if idx == $essential_files.size - 1
712
+ STDERR.puts "#{file_id} is book name. Please rename #{l.chomp.strip}."
713
+ else
714
+ STDERR.puts "#{file_id} is special name. Please rename #{l.chomp.strip}."
715
+ end
716
+ exit 1
717
+ end
718
+ filename = "#{file_id}.html"
719
+ fork {
720
+ STDOUT.reopen("#{@bookdir}/OEBPS/#{filename}")
721
+ exec("review-compile --target=html --level=#{values["secnolevel"]} --htmlversion=#{values["htmlversion"]} #{values["params"]} #{l}")
517
722
  }
723
+ Process.waitall
724
+ getanchors("#{@bookdir}/OEBPS/#{filename}")
725
+ @manifeststr << %Q(<item id="#{file_id}" href="#{filename}" media-type="application/xhtml+xml" />\n)
726
+ @ncxstr << %Q(<itemref idref="#{file_id}" />\n)
518
727
  end
519
728
 
520
729
  def getFigId(filename)
@@ -532,7 +741,7 @@ def getanchors(filename)
532
741
  File.open(filename) {|f|
533
742
  file = filename.sub(/.+\//, '')
534
743
  f.each_line {|l|
535
- if l =~ /\A<h(\d)><a id=\"(.+?)\" \/>(.+?)<\/h/
744
+ if l =~ /\A<h(\d)[^>]*><a id=\"(.+?)\"><\/a>(.+?)<\/h/
536
745
  # level, ID, content
537
746
  @tocdesc << [$1.to_i, file, $2, $3]
538
747
  end
@@ -544,13 +753,27 @@ def make_colophon_page(tmp,bookname,values)
544
753
 
545
754
  header = <<EOT
546
755
  <?xml version="1.0" encoding="UTF-8"?>
547
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
548
- <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
756
+ EOT
757
+ header += make_doctype()
758
+ header += <<EOT
759
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
549
760
  <head>
761
+ EOT
762
+ if @htmlversion == 4
763
+ header += <<EOT
550
764
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
551
765
  <meta http-equiv="Content-Style-Type" content="text/css"/>
552
766
  <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
553
767
  <meta name="generator" content="ReVIEW EPUB Maker"/>
768
+ EOT
769
+ else
770
+ header += <<EOT
771
+ <meta charset="UTF-8" />
772
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
773
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
774
+ EOT
775
+ end
776
+ header += <<EOT
554
777
  <title>#{values["booktitle"]}</title>
555
778
  </head>
556
779
  <body>
@@ -606,4 +829,38 @@ EOT
606
829
  end
607
830
  end
608
831
 
832
+ def make_part_page(part, filename, values)
833
+ File.open("#{@bookdir}/OEBPS/#{filename}", "w") {|f|
834
+ f.puts <<-EOT
835
+ <?xml version="1.0" encoding="UTF-8"?>
836
+ EOT
837
+ doctype = make_doctype()
838
+ f.puts doctype
839
+ f.puts <<-EOT
840
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
841
+ <head>
842
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
843
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
844
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
845
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
846
+ <title>#{values["booktitle"]}</title>
847
+ </head>
848
+ <body>
849
+ <h1 class="part-number">#{ReVIEW::I18n.t("part", part.number)}</h1>
850
+ EOT
851
+
852
+ if part.name.strip.present?
853
+ f.puts <<-EOT
854
+ <h2 class="part-title">#{part.name.strip}</h2>
855
+ EOT
856
+ end
857
+
858
+ f.puts <<-EOT
859
+ </body>
860
+ </html>
861
+ EOT
862
+ }
863
+ end
864
+
865
+
609
866
  main