tmtms-review 1.0.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 (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