review 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/.travis.yml +1 -2
  2. data/ChangeLog +65 -0
  3. data/Gemfile +5 -0
  4. data/README.rdoc +6 -1
  5. data/Rakefile +14 -28
  6. data/bin/review-check +9 -21
  7. data/bin/review-compile +45 -12
  8. data/bin/review-epubmaker +477 -220
  9. data/bin/review-epubmaker-ng +5 -14
  10. data/bin/review-index +4 -2
  11. data/bin/review-init +94 -0
  12. data/bin/review-pdfmaker +70 -287
  13. data/bin/review-preproc +5 -2
  14. data/bin/review-vol +4 -11
  15. data/debian/changelog +3 -3
  16. data/debian/copyright +5 -3
  17. data/debian/docs +1 -0
  18. data/doc/format.rdoc +57 -11
  19. data/doc/quickstart.rdoc +4 -4
  20. data/doc/sample.yaml +11 -7
  21. data/lib/epubmaker.rb +1 -1
  22. data/lib/epubmaker/epubv2.rb +26 -27
  23. data/lib/epubmaker/epubv3.rb +13 -13
  24. data/lib/epubmaker/producer.rb +1 -1
  25. data/lib/review.rb +3 -4
  26. data/lib/review/book.rb +17 -581
  27. data/lib/review/book/base.rb +247 -0
  28. data/lib/review/book/chapter.rb +81 -0
  29. data/lib/review/book/compilable.rb +163 -0
  30. data/lib/review/book/index.rb +339 -0
  31. data/lib/review/book/page_metric.rb +38 -0
  32. data/lib/review/book/parameters.rb +97 -0
  33. data/lib/review/book/part.rb +44 -0
  34. data/lib/review/book/volume.rb +65 -0
  35. data/lib/review/builder.rb +34 -40
  36. data/lib/review/compiler.rb +32 -13
  37. data/lib/review/configure.rb +38 -0
  38. data/lib/review/ewbbuilder.rb +23 -21
  39. data/lib/review/extentions.rb +3 -0
  40. data/lib/review/extentions/object.rb +9 -0
  41. data/lib/review/{compat.rb → extentions/string.rb} +11 -0
  42. data/lib/review/htmlbuilder.rb +162 -74
  43. data/lib/review/htmlutils.rb +28 -1
  44. data/lib/review/i18n.yaml +11 -0
  45. data/lib/review/idgxmlbuilder.rb +119 -35
  46. data/lib/review/inaobuilder.rb +355 -0
  47. data/lib/review/latexbuilder.rb +133 -59
  48. data/lib/review/latexutils.rb +15 -6
  49. data/lib/review/makerhelper.rb +59 -0
  50. data/lib/review/markdownbuilder.rb +129 -0
  51. data/lib/review/preprocessor.rb +20 -7
  52. data/lib/review/review.tex.erb +250 -0
  53. data/lib/review/textutils.rb +28 -3
  54. data/lib/review/tocparser.rb +20 -12
  55. data/lib/review/tocprinter.rb +7 -3
  56. data/lib/review/topbuilder.rb +44 -27
  57. data/lib/review/version.rb +3 -0
  58. data/review.gemspec +20 -117
  59. data/test/book_test_helper.rb +35 -0
  60. data/test/sample-book/README.md +5 -0
  61. data/test/sample-book/src/CHAPS +2 -0
  62. data/test/sample-book/src/PREDEF +1 -0
  63. data/test/sample-book/src/Rakefile +26 -0
  64. data/test/sample-book/src/_cover.html +3 -0
  65. data/test/sample-book/src/ch01.re +71 -0
  66. data/test/sample-book/src/ch02.re +3 -0
  67. data/test/sample-book/src/config.yml +55 -0
  68. data/test/sample-book/src/images/ch01-imgsample.jpg +0 -0
  69. data/test/sample-book/src/images/cover.jpg +0 -0
  70. data/test/sample-book/src/main.css +251 -0
  71. data/test/sample-book/src/preface.re +15 -0
  72. data/test/sample-book/src/sty/jumoline.sty +310 -0
  73. data/test/sample-book/src/sty/samplemacro.sty +21 -0
  74. data/test/sample-book/src/vendor/jumoline/README +29 -0
  75. data/test/sample-book/src/vendor/jumoline/jumoline.dtx +2988 -0
  76. data/test/sample-book/src/vendor/jumoline/jumoline.ins +6 -0
  77. data/test/test_book.rb +26 -646
  78. data/test/test_book_chapter.rb +418 -0
  79. data/test/test_book_parameter.rb +42 -0
  80. data/test/test_book_part.rb +53 -0
  81. data/test/test_builder.rb +17 -10
  82. data/test/test_compiler.rb +46 -0
  83. data/test/test_epubmaker.rb +1 -1
  84. data/test/test_epubmaker_cmd.rb +36 -0
  85. data/test/test_helper.rb +17 -0
  86. data/test/test_htmlbuilder.rb +156 -24
  87. data/test/test_htmlutils.rb +4 -0
  88. data/test/test_i18n.rb +6 -2
  89. data/test/test_idgxmlbuilder.rb +33 -11
  90. data/test/test_inaobuilder.rb +247 -0
  91. data/test/test_index.rb +31 -0
  92. data/test/test_latexbuilder.rb +115 -35
  93. data/test/test_makerhelper.rb +50 -0
  94. data/test/test_pdfmaker_cmd.rb +36 -0
  95. data/test/test_preprocessor.rb +7 -7
  96. data/test/test_topbuilder.rb +6 -7
  97. data/test/test_uuid.rb +1 -0
  98. metadata +117 -12
  99. data/lib/review/index.rb +0 -323
  100. data/lib/review/volume.rb +0 -66
@@ -0,0 +1,247 @@
1
+ #
2
+ # $Id: book.rb 4315 2009-09-02 04:15:24Z kmuto $
3
+ #
4
+ # Copyright (c) 2002-2008 Minero Aoki
5
+ # 2009 Minero Aoki, Kenshi Muto
6
+ #
7
+ # This program is free software.
8
+ # You can distribute or modify this program under the terms of
9
+ # the GNU LGPL, Lesser General Public License version 2.1.
10
+ # For details of the GNU LGPL, see the file "COPYING".
11
+ #
12
+ module ReVIEW
13
+ module Book
14
+ class Base
15
+
16
+ attr_accessor :param
17
+
18
+ def self.load_default
19
+ %w( . .. ../.. ).each do |basedir|
20
+ if File.file?("#{basedir}/CHAPS")
21
+ book = load(basedir)
22
+ if File.file?("#{basedir}/config.rb")
23
+ book.instance_variable_set("@parameters", Parameters.load("#{basedir}/config.rb"))
24
+ end
25
+ return book
26
+ end
27
+ end
28
+ new('.')
29
+ end
30
+
31
+ def self.load(dir)
32
+ update_rubyenv dir
33
+ new(dir)
34
+ end
35
+
36
+ @basedir_seen = {}
37
+
38
+ def self.update_rubyenv(dir)
39
+ return if @basedir_seen.key?(dir)
40
+ if File.directory?("#{dir}/lib/review")
41
+ $LOAD_PATH.unshift "#{dir}/lib"
42
+ end
43
+ if File.file?("#{dir}/review-ext.rb")
44
+ Kernel.load File.expand_path("#{dir}/review-ext.rb")
45
+ end
46
+ @basedir_seen[dir] = true
47
+ end
48
+
49
+ def initialize(basedir, parameters = Parameters.default)
50
+ @basedir = basedir
51
+ @parameters = parameters
52
+ @parts = nil
53
+ @chapter_index = nil
54
+ end
55
+
56
+ extend Forwardable
57
+ def_delegators '@parameters',
58
+ :chapter_file,
59
+ :part_file,
60
+ :bib_file,
61
+ :reject_file,
62
+ :predef_file,
63
+ :postdef_file,
64
+ :ext,
65
+ :image_dir,
66
+ :image_types,
67
+ :page_metric
68
+
69
+ def parts
70
+ @parts ||= read_parts()
71
+ end
72
+
73
+ def parts_in_file
74
+ parts.find_all{|part|
75
+ part if part.present? and part.file?
76
+ }
77
+ end
78
+
79
+ def part(n)
80
+ parts.detect {|part| part.number == n }
81
+ end
82
+
83
+ def each_part(&block)
84
+ parts.each(&block)
85
+ end
86
+
87
+ def chapters
88
+ parts().map {|p| p.chapters }.flatten
89
+ end
90
+
91
+ def each_chapter(&block)
92
+ chapters.each(&block)
93
+ end
94
+
95
+ def chapter_index
96
+ @chapter_index ||= ChapterIndex.new(chapters())
97
+ @chapter_index
98
+ end
99
+
100
+ def chapter(id)
101
+ chapter_index()[id]
102
+ end
103
+
104
+ def volume
105
+ Volume.sum(chapters.map {|chap| chap.volume })
106
+ end
107
+
108
+ def read_CHAPS
109
+ read_FILE("chapter_file")
110
+ end
111
+
112
+ def read_PREDEF
113
+ read_FILE("predef_file")
114
+ end
115
+
116
+ def read_POSTDEF
117
+ read_FILE("postdef_file")
118
+ end
119
+
120
+ def read_PART
121
+ @read_PART ||= File.read("#{@basedir}/#{part_file}")
122
+ end
123
+
124
+ def part_exist?
125
+ File.exist?("#{@basedir}/#{part_file}")
126
+ end
127
+
128
+ def read_bib
129
+ File.read("#{@basedir}/#{bib_file}")
130
+ end
131
+
132
+ def bib_exist?
133
+ File.exist?("#{@basedir}/#{bib_file}")
134
+ end
135
+
136
+ def prefaces
137
+ if File.file?("#{@basedir}/#{predef_file}")
138
+ begin
139
+ return mkpart_from_namelistfile("#{@basedir}/#{predef_file}")
140
+ rescue FileNotFound => err
141
+ raise FileNotFound, "preface #{err.message}"
142
+ end
143
+ else
144
+ mkpart_from_namelist(%w(preface))
145
+ end
146
+ end
147
+
148
+ def postscripts
149
+ if File.file?("#{@basedir}/#{postdef_file}")
150
+ begin
151
+ return mkpart_from_namelistfile("#{@basedir}/#{postdef_file}")
152
+ rescue FileNotFound => err
153
+ raise FileNotFound, "postscript #{err.message}"
154
+ end
155
+ else
156
+ mkpart_from_namelist(%w(appendix postscript))
157
+ end
158
+ end
159
+
160
+ def basedir
161
+ @basedir
162
+ end
163
+
164
+ private
165
+
166
+ def read_parts
167
+ list = parse_chapters
168
+ if pre = prefaces
169
+ list.unshift pre
170
+ end
171
+ if post = postscripts
172
+ list.push post
173
+ end
174
+ list
175
+ end
176
+
177
+ def parse_chapters
178
+ part = 0
179
+ num = 0
180
+ chap = read_CHAPS()\
181
+ .strip.lines.map {|line| line.strip }.join("\n").split(/\n{2,}/)\
182
+ .map {|part_chunk|
183
+ chaps = part_chunk.split.map {|chapid|
184
+ Chapter.new(self, (num += 1), chapid, "#{@basedir}/#{chapid}")
185
+ }
186
+ if part_exist? && read_PART.split("\n").size >= part
187
+ Part.new(self, (part += 1), chaps, read_PART.split("\n")[part-1])
188
+ else
189
+ Part.new(self, (part += 1), chaps)
190
+ end
191
+ }
192
+ return chap
193
+ end
194
+
195
+ def mkpart_from_namelistfile(path)
196
+ chaps = []
197
+ File.read(path).split.each_with_index do |name, idx|
198
+ name.sub!(/\A\xEF\xBB\xBF/u, '') # remove BOM
199
+ if path =~ /PREDEF/
200
+ chaps << mkchap(name)
201
+ else
202
+ chaps << mkchap(name, idx + 1)
203
+ end
204
+ end
205
+ mkpart(chaps)
206
+ end
207
+
208
+ def mkpart_from_namelist(names)
209
+ mkpart(names.map {|n| mkchap_ifexist(n) }.compact)
210
+ end
211
+
212
+ def mkpart(chaps)
213
+ chaps.empty? ? nil : Part.new(self, nil, chaps)
214
+ end
215
+
216
+ def mkchap(name, number = nil)
217
+ name += ext if File.extname(name) == ""
218
+ path = "#{@basedir}/#{name}"
219
+ raise FileNotFound, "file not exist: #{path}" unless File.file?(path)
220
+ Chapter.new(self, number, name, path)
221
+ end
222
+
223
+ def mkchap_ifexist(id)
224
+ name = "#{id}#{ext()}"
225
+ path = "#{@basedir}/#{name}"
226
+ File.file?(path) ? Chapter.new(self, nil, name, path) : nil
227
+ end
228
+
229
+ def read_FILE(filename)
230
+ res = ""
231
+ File.open("#{@basedir}/#{eval(filename)}") do |f|
232
+ while line = f.gets
233
+ line.sub!(/\A\xEF\xBB\xBF/u, '') # remove BOM
234
+ if /\A#/ =~ line
235
+ next
236
+ end
237
+ line.gsub!(/#.*$/, "")
238
+ res << line
239
+ end
240
+ end
241
+ res
242
+ rescue Errno::ENOENT
243
+ Dir.glob("#{@basedir}/*#{ext()}").sort.join("\n")
244
+ end
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,81 @@
1
+ #
2
+ # $Id: book.rb 4315 2009-09-02 04:15:24Z kmuto $
3
+ #
4
+ # Copyright (c) 2002-2008 Minero Aoki
5
+ # 2009 Minero Aoki, Kenshi Muto
6
+ #
7
+ # This program is free software.
8
+ # You can distribute or modify this program under the terms of
9
+ # the GNU LGPL, Lesser General Public License version 2.1.
10
+ # For details of the GNU LGPL, see the file "COPYING".
11
+ #
12
+ require 'review/book/compilable'
13
+ module ReVIEW
14
+ module Book
15
+ class Chapter
16
+ include Compilable
17
+
18
+ def Chapter.intern_pathes(pathes)
19
+ books = {}
20
+ pathes.map {|path|
21
+ basedir = File.dirname(path)
22
+ book = (books[File.expand_path(basedir)] ||= Book.load(basedir))
23
+ begin
24
+ book.chapter(File.basename(path, '.*'))
25
+ rescue KeyError => err
26
+ raise FileNotFound, "no such file: #{path}"
27
+ end
28
+ }
29
+ end
30
+
31
+ def Chapter.for_stdin
32
+ new(nil, nil, '-', nil, $stdin)
33
+ end
34
+
35
+ def Chapter.for_path(number, path)
36
+ new(nil, number, File.basename(path), path)
37
+ end
38
+
39
+ attr_reader :number
40
+
41
+ def initialize(book, number, name, path, io = nil)
42
+ @book = book
43
+ @number = number
44
+ @name = name
45
+ @path = path
46
+ @io = io
47
+ @title = nil
48
+ @content = nil
49
+ @list_index = nil
50
+ @table_index = nil
51
+ @footnote_index = nil
52
+ @image_index = nil
53
+ @icon_index = nil
54
+ @numberless_image_index = nil
55
+ @indepimage_index = nil
56
+ @headline_index = nil
57
+ end
58
+
59
+ def inspect
60
+ "\#<#{self.class} #{@number} #{@path}>"
61
+ end
62
+
63
+ def on_CHAPS?
64
+ on_FILE?(@book.read_CHAPS())
65
+ end
66
+
67
+ def on_PREDEF?
68
+ on_FILE?(@book.read_PREDEF())
69
+ end
70
+
71
+ def on_POSTDEF?
72
+ on_FILE?(@book.read_POSTDEF())
73
+ end
74
+
75
+ private
76
+ def on_FILE?(contents)
77
+ contents.lines.map(&:strip).include?(id() + @book.ext())
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,163 @@
1
+ #
2
+ # $Id: book.rb 4315 2009-09-02 04:15:24Z kmuto $
3
+ #
4
+ # Copyright (c) 2002-2008 Minero Aoki
5
+ # 2009 Minero Aoki, Kenshi Muto
6
+ #
7
+ # This program is free software.
8
+ # You can distribute or modify this program under the terms of
9
+ # the GNU LGPL, Lesser General Public License version 2.1.
10
+ # For details of the GNU LGPL, see the file "COPYING".
11
+ #
12
+ require 'review/textutils'
13
+ module ReVIEW
14
+ module Book
15
+ module Compilable
16
+ include TextUtils
17
+ attr_reader :book
18
+ attr_reader :path
19
+
20
+ def env
21
+ @book
22
+ end
23
+
24
+ def dirname
25
+ return nil unless @path
26
+ File.dirname(@path)
27
+ end
28
+
29
+ def basename
30
+ return nil unless @path
31
+ File.basename(@path)
32
+ end
33
+
34
+ def name
35
+ File.basename(@name, '.*')
36
+ end
37
+
38
+ alias id name
39
+
40
+ def title
41
+ @title = ""
42
+ open {|f|
43
+ f.each_line {|l|
44
+ l = convert_inencoding(l, ReVIEW.book.param["inencoding"])
45
+ if l =~ /\A=+/
46
+ @title = l.sub(/\A=+/, '').strip
47
+ break
48
+ end
49
+ }
50
+ }
51
+ @title
52
+ end
53
+
54
+ def size
55
+ File.size(path())
56
+ end
57
+
58
+ def volume
59
+ @volume ||= Volume.count_file(path())
60
+ end
61
+
62
+ def open(&block)
63
+ return (block_given?() ? yield(@io) : @io) if @io
64
+ File.open(path(), &block)
65
+ end
66
+
67
+ attr_writer :content
68
+
69
+ def content
70
+ @content = convert_inencoding(File.read(path()),
71
+ ReVIEW.book.param["inencoding"])
72
+ rescue
73
+ @content
74
+ end
75
+
76
+ def lines
77
+ # FIXME: we cannot duplicate Enumerator on ruby 1.9 HEAD
78
+ (@lines ||= content().lines.to_a).dup
79
+ end
80
+
81
+ def list(id)
82
+ list_index()[id]
83
+ end
84
+
85
+ def list_index
86
+ @list_index ||= ListIndex.parse(lines())
87
+ @list_index
88
+ end
89
+
90
+ def table(id)
91
+ table_index()[id]
92
+ end
93
+
94
+ def table_index
95
+ @table_index ||= TableIndex.parse(lines())
96
+ @table_index
97
+ end
98
+
99
+ def footnote(id)
100
+ footnote_index()[id]
101
+ end
102
+
103
+ def footnote_index
104
+ @footnote_index ||= FootnoteIndex.parse(lines())
105
+ @footnote_index
106
+ end
107
+
108
+ def image(id)
109
+ return image_index()[id] if image_index().has_key?(id)
110
+ return icon_index()[id] if icon_index().has_key?(id)
111
+ return numberless_image_index()[id] if numberless_image_index().has_key?(id)
112
+ indepimage_index()[id]
113
+ end
114
+
115
+ def numberless_image_index
116
+ @numberless_image_index ||=
117
+ NumberlessImageIndex.parse(lines(), id(),
118
+ "#{book.basedir}#{@book.image_dir}",
119
+ @book.image_types)
120
+ end
121
+
122
+ def image_index
123
+ @image_index ||= ImageIndex.parse(lines(), id(),
124
+ "#{book.basedir}#{@book.image_dir}",
125
+ @book.image_types)
126
+ @image_index
127
+ end
128
+
129
+ def icon_index
130
+ @icon_index ||= IconIndex.parse(lines(), id(),
131
+ "#{book.basedir}#{@book.image_dir}",
132
+ @book.image_types)
133
+ @icon_index
134
+ end
135
+
136
+ def indepimage_index
137
+ @indepimage_index ||=
138
+ IndepImageIndex.parse(lines(), id(),
139
+ "#{book.basedir}#{@book.image_dir}",
140
+ @book.image_types)
141
+ end
142
+
143
+ def bibpaper(id)
144
+ bibpaper_index()[id]
145
+ end
146
+
147
+ def bibpaper_index
148
+ raise FileNotFound, "no such bib file: #{@book.bib_file}" unless @book.bib_exist?
149
+ @bibpaper_index ||= BibpaperIndex.parse(@book.read_bib.lines.to_a)
150
+ @bibpaper_index
151
+ end
152
+
153
+ def headline(caption)
154
+ headline_index()[caption]
155
+ end
156
+
157
+ def headline_index
158
+ @headline_index ||= HeadlineIndex.parse(lines(), self)
159
+ end
160
+ end
161
+ end
162
+ end
163
+