class ReVIEW::Compiler

Constants

COMPLEX_INLINE
INLINE
SYNTAX

Attributes

strategy[RW]

Public Class Methods

defblock(name, argc, optional = false, esc = nil, &block) click to toggle source
# File lib/review/compiler.rb, line 526
def self.defblock(name, argc, optional = false, esc = nil, &block)
  defsyntax(name, (optional ? :optional : :block), argc, esc, &block)
end
defcodeblock(name, argc, optional = false, esc = nil, &block) click to toggle source
# File lib/review/compiler.rb, line 530
def self.defcodeblock(name, argc, optional = false, esc = nil, &block)
  defsyntax(name, (optional ? :optional_code_block : :code_block), argc, esc, &block)
end
defcomplexinline(name) click to toggle source
# File lib/review/compiler.rb, line 565
def self.defcomplexinline(name)
  COMPLEX_INLINE[name] = InlineSyntaxElement.new(name)
end
definline(name) click to toggle source
# File lib/review/compiler.rb, line 561
def self.definline(name)
  INLINE[name] = InlineSyntaxElement.new(name)
end
defsingle(name, argc, esc = nil, &block) click to toggle source
# File lib/review/compiler.rb, line 534
def self.defsingle(name, argc, esc = nil, &block)
  defsyntax name, :line, argc, esc, &block
end
defsyntax(name, type, argc, esc = nil, &block) click to toggle source
# File lib/review/compiler.rb, line 538
def self.defsyntax(name, type, argc, esc = nil, &block)
  SYNTAX[name] = SyntaxElement.new(name, type, argc, esc, &block)
end
new(strategy) click to toggle source

redifine Compiler.new

# File lib/review/compiler.rb, line 396
def initialize(strategy)
  @strategy = strategy
  @current_column = nil
  @chapter = nil
end

Public Instance Methods

check_complex_inline_element_symbol(name) click to toggle source
# File lib/review/compiler.rb, line 863
def check_complex_inline_element_symbol(name)
  COMPLEX_INLINE.key?(name.to_sym)
end
check_indent(s) click to toggle source
# File lib/review/compiler.rb, line 851
def check_indent(s)
  s.size >= @list_stack.last.size
end
check_inline_element_symbol(name) click to toggle source
# File lib/review/compiler.rb, line 859
def check_inline_element_symbol(name)
  INLINE.key?(name.to_sym)
end
check_nested_indent(s) click to toggle source
# File lib/review/compiler.rb, line 855
def check_nested_indent(s)
  s.size >= @list_stack.last.size + 2
end
comment(text) click to toggle source
# File lib/review/compiler.rb, line 713
def comment(text)
  @strategy.comment(text)
end
compile(chap) click to toggle source
# File lib/review/compiler.rb, line 404
def compile(chap)
  @chapter = chap
  do_compile
  @strategy.result
end
compile_block(syntax, args, lines, node) click to toggle source
# File lib/review/compiler.rb, line 783
def compile_block(syntax, args, lines, node)
  node_name = "node_#{syntax.name}".to_sym
  if @strategy.respond_to?(node_name)
    @strategy.__send__(node_name, node)
  else
    args_conv = syntax.parse_args(args)
    @strategy.__send__(syntax.name, (lines || default_block(syntax)), *args_conv)
  end
end
compile_column(level, label, caption, content) click to toggle source
# File lib/review/compiler.rb, line 667
def compile_column(level, label, caption, content)
  buf = ""
  buf << @strategy.__send__("column_begin", level, label, caption)
  buf << content.to_doc
  buf << @strategy.__send__("column_end", level)
  buf
end
compile_command(name, args, lines, node) click to toggle source
# File lib/review/compiler.rb, line 675
def compile_command(name, args, lines, node)
  syntax = syntax_descriptor(name)
  if !syntax || (!@strategy.respond_to?(syntax.name) && !@strategy.respond_to?("node_#{syntax.name}"))
    error "strategy does not support command: //#{name}"
    compile_unknown_command args, lines
    return
  end
  begin
    syntax.check_args args
  rescue ReVIEW::CompileError => err
    error err.message
    args = ['(NoArgument)'] * syntax.min_argc
  end
  if syntax.block_allowed?
    compile_block(syntax, args, lines, node)
  else
    if lines
      error "block is not allowed for command //#{syntax.name}; ignore"
    end
    compile_single(syntax, args, node)
  end
end
compile_dlist(content) click to toggle source
# File lib/review/compiler.rb, line 767
def compile_dlist(content)
  buf = ""
  buf << @strategy.dl_begin
  content.each do |element|
    buf << @strategy.dt(element.text.to_doc)
    buf << @strategy.dd(element.content.map{|s| s.to_doc})
  end
  buf << @strategy.dl_end
  buf
end
compile_headline(level, tag, label, caption) click to toggle source
# File lib/review/compiler.rb, line 698
def compile_headline(level, tag, label, caption)
  buf = ""
  @headline_indexs ||= [0] ## XXX
  caption ||= ""
  caption.strip!
  index = level - 1
  if @headline_indexs.size > (index + 1)
    @headline_indexs = @headline_indexs[0..index]
  end
  @headline_indexs[index] = 0 if @headline_indexs[index].nil?
  @headline_indexs[index] += 1
  buf << @strategy.headline(level, label, caption)
  buf
end
compile_inline(op, args) click to toggle source
# File lib/review/compiler.rb, line 811
    def compile_inline(op, args)
      unless inline_defined?(op)
        raise ReVIEW::CompileError, "no such inline op: #{op}"
      end
      if @strategy.respond_to?("node_inline_#{op}")
        return @strategy.__send__("node_inline_#{op}", args)
      end
      unless @strategy.respond_to?("inline_#{op}")
        raise "strategy does not support inline op: @<#{op}>"
      end
      if !args
        @strategy.__send__("inline_#{op}", "")
      else
        @strategy.__send__("inline_#{op}", *(args.map(&:to_doc)))
      end
#    rescue => err
#      error err.message
    end
compile_olist(content) click to toggle source
# File lib/review/compiler.rb, line 756
def compile_olist(content)
  buf0 = ""
  buf0 << @strategy.ol_begin
  content.each do |element|
    ## XXX 1st arg should be String, not Array
    buf0 << @strategy.ol_item(element.to_doc.split(/\n/), element.num)
  end
  buf0 << @strategy.ol_end
  buf0
end
compile_paragraph(buf) click to toggle source
# File lib/review/compiler.rb, line 830
def compile_paragraph(buf)
  @strategy.paragraph buf
end
compile_raw(builders, content) click to toggle source
# File lib/review/compiler.rb, line 834
def compile_raw(builders, content)
  c = @strategy.class.to_s.gsub(/ReVIEW::/, '').gsub(/Builder/, '').downcase
  if !builders || builders.include?(c)
    content.gsub("\\n", "\n")
  else
    ""
  end
end
compile_single(syntax, args, node) click to toggle source
# File lib/review/compiler.rb, line 800
def compile_single(syntax, args, node)
  node_name = "node_#{syntax.name}".to_sym
  if @strategy.respond_to?(node_name)
    @strategy.__send__(node_name, node)
  else
    args_conv = syntax.parse_args(args)
    @strategy.__send__(syntax.name, *args_conv)
  end
end
compile_text(text) click to toggle source
# File lib/review/compiler.rb, line 466
def compile_text(text)
  @strategy.nofunc_text(text)
end
compile_ulist(content) click to toggle source
# File lib/review/compiler.rb, line 717
def compile_ulist(content)
  buf0 = ""
  level = 0
  content.each do |element|
    current_level = element.level
    buf = element.to_doc
    if level == current_level
      buf0 << @strategy.ul_item_end
      # body
      buf0 << @strategy.ul_item_begin([buf])
    elsif level < current_level # down
      level_diff = current_level - level
      level = current_level
      (1..(level_diff - 1)).to_a.reverse_each do |i|
        buf0 << @strategy.ul_begin{i}
        buf0 << @strategy.ul_item_begin([])
      end
      buf0 << @strategy.ul_begin{level}
      buf0 << @strategy.ul_item_begin([buf])
    elsif level > current_level # up
      level_diff = level - current_level
      level = current_level
      (1..level_diff).to_a.reverse_each do |i|
        buf0 << @strategy.ul_item_end
        buf0 << @strategy.ul_end{level + i}
      end
      buf0 << @strategy.ul_item_end
      # body
      buf0 <<@strategy.ul_item_begin([buf])
    end
  end

  (1..level).to_a.reverse_each do |i|
    buf0 << @strategy.ul_item_end
    buf0 << @strategy.ul_end{i}
  end
  buf0
end
compile_unknown_command(args, lines) click to toggle source
# File lib/review/compiler.rb, line 779
def compile_unknown_command(args, lines)
  @strategy.unknown_command(args, lines)
end
convert_ast() click to toggle source
# File lib/review/compiler.rb, line 417
def convert_ast
  ast = @strategy.ast
  convert_column(ast)
  if $DEBUG
    File.open("review-dump.json","w") do |f|
      f.write(ast.to_json)
    end
  end
  @strategy.output << ast.to_doc
end
convert_column(ast) click to toggle source
# File lib/review/compiler.rb, line 435
def convert_column(ast)
  @column_stack = []
  content = ast.content
  new_content = []
  @current_content = new_content
  content.each do |elem|
    if elem.kind_of?(ReVIEW::HeadlineNode) && elem.cmd && elem.cmd.to_doc == "column"
      flush_column(new_content)
      @current_content = []
      @current_column = ReVIEW::ColumnNode.new(elem.compiler, elem.position, elem.level,
                                              elem.label, elem.content, @current_content)
      next
    elsif elem.kind_of?(ReVIEW::HeadlineNode) && elem.cmd && elem.cmd.to_doc =~ %r|^/|
      cmd_name = elem.cmd.to_doc[1..-1]
      if cmd_name != "column"
        raise ReVIEW::CompileError, "#{cmd_name} is not opened."
      end
      flush_column(new_content)
      @current_content = new_content
      next
    elsif elem.kind_of?(ReVIEW::HeadlineNode) && @current_column && elem.level <= @current_column.level
      flush_column(new_content)
      @current_content = new_content
    end
    @current_content << elem
  end
  flush_column(new_content)
  ast.content = new_content
  ast
end
default_block(syntax) click to toggle source
# File lib/review/compiler.rb, line 793
def default_block(syntax)
  if syntax.block_required?
    error "block is required for //#{syntax.name}; use empty block"
  end
  []
end
do_compile() click to toggle source
# File lib/review/compiler.rb, line 410
def do_compile
  @strategy.bind self, @chapter, ReVIEW::Location.new(@chapter.basename, self)
  setup_parser(@chapter.content)
  parse()
  convert_ast
end
error(msg) click to toggle source
# File lib/review/compiler.rb, line 847
def error(msg)
  @strategy.error msg
end
flush_column(new_content) click to toggle source
# File lib/review/compiler.rb, line 428
def flush_column(new_content)
  if @current_column
    new_content << @current_column
    @current_column = nil
  end
end
inline_defined?(name) click to toggle source
# File lib/review/compiler.rb, line 569
def inline_defined?(name)
  INLINE.key?(name.to_sym) || COMPLEX_INLINE.key?(name.to_sym)
end
position() click to toggle source
# File lib/review/compiler.rb, line 867
def position
  Position.new(self)
end
syntax_defined?(name) click to toggle source
# File lib/review/compiler.rb, line 542
def syntax_defined?(name)
  SYNTAX.key?(name.to_sym)
end
syntax_descriptor(name) click to toggle source
# File lib/review/compiler.rb, line 546
def syntax_descriptor(name)
  SYNTAX[name.to_sym]
end
warn(msg) click to toggle source
# File lib/review/compiler.rb, line 843
def warn(msg)
  @strategy.warn msg
end