File: generator.rb

package info (click to toggle)
ruby-temple 0.10.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 476 kB
  • sloc: ruby: 3,347; makefile: 6
file content (91 lines) | stat: -rw-r--r-- 2,015 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# frozen_string_literal: true
module Temple
  # Abstract generator base class
  # Generators should inherit this class and
  # compile the Core Abstraction to ruby code.
  #
  # @api public
  class Generator
    include Utils
    include Mixins::CompiledDispatcher
    include Mixins::Options

    define_options :save_buffer,
                   capture_generator: 'StringBuffer',
                   buffer: '_buf',
                   freeze_static: true

    def call(exp)
      [preamble, compile(exp), postamble].flatten.compact.join('; ')
    end

    def preamble
      [save_buffer, create_buffer]
    end

    def postamble
      [return_buffer, restore_buffer]
    end

    def save_buffer
      "begin; #{@original_buffer = unique_name} = #{buffer} if defined?(#{buffer})" if options[:save_buffer]
    end

    def restore_buffer
      "ensure; #{buffer} = #{@original_buffer}; end" if options[:save_buffer]
    end

    def create_buffer
    end

    def return_buffer
      'nil'
    end

    def on(*exp)
      raise InvalidExpression, "Generator supports only core expressions - found #{exp.inspect}"
    end

    def on_multi(*exp)
      exp.map {|e| compile(e) }.join('; '.freeze)
    end

    def on_newline
      "\n"
    end

    def on_capture(name, exp)
      capture_generator.new(capture_generator: options[:capture_generator],
                            freeze_static: options[:freeze_static],
                            buffer: name).call(exp)
    end

    def on_static(text)
      concat(options[:freeze_static] ? "#{text.inspect}.freeze" : text.inspect)
    end

    def on_dynamic(code)
      concat(code)
    end

    def on_code(code)
      code
    end

    protected

    def buffer
      options[:buffer]
    end

    def capture_generator
      @capture_generator ||= Class === options[:capture_generator] ?
      options[:capture_generator] :
        Generators.const_get(options[:capture_generator])
    end

    def concat(str)
      "#{buffer} << (#{str})"
    end
  end
end