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,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( eps ai tif tiff png bmp jpg jpeg gif svg pdf ))
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
@@ -0,0 +1,44 @@
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 Part
16
+ include Compilable
17
+
18
+ def initialize(book, number, chapters, name="")
19
+ @book = book
20
+ @number = number
21
+ @chapters = chapters
22
+ @path = name
23
+ @name = name ? File.basename(name, '.*') : nil
24
+ end
25
+
26
+ attr_reader :number
27
+ attr_reader :chapters
28
+ attr_reader :name
29
+
30
+ def each_chapter(&block)
31
+ @chapters.each(&block)
32
+ end
33
+
34
+ def volume
35
+ Volume.sum(@chapters.map {|chap| chap.volume })
36
+ end
37
+
38
+ def file?
39
+ (name.present? and path =~ /\.re\z/) ? true : false
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,65 @@
1
+ #
2
+ # $Id: volume.rb 3883 2008-02-10 11:48:23Z aamine $
3
+ #
4
+ # Copyright (c) 2002-2007 Minero Aoki
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
+ module ReVIEW
12
+ module Book
13
+ class Volume
14
+
15
+ def Volume.count_file(path)
16
+ b = c = l = 0
17
+ File.foreach(path) do |line|
18
+ next if %r<\A\#@> =~ line
19
+ text = line.gsub(/\s+/, '')
20
+ b += text.bytesize
21
+ c += text.charsize
22
+ l += 1
23
+ end
24
+ new(b, c, l)
25
+ end
26
+
27
+ def Volume.sum(vols)
28
+ vols.inject(new()) {|sum, i| sum + i }
29
+ end
30
+
31
+ def Volume.dummy
32
+ new(-1, -1, -1)
33
+ end
34
+
35
+ def initialize(bytes = 0, chars = 0, lines = 0)
36
+ @bytes = bytes
37
+ @chars = chars
38
+ @lines = lines
39
+ end
40
+
41
+ attr_reader :bytes
42
+ attr_reader :chars
43
+ attr_accessor :lines
44
+
45
+ def kbytes
46
+ (@bytes.to_f / 1024).ceil
47
+ end
48
+
49
+ def page
50
+ (kbytes.to_f/ReVIEW.book.page_metric.page_per_kbyte).ceil
51
+ end
52
+
53
+ def to_s
54
+ "#{kbytes()}KB #{@chars}C #{@lines}L #{page()}P"
55
+ end
56
+
57
+ def +(other)
58
+ Volume.new(@bytes + other.bytes,
59
+ @chars + other.chars,
60
+ @lines + other.lines)
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,444 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (c) 2002-2009 Minero Aoki
4
+ #
5
+ # This program is free software.
6
+ # You can distribute or modify this program under the terms of
7
+ # the GNU LGPL, Lesser General Public License version 2.1.
8
+ #
9
+
10
+ require 'review/book/index'
11
+ require 'review/exception'
12
+ require 'review/textutils'
13
+ require 'stringio'
14
+ require 'cgi'
15
+
16
+ module ReVIEW
17
+
18
+ class Builder
19
+ include TextUtils
20
+
21
+ CAPTION_TITLES = %w(note memo tip info planning best important security caution term link notice point shoot reference practice expert)
22
+
23
+ def pre_paragraph
24
+ nil
25
+ end
26
+ def post_paragraph
27
+ nil
28
+ end
29
+
30
+ def initialize(strict = false, *args)
31
+ @strict = strict
32
+ @tabwidth = nil
33
+ if ReVIEW.book.param && ReVIEW.book.param["tabwidth"]
34
+ @tabwidth = ReVIEW.book.param["tabwidth"]
35
+ end
36
+ builder_init(*args)
37
+ end
38
+
39
+ def builder_init(*args)
40
+ end
41
+ private :builder_init
42
+
43
+ def bind(compiler, chapter, location)
44
+ @compiler = compiler
45
+ @chapter = chapter
46
+ @location = location
47
+ @output = StringIO.new
48
+ @book = ReVIEW.book
49
+ builder_init_file
50
+ end
51
+
52
+ def builder_init_file
53
+ end
54
+ private :builder_init_file
55
+
56
+ def result
57
+ @output.string
58
+ end
59
+
60
+ alias :raw_result result
61
+
62
+ def print(*s)
63
+ @output.print *s.map{|i|
64
+ convert_outencoding(i, ReVIEW.book.param["outencoding"])
65
+ }
66
+ end
67
+
68
+ def puts(*s)
69
+ @output.puts *s.map{|i|
70
+ convert_outencoding(i, ReVIEW.book.param["outencoding"])
71
+ }
72
+ end
73
+
74
+ def list(lines, id, caption)
75
+ begin
76
+ list_header id, caption
77
+ rescue KeyError
78
+ error "no such list: #{id}"
79
+ end
80
+ list_body lines
81
+ end
82
+
83
+ def listnum(lines, id, caption)
84
+ begin
85
+ list_header id, caption
86
+ rescue KeyError
87
+ error "no such list: #{id}"
88
+ end
89
+ listnum_body lines
90
+ end
91
+
92
+ def source(lines, caption)
93
+ source_header caption
94
+ source_body lines
95
+ end
96
+
97
+ def image(lines, id, caption, metric = nil)
98
+ if @chapter.image(id).bound?
99
+ image_image id, caption, metric
100
+ else
101
+ warn "image not bound: #{id}" if @strict
102
+ image_dummy id, caption, lines
103
+ end
104
+ end
105
+
106
+ def table(lines, id = nil, caption = nil)
107
+ rows = []
108
+ sepidx = nil
109
+ lines.each_with_index do |line, idx|
110
+ if /\A[\=\-]{12}/ =~ line
111
+ # just ignore
112
+ #error "too many table separator" if sepidx
113
+ sepidx ||= idx
114
+ next
115
+ end
116
+ rows.push line.strip.split(/\t+/).map {|s| s.sub(/\A\./, '') }
117
+ end
118
+ rows = adjust_n_cols(rows)
119
+
120
+ begin
121
+ table_header id, caption unless caption.nil?
122
+ rescue KeyError => err
123
+ error "no such table: #{id}"
124
+ end
125
+ return if rows.empty?
126
+ table_begin rows.first.size
127
+ if sepidx
128
+ sepidx.times do
129
+ tr rows.shift.map {|s| th(s) }
130
+ end
131
+ rows.each do |cols|
132
+ tr cols.map {|s| td(s) }
133
+ end
134
+ else
135
+ rows.each do |cols|
136
+ h, *cs = *cols
137
+ tr [th(h)] + cs.map {|s| td(s) }
138
+ end
139
+ end
140
+ table_end
141
+ end
142
+
143
+ def adjust_n_cols(rows)
144
+ rows.each do |cols|
145
+ while cols.last and cols.last.strip.empty?
146
+ cols.pop
147
+ end
148
+ end
149
+ n_maxcols = rows.map {|cols| cols.size }.max
150
+ rows.each do |cols|
151
+ cols.concat [''] * (n_maxcols - cols.size)
152
+ end
153
+ rows
154
+ end
155
+ private :adjust_n_cols
156
+
157
+ #def footnote(id, str)
158
+ # @footnotes.push [id, str]
159
+ #end
160
+ #
161
+ #def flush_footnote
162
+ # footnote_begin
163
+ # @footnotes.each do |id, str|
164
+ # footnote_item(id, str)
165
+ # end
166
+ # footnote_end
167
+ #end
168
+
169
+ def compile_inline(s)
170
+ @compiler.text(s)
171
+ end
172
+
173
+ def inline_chapref(id)
174
+ @chapter.env.chapter_index.display_string(id)
175
+ rescue KeyError
176
+ error "unknown chapter: #{id}"
177
+ nofunc_text("[UnknownChapter:#{id}]")
178
+ end
179
+
180
+ def inline_chap(id)
181
+ @chapter.env.chapter_index.number(id)
182
+ rescue KeyError
183
+ error "unknown chapter: #{id}"
184
+ nofunc_text("[UnknownChapter:#{id}]")
185
+ end
186
+
187
+ def inline_title(id)
188
+ @chapter.env.chapter_index.title(id)
189
+ rescue KeyError
190
+ error "unknown chapter: #{id}"
191
+ nofunc_text("[UnknownChapter:#{id}]")
192
+ end
193
+
194
+ def inline_list(id)
195
+ "#{I18n.t("list")}#{@chapter.list(id).number}"
196
+ rescue KeyError
197
+ error "unknown list: #{id}"
198
+ nofunc_text("[UnknownList:#{id}]")
199
+ end
200
+
201
+ def inline_img(id)
202
+ "#{I18n.t("image")}#{@chapter.image(id).number}"
203
+ rescue KeyError
204
+ error "unknown image: #{id}"
205
+ nofunc_text("[UnknownImage:#{id}]")
206
+ end
207
+
208
+ def inline_table(id)
209
+ "#{I18n.t("table")}#{@chapter.table(id).number}"
210
+ rescue KeyError
211
+ error "unknown table: #{id}"
212
+ nofunc_text("[UnknownTable:#{id}]")
213
+ end
214
+
215
+ def inline_fn(id)
216
+ @chapter.footnote(id).content
217
+ rescue KeyError
218
+ error "unknown footnote: #{id}"
219
+ nofunc_text("[UnknownFootnote:#{id}]")
220
+ end
221
+
222
+ def inline_bou(str)
223
+ text(str)
224
+ end
225
+
226
+ def inline_ruby(arg)
227
+ base, ruby = *arg.split(',', 2)
228
+ compile_ruby(base, ruby)
229
+ end
230
+
231
+ def inline_kw(arg)
232
+ word, alt = *arg.split(',', 2)
233
+ compile_kw(word, alt)
234
+ end
235
+
236
+ def inline_href(arg)
237
+ url, label = *arg.scan(/(?:(?:(?:\\\\)*\\,)|[^,\\]+)+/).map(&:lstrip)
238
+ url = url.gsub(/\\,/, ",").strip
239
+ label = label.gsub(/\\,/, ",").strip if label
240
+ compile_href(url, label)
241
+ end
242
+
243
+ def text(str)
244
+ str
245
+ end
246
+
247
+ def bibpaper(lines, id, caption)
248
+ bibpaper_header id, caption
249
+ unless lines.empty?
250
+ puts ""
251
+ bibpaper_bibpaper id, caption, lines
252
+ end
253
+ puts ""
254
+ end
255
+
256
+ def inline_hd(id)
257
+ m = /\A(\w+)\|(.+)/.match(id)
258
+ chapter = @book.chapters.detect{|chap| chap.id == m[1]} if m && m[1]
259
+ return inline_hd_chap(chapter, m[2]) if chapter
260
+ return inline_hd_chap(@chapter, id)
261
+ end
262
+
263
+ def raw(str)
264
+ if matched = str.match(/\|(.*?)\|(.*)/)
265
+ builders = matched[1].split(/,/).map{|i| i.gsub(/\s/, '') }
266
+ c = self.class.to_s.gsub(/ReVIEW::/, '').gsub(/Builder/, '').downcase
267
+ if builders.include?(c)
268
+ print matched[2].gsub("\\n", "\n")
269
+ else
270
+ ""
271
+ end
272
+ else
273
+ print str.gsub("\\n", "\n")
274
+ end
275
+ end
276
+
277
+ def find_pathes(id)
278
+ if ReVIEW.book.param["subdirmode"]
279
+ re = /\A#{id}(?i:#{@chapter.name.join('|')})\z/x
280
+ entries().select {|ent| re =~ ent }\
281
+ .sort_by {|ent| @book.image_types.index(File.extname(ent).downcase) }\
282
+ .map {|ent| "#{@book.basedir}/#{@chapter.name}/#{ent}" }
283
+ elsif ReVIEW.book.param["singledirmode"]
284
+ re = /\A#{id}(?i:#{@chapter.name.join('|')})\z/x
285
+ entries().select {|ent| re =~ ent }\
286
+ .sort_by {|ent| @book.image_types.index(File.extname(ent).downcase) }\
287
+ .map {|ent| "#{@book.basedir}/#{ent}" }
288
+ else
289
+ re = /\A#{@chapter.name}-#{id}(?i:#{@book.image_types.join('|')})\z/x
290
+ entries().select {|ent| re =~ ent }\
291
+ .sort_by {|ent| @book.image_types.index(File.extname(ent).downcase) }\
292
+ .map {|ent| "#{@book.basedir}/#{ent}" }
293
+ end
294
+ end
295
+
296
+ def entries
297
+ if ReVIEW.book.param["subdirmode"]
298
+ @entries ||= Dir.entries(File.join(@book.basedir + @book.image_dir, @chapter.name))
299
+ else
300
+ @entries ||= Dir.entries(@book.basedir + @book.image_dir)
301
+ end
302
+ rescue Errno::ENOENT
303
+ @entries = []
304
+ end
305
+
306
+ def warn(msg)
307
+ $stderr.puts "#{@location}: warning: #{msg}"
308
+ end
309
+
310
+ def error(msg)
311
+ raise ApplicationError, "#{@location}: error: #{msg}"
312
+ end
313
+
314
+ def handle_metric(str)
315
+ str
316
+ end
317
+
318
+ def result_metric(array)
319
+ array.join(',')
320
+ end
321
+
322
+ def parse_metric(type, metric)
323
+ return "" if metric.blank?
324
+ params = metric.split(/,\s*/)
325
+ results = []
326
+ params.each do |p|
327
+ if p =~ /\A.+?::/
328
+ if p =~ /\A#{type}::/
329
+ p.sub!(/\A#{type}::/, '')
330
+ else
331
+ next
332
+ end
333
+ end
334
+ p = handle_metric(p)
335
+ results.push(p)
336
+ end
337
+ return result_metric(results)
338
+ end
339
+
340
+ def get_chap(chapter = @chapter)
341
+ if ReVIEW.book.param["secnolevel"] > 0 && !chapter.number.nil? && !chapter.number.to_s.empty?
342
+ return "#{chapter.number}"
343
+ end
344
+ return nil
345
+ end
346
+
347
+ def extract_chapter_id(chap_ref)
348
+ m = /\A([\w+-]+)\|(.+)/.match(chap_ref)
349
+ if m
350
+ return [@book.chapters.detect{|chap| chap.id == m[1]}, m[2]]
351
+ else
352
+ return [@chapter, chap_ref]
353
+ end
354
+ end
355
+
356
+ def captionblock(type, lines, caption, specialstyle = nil)
357
+ raise NotImplementedError
358
+ end
359
+
360
+ CAPTION_TITLES.each do |name|
361
+ class_eval %Q{
362
+ def #{name}(lines, caption = nil)
363
+ captionblock("#{name}", lines, caption)
364
+ end
365
+ }
366
+ end
367
+
368
+ def graph(lines, id, command, caption = nil)
369
+ dir = @book.basedir + @book.image_dir
370
+ file = "#{@chapter.name}-#{id}.#{image_ext}"
371
+ if ReVIEW.book.param["subdirmode"]
372
+ dir = File.join(dir, @chapter.name)
373
+ file = "#{id}.#{image_ext}"
374
+ elsif ReVIEW.book.param["singledirmode"]
375
+ file = "#{id}.#{image_ext}"
376
+ end
377
+ file_path = File.join(dir, file)
378
+
379
+ line = CGI.unescapeHTML(lines.join("\n"))
380
+ cmds = {
381
+ :graphviz => "echo '#{line}' | dot -T#{image_ext} -o#{file_path}",
382
+ :gnuplot => "echo 'set terminal " +
383
+ "#{(image_ext == "eps") ? "postscript eps" : image_ext}\n" +
384
+ " set output \"#{file_path}\"\n#{line}' | gnuplot",
385
+ :blockdiag => "echo '#{line}' "+
386
+ "| blockdiag -a -T #{image_ext} -o #{file_path} /dev/stdin",
387
+ :aafigure => "echo '#{line}' | aafigure -t#{image_ext} -o#{file_path}",
388
+ }
389
+ cmd = cmds[command.to_sym]
390
+ warn cmd
391
+ system cmd
392
+
393
+ image(lines, id, caption)
394
+ end
395
+
396
+ def image_ext
397
+ raise NotImplementedError
398
+ end
399
+
400
+ def inline_include(file_name)
401
+ compile_inline convert_inencoding(File.open(file_name).read,
402
+ ReVIEW.book.param["inencoding"])
403
+ end
404
+
405
+ def include(file_name)
406
+ File.foreach(file_name) do |line|
407
+ paragraph([convert_inencoding(line, ReVIEW.book.param["inencoding"])])
408
+ end
409
+ end
410
+
411
+ def ul_item_begin(lines)
412
+ ul_item(lines)
413
+ end
414
+
415
+ def ul_item_end
416
+ end
417
+
418
+ def inline_raw(args)
419
+ if matched = args.match(/\|(.*?)\|(.*)/)
420
+ builders = matched[1].split(/,/).map{|i| i.gsub(/\s/, '') }
421
+ c = self.class.to_s.gsub(/ReVIEW::/, '').gsub(/Builder/, '').downcase
422
+ if builders.include?(c)
423
+ matched[2].gsub("\\n", "\n")
424
+ else
425
+ ""
426
+ end
427
+ else
428
+ args.gsub("\\n", "\n")
429
+ end
430
+ end
431
+
432
+ ## override TextUtils::detab
433
+ def detab(str, num = nil)
434
+ if num
435
+ super(str, num)
436
+ elsif @tabwidth
437
+ super(str, @tabwidth)
438
+ else
439
+ super(str)
440
+ end
441
+ end
442
+ end
443
+
444
+ end # module ReVIEW