Class: ReVIEW::Compiler

Inherits:
Object show all
Includes:
Loggable
Defined in:
lib/review/compiler.rb

Defined Under Namespace

Classes: InlineSyntaxElement, SyntaxElement

Constant Summary collapse

MAX_HEADLINE_LEVEL =
6
SYNTAX =
{}
INLINE =
{}

Instance Attribute Summary collapse

Attributes included from Loggable

#logger

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Loggable

#app_error, #debug, #error!, #warn

Constructor Details

#initialize(builder) ⇒ Compiler

Returns a new instance of Compiler.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/review/compiler.rb', line 24

def initialize(builder)
  @builder = builder

  ## commands which do not parse block lines in compiler
  @non_parsed_commands = %i[embed texequation graph]

  ## to decide escaping/non-escaping for text
  @command_name_stack = []

  @logger = ReVIEW.logger

  @ignore_errors = builder.is_a?(ReVIEW::IndexBuilder)

  @compile_errors = nil
end

Instance Attribute Details

#builderObject (readonly)

Returns the value of attribute builder.



40
41
42
# File 'lib/review/compiler.rb', line 40

def builder
  @builder
end

#previous_list_typeObject (readonly)

Returns the value of attribute previous_list_type.



40
41
42
# File 'lib/review/compiler.rb', line 40

def previous_list_type
  @previous_list_type
end

Class Method Details

.defblock(name, argc, optional = false, &block) ⇒ Object



109
110
111
# File 'lib/review/compiler.rb', line 109

def self.defblock(name, argc, optional = false, &block)
  defsyntax(name, (optional ? :optional : :block), argc, &block)
end

.definline(name) ⇒ Object



125
126
127
# File 'lib/review/compiler.rb', line 125

def self.definline(name)
  INLINE[name] = InlineSyntaxElement.new(name)
end

.defminicolumn(name, argc, _optional = false, &block) ⇒ Object



113
114
115
# File 'lib/review/compiler.rb', line 113

def self.defminicolumn(name, argc, _optional = false, &block)
  defsyntax(name, :minicolumn, argc, &block)
end

.defsingle(name, argc, &block) ⇒ Object



117
118
119
# File 'lib/review/compiler.rb', line 117

def self.defsingle(name, argc, &block)
  defsyntax(name, :line, argc, &block)
end

.defsyntax(name, type, argc, &block) ⇒ Object



121
122
123
# File 'lib/review/compiler.rb', line 121

def self.defsyntax(name, type, argc, &block)
  SYNTAX[name] = SyntaxElement.new(name, type, argc, &block)
end

.minicolumn_namesObject



129
130
131
132
133
134
135
136
137
# File 'lib/review/compiler.rb', line 129

def self.minicolumn_names
  buf = []
  SYNTAX.each do |name, syntax|
    if syntax.minicolumn?
      buf << name.to_s
    end
  end
  buf
end

Instance Method Details

#compile(chap) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/review/compiler.rb', line 55

def compile(chap)
  @chapter = chap
  do_compile
  if @compile_errors
    raise ApplicationError, "#{location.filename} cannot be compiled."
  end

  @builder.result
end

#inline_defined?(name) ⇒ Boolean

Returns:

  • (Boolean)


157
158
159
# File 'lib/review/compiler.rb', line 157

def inline_defined?(name)
  INLINE.key?(name.to_sym)
end

#non_escaped_commandsObject



47
48
49
50
51
52
53
# File 'lib/review/compiler.rb', line 47

def non_escaped_commands
  if @builder.highlight?
    %i[list emlist listnum emlistnum cmd source]
  else
    []
  end
end

#strategyObject



42
43
44
45
# File 'lib/review/compiler.rb', line 42

def strategy
  error 'Compiler#strategy is obsoleted. Use Compiler#builder.'
  @builder
end

#syntax_defined?(name) ⇒ Boolean

Returns:

  • (Boolean)


139
140
141
# File 'lib/review/compiler.rb', line 139

def syntax_defined?(name)
  SYNTAX.key?(name.to_sym)
end

#syntax_descriptor(name) ⇒ Object



143
144
145
# File 'lib/review/compiler.rb', line 143

def syntax_descriptor(name)
  SYNTAX[name.to_sym]
end

#text(str, block_mode = false) ⇒ Object



670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
# File 'lib/review/compiler.rb', line 670

def text(str, block_mode = false)
  return '' if str.empty?

  words = replace_fence(str).split(/(@<\w+>\{(?:[^}\\]|\\.)*?\})/, -1)
  words.each do |w|
    if w.scan(/@<\w+>/).size > 1 && !/\A@<raw>/.match(w)
      error "`@<xxx>' seen but is not valid inline op: #{w}", location: location
    end
  end
  result = +''
  until words.empty?
    result << if in_non_escaped_command? && block_mode
                revert_replace_fence(words.shift)
              else
                @builder.nofunc_text(revert_replace_fence(words.shift))
              end
    break if words.empty?

    result << compile_inline(revert_replace_fence(words.shift.gsub('\\}', '}').gsub('\\\\', '\\')))
  end
  result
rescue StandardError => e
  error e.message, location: location
end