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,339 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (c) 2002-2007 Minero Aoki
4
+ # 2008-2009 Minero Aoki, 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 LGPL, see the file "COPYING".
10
+ #
11
+
12
+ require 'review/extentions'
13
+ require 'review/exception'
14
+
15
+ module ReVIEW
16
+ module Book
17
+ class Index
18
+ def Index.parse(src, *args)
19
+ items = []
20
+ seq = 1
21
+ src.grep(%r<^//#{item_type()}>) do |line|
22
+ if id = line.slice(/\[(.*?)\]/, 1)
23
+ items.push item_class().new(id, seq)
24
+ seq += 1
25
+ if id == ""
26
+ warn "warning: no ID of #{item_type()} in #{line}"
27
+ end
28
+ end
29
+ end
30
+ new(items, *args)
31
+ end
32
+
33
+ Item = Struct.new(:id, :number)
34
+
35
+ def Index.item_class
36
+ self::Item
37
+ end
38
+
39
+ include Enumerable
40
+
41
+ def item_type
42
+ self.class.item_type
43
+ end
44
+
45
+ def initialize(items)
46
+ @items = items
47
+ @index = {}
48
+ items.each do |i|
49
+ warn "warning: duplicate ID: #{i.id} (#{i})" unless @index[i.id].nil?
50
+ @index[i.id] = i
51
+ end
52
+ end
53
+
54
+ def [](id)
55
+ @index.fetch(id)
56
+ rescue
57
+ raise KeyError
58
+ end
59
+
60
+ def number(id)
61
+ @index.fetch(id).number.to_s
62
+ end
63
+
64
+ def each(&block)
65
+ @items.each(&block)
66
+ end
67
+
68
+ def has_key?(id)
69
+ return @index.has_key?(id)
70
+ end
71
+ end
72
+
73
+
74
+ class ChapterIndex < Index
75
+ def item_type
76
+ 'chapter'
77
+ end
78
+
79
+ def number(id)
80
+ chapter = @index.fetch(id)
81
+ if chapter.on_CHAPS?
82
+ "#{I18n.t("chapter", chapter.number)}"
83
+ elsif chapter.on_PREDEF?
84
+ "#{chapter.number}"
85
+ elsif chapter.on_POSTDEF?
86
+ "#{I18n.t("appendix", chapter.number)}"
87
+ end
88
+ end
89
+
90
+ def title(id)
91
+ @index.fetch(id).title
92
+ end
93
+
94
+ def display_string(id)
95
+ "#{number(id)}「#{title(id)}」"
96
+ end
97
+ end
98
+
99
+
100
+ class ListIndex < Index
101
+ def ListIndex.item_type
102
+ '(list|listnum)'
103
+ end
104
+ end
105
+
106
+
107
+ class TableIndex < Index
108
+ def TableIndex.item_type
109
+ 'table'
110
+ end
111
+ end
112
+
113
+
114
+ class FootnoteIndex < Index
115
+ Item = Struct.new(:id, :number, :content)
116
+
117
+ def FootnoteIndex.parse(src)
118
+ items = []
119
+ seq = 1
120
+ src.grep(%r<^//footnote>) do |line|
121
+ if m = /\[(.*?)\]\[(.*)\]/.match(line)
122
+ m1 = m[1].gsub(/\\(\])/){$1}
123
+ m2 = m[2].gsub(/\\(\])/){$1}
124
+ items.push Item.new(m1, seq, m2)
125
+ end
126
+ seq += 1
127
+ end
128
+ new(items)
129
+ end
130
+ end
131
+
132
+
133
+ class ImageIndex < Index
134
+ class Item
135
+ def initialize(id, number)
136
+ @id = id
137
+ @number = number
138
+ @pathes = nil
139
+ end
140
+
141
+ attr_reader :id
142
+ attr_reader :number
143
+ attr_writer :index # internal use only
144
+
145
+ def bound?
146
+ not pathes().empty?
147
+ end
148
+
149
+ def path
150
+ pathes().first
151
+ end
152
+
153
+ def pathes
154
+ @pathes ||= @index.find_pathes(id)
155
+ end
156
+ end
157
+
158
+ def ImageIndex.item_type
159
+ '(image|graph)'
160
+ end
161
+
162
+ def initialize(items, chapid, basedir, types)
163
+ super items
164
+ items.each do |i|
165
+ i.index = self
166
+ end
167
+ @chapid = chapid
168
+ @basedir = basedir
169
+ @types = types
170
+ end
171
+
172
+ # internal use only
173
+ def find_pathes(id)
174
+ if ReVIEW.book.param["subdirmode"]
175
+ re = /\A#{id}(?i:#{@types.join('|')})\z/x
176
+ entries().select {|ent| re =~ ent }\
177
+ .sort_by {|ent| @types.index(File.extname(ent).downcase) }\
178
+ .map {|ent| "#{@basedir}/#{@chapid}/#{ent}" }
179
+ elsif ReVIEW.book.param["singledirmode"]
180
+ re = /\A#{id}(?i:#{@types.join('|')})\z/x
181
+ entries().select {|ent| re =~ ent }\
182
+ .sort_by {|ent| @types.index(File.extname(ent).downcase) }\
183
+ .map {|ent| "#{@basedir}/#{ent}" }
184
+ else
185
+ re = /\A#{@chapid.gsub('+', '\\\+').gsub('-', '\\\-')}-#{id}(?i:#{@types.join('|')})\z/x
186
+ entries().select {|ent| re =~ ent }\
187
+ .sort_by {|ent| @types.index(File.extname(ent).downcase) }\
188
+ .map {|ent| "#{@basedir}/#{ent}" }
189
+ end
190
+ end
191
+
192
+ private
193
+
194
+ def entries
195
+ # @entries: do not cache for graph
196
+ if ReVIEW.book.param["subdirmode"]
197
+ @entries = Dir.entries(File.join(@basedir, @chapid))
198
+ else
199
+ @entries = Dir.entries(@basedir)
200
+ end
201
+ rescue Errno::ENOENT
202
+ @entries = []
203
+ end
204
+ end
205
+
206
+ class IconIndex < ImageIndex
207
+ def IconIndex.parse(src, *args)
208
+ items = []
209
+ seq = 1
210
+ src.grep(%r!@<icon>!) do |line|
211
+ line.gsub(/@<icon>\{(.+?)\}/) do |m|
212
+ items.push item_class().new($1, seq)
213
+ seq += 1
214
+ end
215
+ end
216
+ new(items, *args)
217
+ end
218
+ end
219
+
220
+ class FormatRef
221
+ def initialize(locale, index)
222
+ @locale = locale
223
+ @index = index
224
+ end
225
+
226
+ def title(id)
227
+ sprintf(@locale["#{@index.item_type}_caption_format".intern],
228
+ @index.title(id))
229
+ end
230
+
231
+ def number(id)
232
+ sprintf(@locale["#{@index.item_type}_number_format".intern],
233
+ @index.number(id))
234
+ end
235
+
236
+ def method_missing(mid, *args, &block)
237
+ super unless @index.respond_to?(mid)
238
+ @index.__send__(mid, *args, &block)
239
+ end
240
+ end
241
+
242
+ class BibpaperIndex < Index
243
+ Item = Struct.new(:id, :number, :caption)
244
+
245
+ def BibpaperIndex.parse(src)
246
+ items = []
247
+ seq = 1
248
+ src.grep(%r<^//bibpaper>) do |line|
249
+ if m = /\[(.*?)\]\[(.*)\]/.match(line)
250
+ m1 = m[1].gsub(/\\(.)/){$1}
251
+ m2 = m[2].gsub(/\\(.)/){$1}
252
+ items.push Item.new(m1, seq, m2)
253
+ end
254
+ seq += 1
255
+ end
256
+ new(items)
257
+ end
258
+ end
259
+
260
+ class NumberlessImageIndex < ImageIndex
261
+ class Item < ImageIndex::Item
262
+ def initialize(id, number)
263
+ @id = id
264
+ @number = ""
265
+ @pathes = nil
266
+ end
267
+ end
268
+
269
+ def NumberlessImageIndex.item_type
270
+ 'numberlessimage'
271
+ end
272
+
273
+ def number(id)
274
+ ""
275
+ end
276
+ end
277
+
278
+ class IndepImageIndex < ImageIndex
279
+ class Item < ImageIndex::Item
280
+ def initialize(id, number)
281
+ @id = id
282
+ @number = ""
283
+ @pathes = nil
284
+ end
285
+ end
286
+
287
+ def IndepImageIndex.item_type
288
+ 'indepimage'
289
+ end
290
+
291
+ def number(id)
292
+ ""
293
+ end
294
+ end
295
+
296
+ class HeadlineIndex < Index
297
+ Item = Struct.new(:id, :number, :caption)
298
+
299
+ def HeadlineIndex.parse(src, chap)
300
+ items = []
301
+ indexs = []
302
+ headlines = []
303
+ src.each do |line|
304
+ if m = /\A(=+)(?:\[(.+?)\])?(?:\{(.+?)\})?(.*)/.match(line)
305
+ next if m[2] == 'column'
306
+ index = m[1].size - 2
307
+ if index >= 0
308
+ if indexs.size > (index + 1)
309
+ indexs = indexs.take(index + 1)
310
+ headlines = headlines.take(index + 1)
311
+ end
312
+ if indexs[index].nil?
313
+ (0..index).each{|i| indexs[i] = 0 if indexs[i].nil?}
314
+ end
315
+ indexs[index] += 1
316
+ headlines[index] = m[3].present? ? m[3].strip : m[4].strip
317
+ items.push Item.new(headlines.join("|"), indexs.dup, m[4].strip)
318
+ end
319
+ end
320
+ end
321
+ new(items, chap)
322
+ end
323
+
324
+ def initialize(items, chap)
325
+ @items = items
326
+ @chap = chap
327
+ @index = {}
328
+ items.each do |i|
329
+ warn "warning: duplicate ID: #{i.id}" unless @index[i.id].nil?
330
+ @index[i.id] = i
331
+ end
332
+ end
333
+
334
+ def number(id)
335
+ return ([@chap.number] + @index.fetch(id).number).join(".")
336
+ end
337
+ end
338
+ end
339
+ end
@@ -0,0 +1,38 @@
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 PageMetric
15
+
16
+ MetricData = Struct.new(:n_lines, :n_columns)
17
+
18
+ def PageMetric.a5
19
+ new(46, 80, 30, 74, 1)
20
+ end
21
+
22
+ def PageMetric.b5
23
+ new(46, 80, 30, 74, 2)
24
+ end
25
+
26
+ def initialize(list_lines, list_columns, text_lines, text_columns, page_per_kbyte)
27
+ @list = MetricData.new(list_lines, list_columns)
28
+ @text = MetricData.new(text_lines, text_columns)
29
+ @page_per_kbyte = page_per_kbyte
30
+ end
31
+
32
+ attr_reader :list
33
+ attr_reader :text
34
+ attr_reader :page_per_kbyte
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,97 @@
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 Parameters
15
+
16
+ def Parameters.default
17
+ new()
18
+ end
19
+
20
+ def Parameters.load(path)
21
+ mod = Module.new
22
+ mod.module_eval File.read(path), path
23
+ new(
24
+ :chapter_file => const_get_safe(mod, :CHAPS_FILE),
25
+ :part_file => const_get_safe(mod, :PART_FILE),
26
+ :bib_file => const_get_safe(mod, :BIB_FILE),
27
+ :reject_file => const_get_safe(mod, :REJECT_FILE) ||
28
+ const_get_safe(mod, :WORDS_FILE),
29
+ :predef_file => const_get_safe(mod, :PREDEF_FILE),
30
+ :postdef_file => const_get_safe(mod, :POSTDEF_FILE),
31
+ :ext => const_get_safe(mod, :EXT),
32
+ :image_dir => const_get_safe(mod, :IMAGE_DIR),
33
+ :image_types => const_get_safe(mod, :IMAGE_TYPES),
34
+ :page_metric => get_page_metric(mod)
35
+ )
36
+ end
37
+
38
+ def Parameters.get_page_metric(mod)
39
+ if paper = const_get_safe(mod, :PAPER)
40
+ unless PageMetric.respond_to?(paper.downcase)
41
+ raise ConfigError, "unknown paper size: #{paper}"
42
+ end
43
+ return PageMetric.send(paper.downcase)
44
+ end
45
+ PageMetric.new(const_get_safe(mod, :LINES_PER_PAGE_list) || 46,
46
+ const_get_safe(mod, :COLUMNS_list) || 80,
47
+ const_get_safe(mod, :LINES_PER_PAGE_text) || 30,
48
+ const_get_safe(mod, :COLUMNS_text) || 74) # 37zw
49
+ end
50
+
51
+ def Parameters.const_get_safe(mod, name)
52
+ return nil unless mod.const_defined?(name)
53
+ mod.const_get(name)
54
+ end
55
+ private_class_method :const_get_safe
56
+
57
+ def initialize(params = {})
58
+ @chapter_file = params[:chapter_file] || 'CHAPS'
59
+ @part_file = params[:part_file] || 'PART'
60
+ @reject_file = params[:reject_file] || 'REJECT'
61
+ @predef_file = params[:predef_file] || 'PREDEF'
62
+ @postdef_file = params[:postdef_file] || 'POSTDEF'
63
+ @page_metric = params[:page_metric] || PageMetric.a5
64
+ @ext = params[:ext] || '.re'
65
+ @image_dir = params[:image_dir] || 'images'
66
+ @image_types = unify_exts(params[:image_types] ||
67
+ %w( ai psd eps pdf tif tiff png bmp jpg jpeg gif svg ))
68
+ @bib_file = params[:bib_file] || "bib#{@ext}"
69
+ end
70
+
71
+ def unify_exts(list)
72
+ list.map {|ext| (ext[0] == '.') ? ext : ".#{ext}" }
73
+ end
74
+ private :unify_exts
75
+
76
+ def self.path_param(name)
77
+ module_eval(<<-End, __FILE__, __LINE__ + 1)
78
+ def #{name}
79
+ "\#{@basedir}/\#{@#{name}}"
80
+ end
81
+ End
82
+ end
83
+
84
+ path_param :chapter_file
85
+ path_param :part_file
86
+ path_param :bib_file
87
+ path_param :reject_file
88
+ path_param :predef_file
89
+ path_param :postdef_file
90
+ attr_reader :ext
91
+ path_param :image_dir
92
+ attr_reader :image_types
93
+ attr_reader :page_metric
94
+
95
+ end
96
+ end
97
+ end