review 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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