review 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/COPYING +515 -0
  2. data/ChangeLog +1278 -0
  3. data/README.rdoc +21 -0
  4. data/Rakefile +42 -0
  5. data/VERSION +1 -0
  6. data/bin/review-check +190 -0
  7. data/bin/review-checkdep +63 -0
  8. data/bin/review-compile +165 -0
  9. data/bin/review-epubmaker +525 -0
  10. data/bin/review-index +108 -0
  11. data/bin/review-preproc +140 -0
  12. data/bin/review-validate +51 -0
  13. data/bin/review-vol +106 -0
  14. data/doc/format.re +486 -0
  15. data/doc/format.txt +434 -0
  16. data/doc/format_idg.txt +194 -0
  17. data/doc/format_sjis.txt +313 -0
  18. data/doc/sample.css +91 -0
  19. data/doc/sample.yaml +46 -0
  20. data/lib/lineinput.rb +155 -0
  21. data/lib/review/book.rb +580 -0
  22. data/lib/review/builder.rb +274 -0
  23. data/lib/review/compat.rb +22 -0
  24. data/lib/review/compiler.rb +483 -0
  25. data/lib/review/epubbuilder.rb +692 -0
  26. data/lib/review/ewbbuilder.rb +382 -0
  27. data/lib/review/exception.rb +21 -0
  28. data/lib/review/htmlbuilder.rb +370 -0
  29. data/lib/review/htmllayout.rb +19 -0
  30. data/lib/review/htmlutils.rb +27 -0
  31. data/lib/review/idgxmlbuilder.rb +1078 -0
  32. data/lib/review/index.rb +224 -0
  33. data/lib/review/latexbuilder.rb +420 -0
  34. data/lib/review/latexindex.rb +35 -0
  35. data/lib/review/latexutils.rb +52 -0
  36. data/lib/review/preprocessor.rb +520 -0
  37. data/lib/review/textutils.rb +19 -0
  38. data/lib/review/tocparser.rb +333 -0
  39. data/lib/review/tocprinter.rb +220 -0
  40. data/lib/review/topbuilder.rb +572 -0
  41. data/lib/review/unfold.rb +138 -0
  42. data/lib/review/volume.rb +66 -0
  43. data/lib/review.rb +4 -0
  44. data/review.gemspec +93 -0
  45. data/setup.rb +1587 -0
  46. data/test/test_epubbuilder.rb +73 -0
  47. data/test/test_helper.rb +2 -0
  48. data/test/test_htmlbuilder.rb +42 -0
  49. data/test/test_latexbuilder.rb +74 -0
  50. metadata +122 -0
@@ -0,0 +1,224 @@
1
+ # $Id: index.rb 4300 2009-06-21 23:45:49Z kmuto $
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/compat'
13
+ require 'review/exception'
14
+
15
+ module ReVIEW
16
+
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
+ end
26
+ end
27
+ new(items, *args)
28
+ end
29
+
30
+ Item = Struct.new(:id, :number)
31
+
32
+ def Index.item_class
33
+ self::Item
34
+ end
35
+
36
+ include Enumerable
37
+
38
+ def item_type
39
+ self.class.item_type
40
+ end
41
+
42
+ def initialize(items)
43
+ @items = items
44
+ @index = {}
45
+ items.each do |i|
46
+ warn "warning: duplicate ID: #{i.id}" unless @index[i.id].nil?
47
+ @index[i.id] = i
48
+ end
49
+ end
50
+
51
+ def setParameter(param)
52
+ @param = param
53
+ end
54
+
55
+ def [](id)
56
+ @index.fetch(id)
57
+ end
58
+
59
+ def number(id)
60
+ @index.fetch(id).number.to_s
61
+ end
62
+
63
+ def each(&block)
64
+ @items.each(&block)
65
+ end
66
+ end
67
+
68
+
69
+ class ChapterIndex < Index
70
+ def item_type
71
+ 'chapter'
72
+ end
73
+
74
+ def number(id)
75
+ "第#{@index.fetch(id).number}章"
76
+ end
77
+
78
+ def title(id)
79
+ @index.fetch(id).title
80
+ end
81
+
82
+ def display_string(id)
83
+ "#{number(id)}「#{title(id)}」"
84
+ end
85
+ end
86
+
87
+
88
+ class ListIndex < Index
89
+ def ListIndex.item_type
90
+ '(list|listnum)'
91
+ end
92
+ end
93
+
94
+
95
+ class TableIndex < Index
96
+ def TableIndex.item_type
97
+ 'table'
98
+ end
99
+ end
100
+
101
+
102
+ class FootnoteIndex < Index
103
+ Item = Struct.new(:id, :number, :content)
104
+
105
+ def FootnoteIndex.parse(src)
106
+ items = []
107
+ seq = 1
108
+ src.grep(%r<^//footnote>) do |line|
109
+ if m = /\[(.*?)\]\[(.*)\]/.match(line)
110
+ items.push Item.new(m[1], seq, m[2])
111
+ end
112
+ seq += 1
113
+ end
114
+ new(items)
115
+ end
116
+ end
117
+
118
+
119
+ class ImageIndex < Index
120
+ class Item
121
+ def initialize(id, number)
122
+ @id = id
123
+ @number = number
124
+ @pathes = nil
125
+ end
126
+
127
+ attr_reader :id
128
+ attr_reader :number
129
+ attr_writer :index # internal use only
130
+
131
+ def bound?
132
+ not pathes().empty?
133
+ end
134
+
135
+ def path
136
+ pathes().first
137
+ end
138
+
139
+ def pathes
140
+ @pathes ||= @index.find_pathes(id)
141
+ end
142
+ end
143
+
144
+ def ImageIndex.item_type
145
+ 'image'
146
+ end
147
+
148
+ def initialize(items, chapid, basedir, types)
149
+ super items
150
+ items.each do |i|
151
+ i.index = self
152
+ end
153
+ @chapid = chapid
154
+ @basedir = basedir
155
+ @types = types
156
+ end
157
+
158
+ # internal use only
159
+ def find_pathes(id)
160
+ if @param["subdirmode"].nil?
161
+ re = /\A#{@chapid}-#{id}(?i:#{@types.join('|')})\z/x
162
+ entries().select {|ent| re =~ ent }\
163
+ .sort_by {|ent| @types.index(File.extname(ent).downcase) }\
164
+ .map {|ent| "#{@basedir}/#{ent}" }
165
+ else
166
+ re = /\A#{id}(?i:#{@types.join('|')})\z/x
167
+ entries().select {|ent| re =~ ent }\
168
+ .sort_by {|ent| @types.index(File.extname(ent).downcase) }\
169
+ .map {|ent| "#{@basedir}/#{@chapid}/#{ent}" }
170
+ end
171
+ end
172
+
173
+ private
174
+
175
+ def entries
176
+ if @param["subdirmode"].nil?
177
+ @entries ||= Dir.entries(@basedir)
178
+ else
179
+ @entries ||= Dir.entries(File.join(@basedir, @chapid))
180
+ end
181
+ rescue Errno::ENOENT
182
+ @entries = []
183
+ end
184
+ end
185
+
186
+
187
+ class FormatRef
188
+ def initialize(locale, index)
189
+ @locale = locale
190
+ @index = index
191
+ end
192
+
193
+ def title(id)
194
+ sprintf(@locale["#{@index.item_type}_caption_format".intern],
195
+ @index.title(id))
196
+ end
197
+
198
+ def number(id)
199
+ sprintf(@locale["#{@index.item_type}_number_format".intern],
200
+ @index.number(id))
201
+ end
202
+
203
+ def method_missing(mid, *args, &block)
204
+ super unless @index.respond_to?(mid)
205
+ @index.__send__(mid, *args, &block)
206
+ end
207
+ end
208
+
209
+ class BibpaperIndex < Index
210
+ Item = Struct.new(:id, :number, :caption)
211
+
212
+ def BibpaperIndex.parse(src)
213
+ items = []
214
+ seq = 1
215
+ src.grep(%r<^//bibpaper>) do |line|
216
+ if m = /\[(.*?)\]\[(.*)\]/.match(line)
217
+ items.push Item.new(m[1], seq, m[2])
218
+ end
219
+ seq += 1
220
+ end
221
+ new(items)
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,420 @@
1
+ #
2
+ #
3
+ # Copyright (c) 2002-2007 Minero Aoki
4
+ # 2008-2009 Minero Aoki, Kenshi Muto
5
+ # 2010 Minero Aoki, Kenshi Muto, TAKAHASHI Masayoshi
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
+
13
+ require 'review/builder'
14
+ require 'review/latexutils'
15
+ require 'review/textutils'
16
+
17
+ module ReVIEW
18
+
19
+ class LATEXBuilder < Builder
20
+
21
+ include LaTeXUtils
22
+ include TextUtils
23
+
24
+ def extname
25
+ '.tex'
26
+ end
27
+
28
+ def builder_init_file
29
+ #@index = indexes[:latex_index]
30
+ @blank_needed = false
31
+ end
32
+ private :builder_init_file
33
+
34
+ def blank
35
+ @blank_needed = true
36
+ end
37
+ private :blank
38
+
39
+ def print(*s)
40
+ if @blank_needed
41
+ @output.puts
42
+ @blank_needed = false
43
+ end
44
+ super
45
+ end
46
+ private :print
47
+
48
+ def puts(*s)
49
+ if @blank_needed
50
+ @output.puts
51
+ @blank_needed = false
52
+ end
53
+ super
54
+ end
55
+ private :puts
56
+
57
+ HEADLINE = {
58
+ 1 => 'chapter',
59
+ 2 => 'section',
60
+ 3 => 'subsection',
61
+ 4 => 'subsubsection'
62
+ }
63
+
64
+ def headline(level, label, caption)
65
+ prefix = ""
66
+ if level > @param["secnolevel"]
67
+ prefix = "*"
68
+ end
69
+ blank unless @output.pos == 0
70
+ puts macro(HEADLINE[level]+prefix, escape(caption))
71
+ end
72
+
73
+ def column_begin(level, label, caption)
74
+ blank
75
+ ## puts '\vspace{2zw}'
76
+ puts '\begin{center}'
77
+ puts '\begin{minipage}{0.9\linewidth}'
78
+ puts '\begin{framed}'
79
+ puts '\setlength{\FrameSep}{2zw}'
80
+
81
+ headline(2, label, caption) # FIXME
82
+ end
83
+
84
+ def column_end(level)
85
+ puts '\end{framed}'
86
+ puts '\end{minipage}'
87
+ puts '\end{center}'
88
+ ## puts '\vspace{2zw}'
89
+ blank
90
+ end
91
+
92
+ def ul_begin
93
+ blank
94
+ puts '\begin{itemize}'
95
+ end
96
+
97
+ def ul_item(lines)
98
+ puts '\item ' + lines.join("\n")
99
+ end
100
+
101
+ def ul_end
102
+ puts '\end{itemize}'
103
+ blank
104
+ end
105
+
106
+ def ol_begin
107
+ blank
108
+ puts '\begin{enumerate}'
109
+ end
110
+
111
+ def ol_item(lines, num)
112
+ puts '\item ' + lines.join("\n")
113
+ end
114
+
115
+ def ol_end
116
+ puts '\end{enumerate}'
117
+ blank
118
+ end
119
+
120
+ def dl_begin
121
+ blank
122
+ puts '\begin{description}'
123
+ end
124
+
125
+ def dt(str)
126
+ puts '\item[' + str + '] \mbox{} \\\\'
127
+ end
128
+
129
+ def dd(lines)
130
+ lines.each do |line|
131
+ puts line
132
+ end
133
+ end
134
+
135
+ def dl_end
136
+ puts '\end{description}'
137
+ blank
138
+ end
139
+
140
+ def paragraph(lines)
141
+ blank
142
+ lines.each do |line|
143
+ puts line
144
+ end
145
+ blank
146
+ end
147
+
148
+ def parasep()
149
+ puts '\\parasep'
150
+ end
151
+
152
+ def read(lines)
153
+ latex_block 'quotation', lines
154
+ end
155
+
156
+ alias lead read
157
+
158
+ def emlist(lines)
159
+ blank
160
+ puts '\begin{reviewemlist}'
161
+ puts '\begin{verbatim}'
162
+ lines.each do |line|
163
+ puts line
164
+ end
165
+ puts '\end{verbatim}'
166
+ puts '\end{reviewemlist}'
167
+ blank
168
+ end
169
+
170
+ def cmd(lines)
171
+ blank
172
+ puts '\begin{reviewcmd}'
173
+ puts '\begin{verbatim}'
174
+ lines.each do |line|
175
+ puts line
176
+ end
177
+ puts '\end{verbatim}'
178
+ puts '\end{reviewcmd}'
179
+ blank
180
+ end
181
+
182
+ def list_header(id, caption)
183
+ puts macro('reviewlistcaption', "#{@chapter.number}.#{@chapter.list(id).number}", text(caption))
184
+ end
185
+
186
+ def list_body(lines)
187
+ puts '\begin{reviewlist}'
188
+ puts '\begin{verbatim}'
189
+ lines.each do |line|
190
+ puts line
191
+ end
192
+ puts '\end{verbatim}'
193
+ puts '\end{reviewlist}'
194
+ puts
195
+ end
196
+
197
+ def image_header(id, caption)
198
+ end
199
+
200
+ def image_image(id, metric, caption)
201
+ # image is always bound here
202
+ puts '\begin{reviewimage}'
203
+ if metric
204
+ puts "\\includegraphics[#{metric}]{#{@chapter.image(id).path}}"
205
+ else
206
+ puts macro('includegraphics', @chapter.image(id).path)
207
+ end
208
+ puts macro('label', image_label(id))
209
+ if !caption.empty?
210
+ puts macro('caption', text(caption))
211
+ end
212
+ puts '\end{reviewimage}'
213
+ end
214
+
215
+ def image_dummy(id, caption, lines)
216
+ puts '\begin{reviewdummyimage}'
217
+ puts '\begin{verbatim}'
218
+ path = @chapter.image(id).path
219
+ puts "--[[path = #{path} (#{existence(id)})]]--"
220
+ lines.each do |line|
221
+ puts detab(line.rstrip)
222
+ end
223
+ puts '\end{verbatim}'
224
+ puts macro('label', image_label(id))
225
+ puts text(caption)
226
+ puts '\end{reviewdummyimage}'
227
+ end
228
+
229
+ def existence(id)
230
+ @chapter.image(id).bound? ? 'exist' : 'not exist'
231
+ end
232
+ private :existence
233
+
234
+ def image_label(id)
235
+ "image:#{@chapter.id}:#{id}"
236
+ end
237
+ private :image_label
238
+
239
+ def table_header(id, caption)
240
+ puts macro('reviewtablecaption', "#{@chapter.number}.#{@chapter.table(id).number}", text(caption))
241
+ end
242
+
243
+ def table_begin(ncols)
244
+ puts macro('begin', 'reviewtable', (['|'] * (ncols + 1)).join('l'))
245
+ puts '\hline'
246
+ end
247
+
248
+ def table_separator
249
+ #puts '\hline'
250
+ end
251
+
252
+ def th(s)
253
+ macro('textgt', s)
254
+ end
255
+
256
+ def td(s)
257
+ s
258
+ end
259
+
260
+ def tr(rows)
261
+ print rows.join(' & ')
262
+ puts ' \\\\ \hline'
263
+ end
264
+
265
+ def table_end
266
+ puts macro('end', 'reviewtable')
267
+ blank
268
+ end
269
+
270
+ def quote(lines)
271
+ latex_block 'quotation', lines
272
+ end
273
+
274
+ def center(lines)
275
+ latex_block 'center', lines
276
+ end
277
+
278
+ def right(lines)
279
+ latex_block 'flushright', lines
280
+ end
281
+
282
+ def latex_block(type, lines)
283
+ blank
284
+ puts macro('begin', type)
285
+ lines.each do |line|
286
+ puts line
287
+ end
288
+ puts macro('end', type)
289
+ blank
290
+ end
291
+ private :latex_block
292
+
293
+ def direct(lines, fmt)
294
+ return unless fmt == 'latex'
295
+ lines.each do |line|
296
+ puts line
297
+ end
298
+ end
299
+
300
+ def comment(str)
301
+ puts "% #{str}"
302
+ end
303
+
304
+ def label(id)
305
+ puts macro('label', id)
306
+ end
307
+
308
+ def pagebreak
309
+ puts '\pagebreak'
310
+ end
311
+
312
+ def linebreak
313
+ puts '\\\\'
314
+ end
315
+
316
+ def noindent
317
+ puts '\noindent'
318
+ end
319
+
320
+ # FIXME: use TeX native label/ref.
321
+ def inline_list(id)
322
+ macro('reviewlistref', "#{@chapter.number}.#{@chapter.list(id).number}")
323
+ end
324
+
325
+ def inline_table(id)
326
+ macro('reviewtableref', "#{@chapter.number}.#{@chapter.table(id).number}")
327
+ end
328
+
329
+ def inline_img(id)
330
+ macro('reviewimageref', "#{@chapter.number}.#{@chapter.image(id).number}")
331
+ end
332
+
333
+ def footnote(id, content)
334
+ end
335
+
336
+ def inline_fn(id)
337
+ macro('footnote', compile_inline(@chapter.footnote(id).content.strip))
338
+ end
339
+
340
+ BOUTEN = "・"
341
+
342
+ def inline_bou(str)
343
+ str.split(//).map {|c| macro('ruby', escape(c), macro('textgt', BOUTEN)) }.join('\allowbreak')
344
+ end
345
+
346
+ def inline_ruby(str)
347
+ base, ruby = *str.split(/,/)
348
+ macro('ruby', base, ruby)
349
+ end
350
+
351
+ # math
352
+ def inline_m(str)
353
+ " $#{str}$ "
354
+ end
355
+
356
+ # hidden index
357
+ def inline_hi(str)
358
+ index(str)
359
+ end
360
+
361
+ # index
362
+ def inline_i(str)
363
+ text(str) + index(str)
364
+ end
365
+
366
+ # bold
367
+ def inline_b(str)
368
+ macro('textbf', text(str))
369
+ end
370
+
371
+ def nofunc_text(str)
372
+ escape(str)
373
+ end
374
+
375
+ def inline_tt(str)
376
+ macro('texttt', escape(str))
377
+ end
378
+
379
+ def index(str)
380
+ str.sub!(/\(\)/, '')
381
+ decl = ''
382
+ if /@\z/ =~ str
383
+ str.chop!
384
+ decl = '|IndexDecl'
385
+ end
386
+ unless /[^ -~]/ =~ str
387
+ if /\^/ =~ str
388
+ macro('index', escape_index(str.gsub(/\^/, '')) + '@' + escape_index(text(str)) + decl)
389
+ else
390
+ '\index{' + escape_index(text(str)) + decl + '}'
391
+ end
392
+ else
393
+ '\index{' + escape_index(@index_db[str]) + '@' + escape_index(text(str)) + '}'
394
+ end
395
+ end
396
+
397
+ def compile_kw(word, alt)
398
+ if alt
399
+ macro('textgt', escape(word)) + "(#{escape(alt.strip)})"
400
+ else
401
+ macro('textgt', escape(word))
402
+ end
403
+ end
404
+
405
+ def compile_href(url, label)
406
+ label ||= url
407
+ if /\A[a-z]+:\/\// =~ url
408
+ macro("href", url, escape(label))
409
+ else
410
+ macro("ref", url)
411
+ end
412
+ end
413
+
414
+ def tsize(str)
415
+ # dummy
416
+ end
417
+
418
+ end
419
+
420
+ end