Class: ReVIEW::Builder

Inherits:
Object show all
Includes:
TextUtils
Defined in:
lib/review/builder.rb

Constant Summary collapse

CAPTION_TITLES =
%w(note memo tip info planning best important security caution term link notice point shoot reference practice expert)

Instance Method Summary collapse

Methods included from TextUtils

#convert_inencoding, #convert_outencoding, #split_paragraph

Constructor Details

#initialize(strict = false, *args) ⇒ Builder



31
32
33
34
# File 'lib/review/builder.rb', line 31

def initialize(strict = false, *args)
  @strict = strict
  builder_init(*args)
end

Instance Method Details

#bibpaper(lines, id, caption) ⇒ Object



254
255
256
257
258
259
260
261
# File 'lib/review/builder.rb', line 254

def bibpaper(lines, id, caption)
  bibpaper_header id, caption
  unless lines.empty?
    puts ""
    bibpaper_bibpaper id, caption, lines
  end
  puts ""
end

#bind(compiler, chapter, location) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/review/builder.rb', line 40

def bind(compiler, chapter, location)
  @compiler = compiler
  @chapter = chapter
  @location = location
  @output = StringIO.new
  @book = @chapter.book if @chapter.present?
  @tabwidth = nil
  if @book && @book.config && @book.config["tabwidth"]
    @tabwidth = @book.config["tabwidth"]
  end
  builder_init_file
end

#captionblock(type, lines, caption, specialstyle = nil) ⇒ Object

Raises:

  • (NotImplementedError)


341
342
343
# File 'lib/review/builder.rb', line 341

def captionblock(type, lines, caption, specialstyle = nil)
  raise NotImplementedError
end

#compile_inline(s) ⇒ Object

def footnote(id, str)

@footnotes.push [id, str]

end

def flush_footnote

footnote_begin
@footnotes.each do |id, str|
  footnote_item(id, str)
end
footnote_end

end



174
175
176
# File 'lib/review/builder.rb', line 174

def compile_inline(s)
  @compiler.text(s)
end

#detab(str, num = nil) ⇒ Object

override TextUtils::detab



415
416
417
418
419
420
421
422
423
# File 'lib/review/builder.rb', line 415

def detab(str, num = nil)
  if num
    super(str, num)
  elsif @tabwidth
    super(str, @tabwidth)
  else
    super(str)
  end
end

#error(msg) ⇒ Object

Raises:



295
296
297
# File 'lib/review/builder.rb', line 295

def error(msg)
  raise ApplicationError, "#{@location}: error: #{msg}"
end

#extract_chapter_id(chap_ref) ⇒ Object



332
333
334
335
336
337
338
339
# File 'lib/review/builder.rb', line 332

def extract_chapter_id(chap_ref)
  m = /\A([\w+-]+)\|(.+)/.match(chap_ref)
  if m
    return [@book.chapters.detect{|chap| chap.id == m[1]}, m[2]]
  else
    return [@chapter, chap_ref]
  end
end

#get_chap(chapter = @chapter) ⇒ Object



325
326
327
328
329
330
# File 'lib/review/builder.rb', line 325

def get_chap(chapter = @chapter)
  if @book.config["secnolevel"] > 0 && !chapter.number.nil? && !chapter.number.to_s.empty?
    return "#{chapter.number}"
  end
  return nil
end

#graph(lines, id, command, caption = nil) ⇒ Object



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/review/builder.rb', line 353

def graph(lines, id, command, caption = nil)
  c = target_name
  dir = File.join(@book.basedir, @book.image_dir, c)
  Dir.mkdir(dir) unless File.exist?(dir)
  file = "#{id}.#{image_ext}"
  file_path = File.join(dir, file)

  line = self.unescape(lines.join("\n"))
  cmds = {
    :graphviz => "echo '#{line}' | dot -T#{image_ext} -o#{file_path}",
    :gnuplot  => "echo 'set terminal " +
    "#{(image_ext == "eps") ? "postscript eps" : image_ext}\n" +
    " set output \"#{file_path}\"\n#{line}' | gnuplot",
    :blockdiag => "echo '#{line}' "+
    "| blockdiag -a -T #{image_ext} -o #{file_path} /dev/stdin",
    :aafigure => "echo '#{line}' | aafigure -t#{image_ext} -o#{file_path}",
  }
  cmd = cmds[command.to_sym]
  warn cmd
  system cmd
  @chapter.image_index.image_finder.add_entry(file_path)

  image(lines, id, caption ||= "")
end

#handle_metric(str) ⇒ Object



299
300
301
# File 'lib/review/builder.rb', line 299

def handle_metric(str)
  str
end

#image(lines, id, caption, metric = nil) ⇒ Object



102
103
104
105
106
107
108
109
# File 'lib/review/builder.rb', line 102

def image(lines, id, caption, metric = nil)
  if @chapter.image(id).bound?
    image_image id, caption, metric
  else
    warn "image not bound: #{id}" if @strict
    image_dummy id, caption, lines
  end
end

#image_extObject

Raises:

  • (NotImplementedError)


378
379
380
# File 'lib/review/builder.rb', line 378

def image_ext
  raise NotImplementedError
end

#include(file_name) ⇒ Object



387
388
389
390
391
# File 'lib/review/builder.rb', line 387

def include(file_name)
  File.foreach(file_name) do |line|
    paragraph([convert_inencoding(line, @book.config["inencoding"])])
  end
end

#inline_bou(str) ⇒ Object



227
228
229
# File 'lib/review/builder.rb', line 227

def inline_bou(str)
  text(str)
end

#inline_chap(id) ⇒ Object



185
186
187
188
189
190
# File 'lib/review/builder.rb', line 185

def inline_chap(id)
  @chapter.env.chapter_index.number(id)
rescue KeyError
  error "unknown chapter: #{id}"
  nofunc_text("[UnknownChapter:#{id}]")
end

#inline_chapref(id) ⇒ Object



178
179
180
181
182
183
# File 'lib/review/builder.rb', line 178

def inline_chapref(id)
  compile_inline @chapter.env.chapter_index.display_string(id)
rescue KeyError
  error "unknown chapter: #{id}"
  nofunc_text("[UnknownChapter:#{id}]")
end

#inline_column(id) ⇒ Object



270
271
272
273
274
275
# File 'lib/review/builder.rb', line 270

def inline_column(id)
  @chapter.column(id).caption
rescue
  error "unknown column: #{id}"
  nofunc_text("[UnknownColumn:#{id}]")
end

#inline_fn(id) ⇒ Object



220
221
222
223
224
225
# File 'lib/review/builder.rb', line 220

def inline_fn(id)
  @chapter.footnote(id).content
rescue KeyError
  error "unknown footnote: #{id}"
  nofunc_text("[UnknownFootnote:#{id}]")
end

#inline_hd(id) ⇒ Object



263
264
265
266
267
268
# File 'lib/review/builder.rb', line 263

def inline_hd(id)
  m = /\A([^|]+)\|(.+)/.match(id)
  chapter = @book.chapters.detect{|chap| chap.id == m[1]} if m && m[1]
  return inline_hd_chap(chapter, m[2]) if chapter
  return inline_hd_chap(@chapter, id)
end

#inline_href(arg) ⇒ Object



243
244
245
246
247
248
# File 'lib/review/builder.rb', line 243

def inline_href(arg)
  url, label = *arg.scan(/(?:(?:(?:\\\\)*\\,)|[^,\\]+)+/).map(&:lstrip)
  url = url.gsub(/\\,/, ",").strip
  label = label.gsub(/\\,/, ",").strip if label
  compile_href(url, label)
end

#inline_img(id) ⇒ Object



206
207
208
209
210
211
# File 'lib/review/builder.rb', line 206

def inline_img(id)
  "#{I18n.t("image")}#{@chapter.image(id).number}"
rescue KeyError
  error "unknown image: #{id}"
  nofunc_text("[UnknownImage:#{id}]")
end

#inline_include(file_name) ⇒ Object



382
383
384
385
# File 'lib/review/builder.rb', line 382

def inline_include(file_name)
  compile_inline convert_inencoding(File.open(file_name).read,
                                    @book.config["inencoding"])
end

#inline_kw(arg) ⇒ Object



238
239
240
241
# File 'lib/review/builder.rb', line 238

def inline_kw(arg)
  word, alt = *arg.split(',', 2)
  compile_kw(word, alt)
end

#inline_list(id) ⇒ Object



199
200
201
202
203
204
# File 'lib/review/builder.rb', line 199

def inline_list(id)
  "#{I18n.t("list")}#{@chapter.list(id).number}"
rescue KeyError
  error "unknown list: #{id}"
  nofunc_text("[UnknownList:#{id}]")
end

#inline_raw(args) ⇒ Object



400
401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/review/builder.rb', line 400

def inline_raw(args)
  if matched = args.match(/\|(.*?)\|(.*)/)
    builders = matched[1].split(/,/).map{|i| i.gsub(/\s/, '') }
    c = self.class.to_s.gsub(/ReVIEW::/, '').gsub(/Builder/, '').downcase
    if builders.include?(c)
      matched[2].gsub("\\n", "\n")
    else
      ""
    end
  else
    args.gsub("\\n", "\n")
  end
end

#inline_ruby(arg) ⇒ Object



231
232
233
234
235
236
# File 'lib/review/builder.rb', line 231

def inline_ruby(arg)
  base, *ruby = *arg.scan(/(?:(?:(?:\\\\)*\\,)|[^,\\]+)+/)
  base = base.gsub(/\\,/, ",") if base
  ruby = ruby.join(",").gsub(/\\,/, ",") if ruby
  compile_ruby(base, ruby)
end

#inline_table(id) ⇒ Object



213
214
215
216
217
218
# File 'lib/review/builder.rb', line 213

def inline_table(id)
  "#{I18n.t("table")}#{@chapter.table(id).number}"
rescue KeyError
  error "unknown table: #{id}"
  nofunc_text("[UnknownTable:#{id}]")
end

#inline_title(id) ⇒ Object



192
193
194
195
196
197
# File 'lib/review/builder.rb', line 192

def inline_title(id)
  compile_inline @chapter.env.chapter_index.title(id)
rescue KeyError
  error "unknown chapter: #{id}"
  nofunc_text("[UnknownChapter:#{id}]")
end

#list(lines, id, caption) ⇒ Object



79
80
81
82
83
84
85
86
# File 'lib/review/builder.rb', line 79

def list(lines, id, caption)
  begin
    list_header id, caption
  rescue KeyError
    error "no such list: #{id}"
  end
  list_body id, lines
end

#listnum(lines, id, caption) ⇒ Object



88
89
90
91
92
93
94
95
# File 'lib/review/builder.rb', line 88

def listnum(lines, id, caption)
  begin
    list_header id, caption
  rescue KeyError
    error "no such list: #{id}"
  end
  listnum_body lines
end

#parse_metric(type, metric) ⇒ Object



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/review/builder.rb', line 307

def parse_metric(type, metric)
  return "" if metric.blank?
  params = metric.split(/,\s*/)
  results = []
  params.each do |p|
    if p =~ /\A.+?::/
      if p =~ /\A#{type}::/
          p.sub!(/\A#{type}::/, '')
      else
        next
      end
    end
    p = handle_metric(p)
    results.push(p)
  end
  return result_metric(results)
end

#post_paragraphObject



27
28
29
# File 'lib/review/builder.rb', line 27

def post_paragraph
  nil
end

#pre_paragraphObject



24
25
26
# File 'lib/review/builder.rb', line 24

def pre_paragraph
  nil
end


63
64
65
66
67
# File 'lib/review/builder.rb', line 63

def print(*s)
  @output.print(*s.map{|i|
    convert_outencoding(i, @book.config["outencoding"])
  })
end

#puts(*s) ⇒ Object



69
70
71
72
73
# File 'lib/review/builder.rb', line 69

def puts(*s)
  @output.puts *s.map{|i|
    convert_outencoding(i, @book.config["outencoding"])
  }
end

#raw(str) ⇒ Object



277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/review/builder.rb', line 277

def raw(str)
  if matched = str.match(/\|(.*?)\|(.*)/)
    builders = matched[1].split(/,/).map{|i| i.gsub(/\s/, '') }
    c = target_name
    if builders.include?(c)
      print matched[2].gsub("\\n", "\n")
    else
      ""
    end
  else
    print str.gsub("\\n", "\n")
  end
end

#resultObject Also known as: raw_result



57
58
59
# File 'lib/review/builder.rb', line 57

def result
  @output.string
end

#result_metric(array) ⇒ Object



303
304
305
# File 'lib/review/builder.rb', line 303

def result_metric(array)
  array.join(',')
end

#source(lines, caption) ⇒ Object



97
98
99
100
# File 'lib/review/builder.rb', line 97

def source(lines, caption)
  source_header caption
  source_body lines
end

#table(lines, id = nil, caption = nil) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/review/builder.rb', line 111

def table(lines, id = nil, caption = nil)
  rows = []
  sepidx = nil
  lines.each_with_index do |line, idx|
    if /\A[\=\-]{12}/ =~ line
      # just ignore
      #error "too many table separator" if sepidx
      sepidx ||= idx
      next
    end
    rows.push line.strip.split(/\t+/).map {|s| s.sub(/\A\./, '') }
  end
  rows = adjust_n_cols(rows)

  begin
    table_header id, caption unless caption.nil?
  rescue KeyError
    error "no such table: #{id}"
  end
  return if rows.empty?
  table_begin rows.first.size
  if sepidx
    sepidx.times do
      tr rows.shift.map {|s| th(s) }
    end
    rows.each do |cols|
      tr cols.map {|s| td(s) }
    end
  else
    rows.each do |cols|
      h, *cs = *cols
      tr [th(h)] + cs.map {|s| td(s) }
    end
  end
  table_end
end

#target_nameObject



75
76
77
# File 'lib/review/builder.rb', line 75

def target_name
  self.class.to_s.gsub(/ReVIEW::/, '').gsub(/Builder/, '').downcase
end

#text(str) ⇒ Object



250
251
252
# File 'lib/review/builder.rb', line 250

def text(str)
  str
end

#ul_item_begin(lines) ⇒ Object



393
394
395
# File 'lib/review/builder.rb', line 393

def ul_item_begin(lines)
  ul_item(lines)
end

#ul_item_endObject



397
398
# File 'lib/review/builder.rb', line 397

def ul_item_end
end

#warn(msg) ⇒ Object



291
292
293
# File 'lib/review/builder.rb', line 291

def warn(msg)
  $stderr.puts "#{@location}: warning: #{msg}"
end