tmtms-review 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +9 -0
  3. data/COPYING +515 -0
  4. data/ChangeLog +2083 -0
  5. data/README.rdoc +50 -0
  6. data/Rakefile +56 -0
  7. data/VERSION +1 -0
  8. data/bin/review-check +178 -0
  9. data/bin/review-checkdep +63 -0
  10. data/bin/review-compile +205 -0
  11. data/bin/review-epubmaker +661 -0
  12. data/bin/review-epubmaker-ng +176 -0
  13. data/bin/review-index +118 -0
  14. data/bin/review-pdfmaker +208 -0
  15. data/bin/review-preproc +142 -0
  16. data/bin/review-validate +51 -0
  17. data/bin/review-vol +102 -0
  18. data/debian/README.Debian +12 -0
  19. data/debian/README.source +5 -0
  20. data/debian/changelog +5 -0
  21. data/debian/compat +1 -0
  22. data/debian/control +22 -0
  23. data/debian/copyright +62 -0
  24. data/debian/docs +6 -0
  25. data/debian/manpage.1.ex +59 -0
  26. data/debian/patches/path.diff +91 -0
  27. data/debian/patches/series +1 -0
  28. data/debian/review.install +13 -0
  29. data/debian/review.links +4 -0
  30. data/debian/rules +13 -0
  31. data/debian/source/format +1 -0
  32. data/doc/format.rdoc +582 -0
  33. data/doc/format_idg.rdoc +180 -0
  34. data/doc/libepubmaker/sample.yaml +90 -0
  35. data/doc/quickstart.rdoc +188 -0
  36. data/doc/ruby-uuid/README +11 -0
  37. data/doc/ruby-uuid/README.ja +34 -0
  38. data/doc/sample.css +108 -0
  39. data/doc/sample.yaml +62 -0
  40. data/lib/epubmaker.rb +28 -0
  41. data/lib/epubmaker/content.rb +82 -0
  42. data/lib/epubmaker/epubv2.rb +418 -0
  43. data/lib/epubmaker/epubv3.rb +249 -0
  44. data/lib/epubmaker/producer.rb +204 -0
  45. data/lib/epubmaker/resource.rb +66 -0
  46. data/lib/lineinput.rb +155 -0
  47. data/lib/review.rb +3 -0
  48. data/lib/review/book.rb +46 -0
  49. data/lib/review/book/base.rb +235 -0
  50. data/lib/review/book/chapter.rb +81 -0
  51. data/lib/review/book/compilable.rb +159 -0
  52. data/lib/review/book/index.rb +339 -0
  53. data/lib/review/book/page_metric.rb +38 -0
  54. data/lib/review/book/parameters.rb +97 -0
  55. data/lib/review/book/part.rb +44 -0
  56. data/lib/review/book/volume.rb +65 -0
  57. data/lib/review/builder.rb +444 -0
  58. data/lib/review/compiler.rb +550 -0
  59. data/lib/review/configure.rb +38 -0
  60. data/lib/review/epubbuilder.rb +18 -0
  61. data/lib/review/exception.rb +21 -0
  62. data/lib/review/extentions.rb +3 -0
  63. data/lib/review/extentions/object.rb +9 -0
  64. data/lib/review/extentions/string.rb +33 -0
  65. data/lib/review/htmlbuilder.rb +1097 -0
  66. data/lib/review/htmllayout.rb +19 -0
  67. data/lib/review/htmlutils.rb +36 -0
  68. data/lib/review/i18n.rb +30 -0
  69. data/lib/review/i18n.yaml +34 -0
  70. data/lib/review/idgxmlbuilder.rb +1145 -0
  71. data/lib/review/latexbuilder.rb +815 -0
  72. data/lib/review/latexindex.rb +35 -0
  73. data/lib/review/latexutils.rb +79 -0
  74. data/lib/review/preprocessor.rb +563 -0
  75. data/lib/review/review.tex.erb +232 -0
  76. data/lib/review/textbuilder.rb +17 -0
  77. data/lib/review/textutils.rb +66 -0
  78. data/lib/review/tocparser.rb +342 -0
  79. data/lib/review/tocprinter.rb +221 -0
  80. data/lib/review/topbuilder.rb +785 -0
  81. data/lib/review/unfold.rb +138 -0
  82. data/lib/uuid.rb +312 -0
  83. data/review.gemspec +141 -0
  84. data/test/CHAPS +2 -0
  85. data/test/bib.re +13 -0
  86. data/test/book_test_helper.rb +35 -0
  87. data/test/test.re +43 -0
  88. data/test/test_book.rb +598 -0
  89. data/test/test_book_chapter.rb +418 -0
  90. data/test/test_book_parameter.rb +42 -0
  91. data/test/test_book_part.rb +50 -0
  92. data/test/test_builder.rb +144 -0
  93. data/test/test_compiler.rb +44 -0
  94. data/test/test_epubmaker.rb +507 -0
  95. data/test/test_helper.rb +27 -0
  96. data/test/test_htmlbuilder.rb +554 -0
  97. data/test/test_htmlutils.rb +28 -0
  98. data/test/test_i18n.rb +64 -0
  99. data/test/test_idgxmlbuilder.rb +589 -0
  100. data/test/test_index.rb +31 -0
  101. data/test/test_latexbuilder.rb +656 -0
  102. data/test/test_lineinput.rb +198 -0
  103. data/test/test_preprocessor.rb +23 -0
  104. data/test/test_textutils.rb +68 -0
  105. data/test/test_topbuilder.rb +244 -0
  106. data/test/test_uuid.rb +156 -0
  107. metadata +161 -0
@@ -0,0 +1,11 @@
1
+ For GitHub users;
2
+
3
+ This is a pure-ruby implementation of RFC4122 that I wrote back in
4
+ 2005. I have touched its internals a few times (mainly bugfixes). I
5
+ know someone has already uploaded an old copy of it to GitHub, and
6
+ thats' 100% legal he has the right to do so, but I believe what I have
7
+ now is better than the older ones. So I upload this.
8
+
9
+ It's very tiny (<300 lines ruby code) and you can simply copy
10
+ lib/uuid.rb to your project. The gemspec file can help you maintain
11
+ your dependency though.
@@ -0,0 +1,34 @@
1
+ UUID: Pure-ruby RFC4122 Implementation
2
+
3
+ RFC4122をフルサポート(はず)のライブラリ。使いかたは
4
+
5
+ require 'uuid'
6
+ UUID.create # => instance
7
+
8
+ とか。
9
+
10
+ 基本的にUUIDってのは存在していることに意味があるオブジェクトなため、それ自身には
11
+ ほとんどインスタンスメソッドを持たない。以下はその数少ないメソッドたち
12
+
13
+ * UUID#==, UUID#<=>
14
+ 比較。RFC4122によるとなぜかUUIDは順序つきなんだそうだ。何に使うのか不明。RFCに準
15
+ 拠するためだけのメソッド。
16
+
17
+ * UUID#to_i, UUID#to_int
18
+ 128bit unsigned intとみなして整数化。
19
+
20
+ * UUID#to_s, UUID#to_uri, UUID#guid
21
+ 人間が読める文字列にする。to_uriはRFC4122が定めるURIとして変換。guidはよく
22
+ Windowsとかで見るあれ。
23
+
24
+ * UUID#raw_bytes
25
+ これも文字列を返すんだけど、基本的には読めない。128bit長のUUID値そのもの。
26
+
27
+
28
+ # Local Variables:
29
+ # mode: text
30
+ # indent-tabs-mode: t
31
+ # tab-width: 8
32
+ # fill-column: 79
33
+ # default-justification: full
34
+ # End:
@@ -0,0 +1,108 @@
1
+ @charset "utf-8";
2
+
3
+ h1 {
4
+ color: #000080;
5
+ font-weight: bold;
6
+ text-align: center;
7
+ }
8
+
9
+ h2 {
10
+ color: #000080;
11
+ font-weight: bold;
12
+ border-bottom: dotted 1px #000080;
13
+ margin-top: 1em;
14
+ }
15
+
16
+ h3 {
17
+ color: #000080;
18
+ border-bottom: dotted 1px #000080;
19
+ margin-top: 1em;
20
+ }
21
+
22
+ p.lead {
23
+ padding: 1em;
24
+ background: #c0c0ff;
25
+ }
26
+
27
+ p.footnote {
28
+ font-size: xx-small;
29
+ padding: 1em;
30
+ background: #d0d0d0;
31
+ }
32
+
33
+ p.sourcecaption {
34
+ font-weight: bold;
35
+ text-align: center;
36
+ }
37
+ p.imagecaption {
38
+ font-weight: bold;
39
+ text-align: center;
40
+ }
41
+ p.listcaption {
42
+ font-weight: bold;
43
+ text-align: center;
44
+ }
45
+ p.emlistcaption {
46
+ font-weight: bold;
47
+ text-align: center;
48
+ }
49
+ p.tablecaption {
50
+ font-weight: bold;
51
+ text-align: center;
52
+ }
53
+ p.notecaption {
54
+ font-weight: bold;
55
+ text-align: center;
56
+ }
57
+
58
+ img {
59
+ text-align: center;
60
+ }
61
+
62
+ table {
63
+ border: solid 1px #000000;
64
+ width: 90%;
65
+ margin-bottom: 1em;
66
+ }
67
+
68
+ th {
69
+ border-bottom: solid 1px #000000;
70
+ background: #800000;
71
+ color: #ffffff;
72
+ }
73
+
74
+ span.kw {
75
+ font-weight: bold;
76
+ }
77
+
78
+ div.column {
79
+ padding: 0.5em;
80
+ background: #ffd0d0;
81
+ border: dotted 2px #808080;
82
+ }
83
+
84
+ div.image {
85
+ text-align: center;
86
+ }
87
+
88
+ div h5 {
89
+ font-size: larger;
90
+ border-bottom: solid 1px #000000;
91
+ }
92
+
93
+ p {
94
+ text-indent: 1em;
95
+ }
96
+
97
+ p.caption {
98
+ font-weight: bold;
99
+ text-indent: 0em;
100
+ }
101
+
102
+ p.noindent {
103
+ text-indent: 0em;
104
+ }
105
+
106
+ p.flushright {
107
+ text-align: right;
108
+ }
@@ -0,0 +1,62 @@
1
+ # review-epubmaker向けの設定ファイルの例。
2
+ # yamlファイルをReVIEWファイルのある場所に置き、
3
+ # 「review-epubmaker yamlファイル」を実行すると、<bookname>.epubファイルが
4
+ # 生成されます。
5
+ # このファイルはUTF-8エンコーディングで記述してください。
6
+
7
+ # ブック名(ファイル名になるもの。ASCII範囲の文字を使用)
8
+ bookname: review-sample
9
+ # 書名
10
+ booktitle: ReVIEW EPUBサンプル
11
+ # 著者
12
+ aut: 吟遊詩人
13
+ # 以下はオプション
14
+ # prt: 出版社
15
+ # asn: Associated name
16
+ # ant: Bibliographic antecedent
17
+ # clb: 貢献者
18
+ # edt: 編集者
19
+ # dsr: デザイナ
20
+ # ill: イラストレータ
21
+ # pht: 撮影者
22
+ # trl: 翻訳者
23
+ # date: 刊行日
24
+ # rights: 権利表記
25
+ # description: ブックの説明
26
+ #
27
+ # coverfile: カバーページのbody要素内に挿入する内容を記述したファイル名
28
+ #
29
+ # coverimage: カバー用画像。画像ディレクトリ内に置いてもディレクトリ名は不要(例: cover.jpg)
30
+ #
31
+ # 固有IDに使用するドメイン。指定しない場合には、時刻に基づくランダムUUIDが入る
32
+ # urnid: urn:uid:http://example.com/some-book-title/1.0.2/
33
+ # CSSファイル (yamlファイルおよびReVIEWファイルを置いたディレクトリにあること)
34
+ stylesheet: stylesheet.css
35
+ # LaTeX用のスタイルファイル(styディレクトリ以下に置くこと)
36
+ # texstyle: samplemacro
37
+ # LaTeX用のdocumentclassを指定する
38
+ # texdocumentclass: ["jsarticle", "b5paper,oneside"]
39
+ # 目次として抽出するレベル
40
+ toclevel: 3
41
+ # セクション番号を表示するレベル
42
+ secnolevel: 2
43
+ # EPUBのバージョン(現時点では2または3。デフォルトは2)
44
+ epubversion: 2
45
+ # HTMLのバージョン(現時点では4または5。デフォルトは4。epubversionを3にした場合は自動で5に設定される)
46
+ htmlversion: 4
47
+ # 表紙を出力するか
48
+ titlepage: true
49
+ # 目次を出力するか
50
+ toc: true
51
+ # EPUB標準の目次以外に目次を作成するか
52
+ mytoc: null
53
+ # 奥付を作成するか。デフォルトでは作成されない。trueを指定するとデフォルトの奥付、ファイル名を指定するとそれがcolophon.htmlとしてコピーされる
54
+ colophon: null
55
+ # XHTML生成後に実行するプログラム。$1:HTMLの生成されたディレクトリ $2:ReVIEWファイルのあるディレクトリ $3:起動時指定のyamlファイル名
56
+ # posthook: hook.sh
57
+ # EPUBで表紙をコンテンツに含めるか。デフォルトでは作成されない。yesにするとiBooks等でも最初に表紙が表示されるようになる
58
+ cover_linear: null
59
+ # review-compileに渡すパラメータ
60
+ params: --stylesheet=sample.css
61
+ # デバッグフラグ。nullでないときには一時ファイルをカレントディレクトリに作成し、削除もしない
62
+ debug: null
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ # = epubmaker.rb -- EPUB production set.
3
+ #
4
+ # Copyright (c) 2010-2012 Kenshi Muto
5
+ #
6
+ # This program is free software.
7
+ # You can distribute or modify this program under the terms of
8
+ # the GNU LGPL, Lesser General Public License version 2.1.
9
+ # For details of the GNU LGPL, see the file "COPYING".
10
+ #
11
+ # == Quick usage
12
+ # (If you put xhtml files on current directory and put figures in
13
+ # images subdirectory)
14
+ #
15
+ # require 'epubmaker'
16
+ # epub = EPUBMaker::Producer.new
17
+ # params = epub.load("config.yaml")
18
+ # epub.contents.push(EPUBMaker::Content.new({"file" => "ch01.xhtml"}))
19
+ # epub.contents.push(EPUBMaker::Content.new({"file" => "ch02.xhtml"}))
20
+ # ...
21
+ # epub.importImageInfo("images")
22
+ # epub.produce
23
+
24
+ require 'epubmaker/producer'
25
+ require 'epubmaker/resource'
26
+ require 'epubmaker/content'
27
+ require 'epubmaker/epubv2'
28
+ require 'epubmaker/epubv3'
@@ -0,0 +1,82 @@
1
+ # encoding: utf-8
2
+ # = content.rb -- Content object for EPUBMaker.
3
+ #
4
+ # Copyright (c) 2010 Kenshi Muto
5
+ #
6
+ # This program is free software.
7
+ # You can distribute or modify this program under the terms of
8
+ # the GNU LGPL, Lesser General Public License version 2.1.
9
+ # For details of the GNU LGPL, see the file "COPYING".
10
+ #
11
+
12
+ module EPUBMaker
13
+
14
+ # EPUBMaker::Content describes a content data for EPUBMaker. EPUBMaker#contents takes an array of Content.
15
+ class Content
16
+ # ID
17
+ attr_accessor :id
18
+ # File path (can accept #<anchor> suffix also)
19
+ attr_accessor :file
20
+ # MIME type
21
+ attr_accessor :media
22
+ # Title
23
+ attr_accessor :title
24
+ # Header level (from 1)
25
+ attr_accessor :level
26
+ # Show in TOC? nil:No.
27
+ attr_accessor :notoc
28
+
29
+ # :call-seq:
30
+ # initialize(file, id, media, title, level, notoc)
31
+ # initialize(hash)
32
+ # Construct Content object by passing a sequence of parameters or hash.
33
+ # Keys of +hash+ relate with each parameters.
34
+ # +file+ (or +hash+["file"]) is required. Others are optional.
35
+ def initialize(fileorhash, id=nil, media=nil, title=nil, level=nil, notoc=nil)
36
+ if fileorhash.instance_of?(Hash)
37
+ @id = fileorhash["id"]
38
+ @file = fileorhash["file"]
39
+ @media = fileorhash["media"]
40
+ @title = fileorhash["title"]
41
+ @level = fileorhash["level"]
42
+ @notoc = fileorhash["notoc"]
43
+ else
44
+ @file = fileorhash
45
+ @id = id
46
+ @media = media
47
+ @title = title
48
+ @level = level
49
+ @notoc = notoc
50
+ end
51
+ complement
52
+ end
53
+
54
+ def ==(obj)
55
+ if self.class != obj.class
56
+ return false
57
+ end
58
+ [self.id, self.file, self.media, self.title, self.level, self.notoc] ==
59
+ [obj.id, obj.file, obj.media, obj.title, obj.level, obj.notoc]
60
+ end
61
+
62
+ private
63
+
64
+ # Complement other parameters from file parameter.
65
+ def complement
66
+ @id = @file.gsub(/[\\\/\.]/, '-') if @id.nil?
67
+ @media = @file.sub(/.+\./, '').downcase if !@file.nil? && @media.nil?
68
+
69
+ @media = "application/xhtml+xml" if @media == "xhtml" || @media == "xml" || @media == "html"
70
+ @media = "text/css" if @media == "css"
71
+ @media = "image/jpeg" if @media == "jpg" || @media == "jpeg" || @media == "image/jpg"
72
+ @media = "image/png" if @media == "png"
73
+ @media = "image/gif" if @media == "gif"
74
+ @media = "image/svg" if @media == "svg"
75
+ @media = "image/svg+xml" if @media == "svg" || @media == "image/svg"
76
+
77
+ if @id.nil? || @file.nil? || @media.nil?
78
+ raise "Type error: #{id}, #{file}, #{media}, #{title}, #{notoc}"
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,418 @@
1
+ # encoding: utf-8
2
+ # = epubv2.rb -- EPUB version 2 producer.
3
+ #
4
+ # Copyright (c) 2010-2012 Kenshi Muto and Masayoshi Takahashi
5
+ #
6
+ # This program is free software.
7
+ # You can distribute or modify this program under the terms of
8
+ # the GNU LGPL, Lesser General Public License version 2.1.
9
+ # For details of the GNU LGPL, see the file "COPYING".
10
+ #
11
+
12
+ require 'epubmaker/producer'
13
+ require 'cgi'
14
+
15
+ module EPUBMaker
16
+
17
+ # EPUBv2 is EPUB version 2 producer.
18
+ class EPUBv2
19
+ # Construct object with parameter hash +params+ and message resource hash +res+.
20
+ def initialize(producer)
21
+ @producer = producer
22
+ end
23
+
24
+ # Return mimetype content.
25
+ def mimetype
26
+ return "application/epub+zip"
27
+ end
28
+
29
+ # Return opf file content.
30
+ def opf
31
+ s = <<EOT
32
+ <?xml version="1.0" encoding="UTF-8"?>
33
+ <package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
34
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
35
+ EOT
36
+ %w[title language date type format source description relation coverage subject rights].each do |item|
37
+ next if @producer.params[item].nil?
38
+ if @producer.params[item].instance_of?(Array)
39
+ s << @producer.params[item].map {|i| %Q[ <dc:#{item}>#{CGI.escapeHTML(i.to_s)}</dc:#{item}>\n]}.join
40
+ else
41
+ s << %Q[ <dc:#{item}>#{CGI.escapeHTML(@producer.params[item].to_s)}</dc:#{item}>\n]
42
+ end
43
+ end
44
+
45
+ # ID
46
+ if @producer.params["isbn"].nil?
47
+ s << %Q[ <dc:identifier id="BookId">#{@producer.params["urnid"]}</dc:identifier>\n]
48
+ else
49
+ s << %Q[ <dc:identifier id="BookId" opf:scheme="ISBN">#{@producer.params["isbn"]}</dc:identifier>\n]
50
+ end
51
+
52
+ # creator
53
+ %w[aut a-adp a-ann a-arr a-art a-asn a-aqt a-aft a-aui a-ant a-bkp a-clb a-cmm a-dsr a-edt a-ill a-lyr a-mdc a-mus a-nrt a-oth a-pht a-prt a-red a-rev a-spn a-ths a-trc a-trl].each do |role|
54
+ next if @producer.params[role].nil?
55
+ @producer.params[role].each do |v|
56
+ s << %Q[ <dc:creator opf:role="#{role.sub('a-', '')}">#{CGI.escapeHTML(v)}</dc:creator>\n]
57
+ end
58
+ end
59
+ # contributor
60
+ %w[adp ann arr art asn aqt aft aui ant bkp clb cmm dsr edt ill lyr mdc mus nrt oth pht prt red rev spn ths trc trl].each do |role|
61
+ next if @producer.params[role].nil?
62
+ @producer.params[role].each do |v|
63
+ s << %Q[ <dc:contributor opf:role="#{role}">#{CGI.escapeHTML(v)}</dc:contributor>\n]
64
+ if role == "prt"
65
+ s << %Q[ <dc:publisher>#{v}</dc:publisher>\n]
66
+ end
67
+ end
68
+ end
69
+
70
+ if @producer.params["coverimage"]
71
+ @producer.contents.each do |item|
72
+ if item.media =~ /\Aimage/ && item.file =~ /#{@producer.params["coverimage"]}\Z/
73
+ s << %Q[ <meta name="cover" content="#{item.id}"/>\n]
74
+ break
75
+ end
76
+ end
77
+ end
78
+
79
+ s << %Q[ </metadata>\n]
80
+
81
+ # manifest
82
+ s << <<EOT
83
+ <manifest>
84
+ <item id="ncx" href="#{@producer.params["bookname"]}.ncx" media-type="application/x-dtbncx+xml"/>
85
+ <item id="#{@producer.params["bookname"]}" href="#{@producer.params["cover"]}" media-type="application/xhtml+xml"/>
86
+ EOT
87
+
88
+ s << %Q[ <item id="toc" href="#{@producer.params["tocfile"]}" media-type="application/xhtml+xml"/>\n] unless @producer.params["mytoc"].nil?
89
+
90
+ @producer.contents.each do |item|
91
+ next if item.file =~ /#/ # skip subgroup
92
+ s << %Q[ <item id="#{item.id}" href="#{item.file}" media-type="#{item.media}"/>\n]
93
+ end
94
+ s << %Q[ </manifest>\n]
95
+
96
+ # tocx
97
+ s << %Q[ <spine toc="ncx">\n]
98
+ s << %Q[ <itemref idref="#{@producer.params["bookname"]}" linear="no"/>\n]
99
+ s << %Q[ <itemref idref="toc" />\n] unless @producer.params["mytoc"].nil?
100
+
101
+ @producer.contents.each do |item|
102
+ next if item.media !~ /xhtml\+xml/ # skip non XHTML
103
+ s << %Q[ <itemref idref="#{item.id}"/>\n] if item.notoc.nil?
104
+ end
105
+ s << %Q[ </spine>\n]
106
+
107
+ # guide
108
+ s << %Q[ <guide>\n]
109
+ s << %Q[ <reference type="cover" title="#{@producer.res.v("covertitle")}" href="#{@producer.params["cover"]}"/>\n]
110
+ s << %Q[ <reference type="title-page" title="#{@producer.res.v("titlepagetitle")}" href="#{@producer.params["titlepage"]}"/>\n] unless @producer.params["titlepage"].nil?
111
+ s << %Q[ <reference type="toc" title="#{@producer.res.v("toctitle")}" href="#{@producer.params["tocfile"]}"/>\n] unless @producer.params["mytoc"].nil?
112
+ s << %Q[ <reference type="colophon" title="#{@producer.res.v("colophontitle")}" href="colophon.#{@producer.params["htmlext"]}"/>\n] unless @producer.params["colophon"].nil? # FIXME: path
113
+ s << %Q[ </guide>\n]
114
+ s << %Q[</package>\n]
115
+ return s
116
+ end
117
+
118
+ # Return ncx content. +indentarray+ defines prefix string for each level.
119
+ def ncx(indentarray)
120
+ s = <<EOT
121
+ <?xml version="1.0" encoding="UTF-8"?>
122
+ <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
123
+ <head>
124
+ <meta name="dtb:depth" content="1"/>
125
+ <meta name="dtb:totalPageCount" content="0"/>
126
+ <meta name="dtb:maxPageNumber" content="0"/>
127
+ EOT
128
+ if @producer.params["isbn"].nil?
129
+ s << %Q[ <meta name="dtb:uid" content="#{@producer.params["urnid"]}"/>\n]
130
+ else
131
+ s << %Q[ <meta name="dtb:uid" content="#{@producer.params["isbn"]}"/>\n]
132
+ end
133
+
134
+ s << <<EOT
135
+ </head>
136
+ <docTitle>
137
+ <text>#{CGI.escapeHTML(@producer.params["title"])}</text>
138
+ </docTitle>
139
+ <docAuthor>
140
+ <text>#{@producer.params["aut"].nil? ? "" : CGI.escapeHTML(@producer.params["aut"].join(", "))}</text>
141
+ </docAuthor>
142
+ <navMap>
143
+ <navPoint id="top" playOrder="1">
144
+ <navLabel>
145
+ <text>#{CGI.escapeHTML(@producer.params["title"])}</text>
146
+ </navLabel>
147
+ <content src="#{@producer.params["cover"]}"/>
148
+ </navPoint>
149
+ EOT
150
+
151
+ nav_count = 2
152
+
153
+ unless @producer.params["mytoc"].nil?
154
+ s << <<EOT
155
+ <navPoint id="toc" playOrder="#{nav_count}">
156
+ <navLabel>
157
+ <text>#{@producer.res.v("toctitle")}</text>
158
+ </navLabel>
159
+ <content src="#{@producer.params["tocfile"]}"/>
160
+ </navPoint>
161
+ EOT
162
+ nav_count += 1
163
+ end
164
+
165
+ @producer.contents.each do |item|
166
+ next if item.title.nil?
167
+ indent = indentarray.nil? ? [""] : indentarray
168
+ level = item.level.nil? ? 0 : (item.level - 1)
169
+ level = indent.size - 1 if level >= indent.size
170
+ s << <<EOT
171
+ <navPoint id="nav-#{nav_count}" playOrder="#{nav_count}">
172
+ <navLabel>
173
+ <text>#{indent[level]}#{item.title}</text>
174
+ </navLabel>
175
+ <content src="#{item.file}"/>
176
+ </navPoint>
177
+ EOT
178
+ nav_count += 1
179
+ end
180
+
181
+ s << <<EOT
182
+ </navMap>
183
+ </ncx>
184
+ EOT
185
+ return s
186
+ end
187
+
188
+ # Return container content.
189
+ def container
190
+ s = <<EOT
191
+ <?xml version="1.0" encoding="UTF-8"?>
192
+ <container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
193
+ <rootfiles>
194
+ <rootfile full-path="OEBPS/#{@producer.params["bookname"]}.opf" media-type="application/oebps-package+xml" />
195
+ </rootfiles>
196
+ </container>
197
+ EOT
198
+ return s
199
+ end
200
+
201
+ # Return cover content.
202
+ def cover
203
+ s = common_header
204
+ s << <<EOT
205
+ <title>#{CGI.escapeHTML(@producer.params["title"])}</title>
206
+ </head>
207
+ <body>
208
+ EOT
209
+ if @producer.params["coverimage"].nil?
210
+ s << <<EOT
211
+ <h1 class="cover-title">#{CGI.escapeHTML(@producer.params["title"])}</h1>
212
+ EOT
213
+ else
214
+ file = nil
215
+ @producer.contents.each do |item|
216
+ if item.media =~ /\Aimage/ && item.file =~ /#{@producer.params["coverimage"]}\Z/ # /
217
+ file = item.file
218
+ break
219
+ end
220
+ end
221
+ raise "coverimage #{@producer.params["coverimage"]} not found. Abort." if file.nil?
222
+ s << <<EOT
223
+ <div id="cover-image" class="cover-image">
224
+ <img src="#{file}" alt="#{CGI.escapeHTML(@producer.params["title"])}" class="max"/>
225
+ </div>
226
+ EOT
227
+ end
228
+
229
+ s << <<EOT
230
+ </body>
231
+ </html>
232
+ EOT
233
+ return s
234
+ end
235
+
236
+ # Return title (copying) content.
237
+ def titlepage
238
+ s = common_header
239
+ s << <<EOT
240
+ <title>#{CGI.escapeHTML(@producer.params["title"])}</title>
241
+ </head>
242
+ <body>
243
+ <h1 class="tp-title">#{CGI.escapeHTML(@producer.params["title"])}</h1>
244
+ EOT
245
+
246
+ if @producer.params["aut"]
247
+ s << <<EOT
248
+ <p>
249
+ <br />
250
+ <br />
251
+ </p>
252
+ <h2 class="tp-author">#{CGI.escapeHTML(@producer.params["aut"])}</h2>
253
+ EOT
254
+ end
255
+
256
+ if @producer.params["prt"]
257
+ s << <<EOT
258
+ <p>
259
+ <br />
260
+ <br />
261
+ <br />
262
+ <br />
263
+ </p>
264
+ <h3 class="tp-publisher">#{CGI.escapeHTML(@producer.params["prt"])}</h3>
265
+ EOT
266
+ end
267
+
268
+ s << <<EOT
269
+ </body>
270
+ </html>
271
+ EOT
272
+ return s
273
+ end
274
+
275
+ # Return colophon content.
276
+ def colophon
277
+ s = common_header
278
+ s << <<EOT
279
+ <title>#{@producer.res.v("colophontitle")}</title>
280
+ </head>
281
+ <body>
282
+ <div class="colophon">
283
+ <p class="title">#{CGI.escapeHTML(@producer.params["title"])}</p>
284
+ EOT
285
+
286
+ if @producer.params["pubhistory"]
287
+ s << %Q[ <div class="pubhistory">\n <p>#{@producer.params["pubhistory"].gsub(/\n/, "<br />")}</p>\n </div>\n] # FIXME: should be array?
288
+ end
289
+
290
+ s << %Q[ <table class="colophon">\n]
291
+ s << %Q[ <tr><th>#{@producer.res.v("c-aut")}</th><td>#{CGI.escapeHTML(@producer.params["aut"])}</td></tr>\n] if @producer.params["aut"]
292
+ s << %Q[ <tr><th>#{@producer.res.v("c-dsr")}</th><td>#{CGI.escapeHTML(@producer.params["dsr"])}</td></tr>\n] if @producer.params["dsr"]
293
+ s << %Q[ <tr><th>#{@producer.res.v("c-ill")}</th><td>#{CGI.escapeHTML(@producer.params["ill"])}</td></tr>\n] if @producer.params["ill"]
294
+ s << %Q[ <tr><th>#{@producer.res.v("c-edt")}</th><td>#{CGI.escapeHTML(@producer.params["edt"])}</td></tr>\n] if @producer.params["edt"]
295
+ s << %Q[ <tr><th>#{@producer.res.v("c-prt")}</th><td>#{CGI.escapeHTML(@producer.params["prt"])}</td></tr>\n] if @producer.params["prt"]
296
+ s << <<EOT
297
+ </table>
298
+ </div>
299
+ </body>
300
+ </html>
301
+ EOT
302
+ return s
303
+ end
304
+
305
+ # Return own toc content.
306
+ def mytoc
307
+ s = common_header
308
+ s << <<EOT
309
+ <title>#{@producer.res.v("toctitle")}</title>
310
+ </head>
311
+ <body>
312
+ <h1 class="toc-title">#{@producer.res.v("toctitle")}</h1>
313
+ <ul class="toc-h1">
314
+ EOT
315
+
316
+ # FIXME: indent
317
+ current = 1
318
+ init_item = true
319
+ @producer.contents.each do |item|
320
+ next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > @producer.params["toclevel"].to_i
321
+ if item.level > current
322
+ s << %Q[\n<ul class="toc-h#{item.level}">\n]
323
+ current = item.level
324
+ elsif item.level < current
325
+ (current - 1).downto(item.level) do |n|
326
+ s << %Q[</li>\n</ul>\n]
327
+ end
328
+ s << %Q[</li>\n]
329
+ current = item.level
330
+ elsif init_item
331
+ # noop
332
+ else
333
+ s << %Q[</li>\n]
334
+ end
335
+ s << %Q[<li><a href="#{item.file}">#{item.title}</a>]
336
+ init_item = false
337
+ end
338
+
339
+ (current - 1).downto(1) do |n|
340
+ s << %Q[</li>\n</ul>\n]
341
+ end
342
+ if !init_item
343
+ s << %Q[</li>\n]
344
+ end
345
+ s << <<EOT
346
+ </ul>
347
+ </body>
348
+ </html>
349
+ EOT
350
+ return s
351
+ end
352
+
353
+ # Produce EPUB file +epubfile+.
354
+ # +basedir+ points the directory has contents.
355
+ # +tmpdir+ defines temporary directory.
356
+ def produce(epubfile, basedir, tmpdir)
357
+ File.open("#{tmpdir}/mimetype", "w") {|f| @producer.mimetype(f) }
358
+
359
+ Dir.mkdir("#{tmpdir}/META-INF") unless File.exist?("#{tmpdir}/META-INF")
360
+ File.open("#{tmpdir}/META-INF/container.xml", "w") {|f| @producer.container(f) }
361
+
362
+ Dir.mkdir("#{tmpdir}/OEBPS") unless File.exist?("#{tmpdir}/OEBPS")
363
+ File.open("#{tmpdir}/OEBPS/#{@producer.params["bookname"]}.opf", "w") {|f| @producer.opf(f) }
364
+ File.open("#{tmpdir}/OEBPS/#{@producer.params["bookname"]}.ncx", "w") {|f| @producer.ncx(f, @producer.params["ncxindent"]) }
365
+ File.open("#{tmpdir}/OEBPS/#{@producer.params["tocfile"]}", "w") {|f| @producer.mytoc(f) } unless @producer.params["mytoc"].nil?
366
+
367
+ if File.exist?("#{basedir}/#{@producer.params["cover"]}")
368
+ FileUtils.cp("#{basedir}/#{@producer.params["cover"]}", "#{tmpdir}/OEBPS")
369
+ else
370
+ File.open("#{tmpdir}/OEBPS/#{@producer.params["cover"]}", "w") {|f| @producer.cover(f) }
371
+ end
372
+
373
+ # FIXME:colophon and titlepage should be included in @producer.contents.
374
+
375
+ @producer.contents.each do |item|
376
+ next if item.file =~ /#/ # skip subgroup
377
+ fname = "#{basedir}/#{item.file}"
378
+ raise "#{fname} doesn't exist. Abort." unless File.exist?(fname)
379
+ FileUtils.mkdir_p(File.dirname("#{tmpdir}/OEBPS/#{item.file}")) unless File.exist?(File.dirname("#{tmpdir}/OEBPS/#{item.file}"))
380
+ FileUtils.cp(fname, "#{tmpdir}/OEBPS/#{item.file}")
381
+ end
382
+
383
+ fork {
384
+ Dir.chdir(tmpdir) {|d|
385
+ exec("zip", "-0X", "#{epubfile}", "mimetype")
386
+ }
387
+ }
388
+ Process.waitall
389
+ fork {
390
+ Dir.chdir(tmpdir) {|d|
391
+ exec("zip", "-Xr9D", "#{epubfile}", "META-INF", "OEBPS")
392
+ }
393
+ }
394
+ Process.waitall
395
+ end
396
+
397
+ private
398
+
399
+ # Return common XHTML headder
400
+ def common_header
401
+ s =<<EOT
402
+ <?xml version="1.0" encoding="UTF-8"?>
403
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
404
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="#{@producer.params["language"]}">
405
+ <head>
406
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
407
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
408
+ <meta name="generator" content="EPUBMaker::Producer"/>
409
+ EOT
410
+
411
+ @producer.params["stylesheet"].each do |file|
412
+ s << %Q[ <link rel="stylesheet" type="text/css" href="#{file}"/>\n]
413
+ end
414
+ return s
415
+ end
416
+ end
417
+
418
+ end