Class: Twig::ExtensionSet

Inherits:
Object
  • Object
show all
Defined in:
lib/twig/extension_set.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeExtensionSet

Returns a new instance of ExtensionSet.



9
10
11
12
13
14
# File 'lib/twig/extension_set.rb', line 9

def initialize
  @extensions = {}
  @extensions.default_proc = lambda { |_hash, key|
    raise "Extension '#{key}' does not exist"
  }
end

Instance Attribute Details

#extensionsHash<String, Extension::Base> (readonly)

Returns:



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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/twig/extension_set.rb', line 6

class ExtensionSet
  attr_reader :extensions

  def initialize
    @extensions = {}
    @extensions.default_proc = lambda { |_hash, key|
      raise "Extension '#{key}' does not exist"
    }
  end

  # @param [Extension::Base] extension
  def add(extension)
    raise "Extension #{extension.class} already added" if has?(extension)

    @extensions[key(extension)] = extension
  end

  # @param [Object, String] extension
  # @return [Boolean]
  def has?(extension)
    extensions.key?(key(extension))
  end

  # @return [Extension::Base]
  def get(extension)
    extensions[key(extension)]
  end

  def expression_parsers
    @expression_parsers ||= ExpressionParser::ExpressionParsers.new.tap do |parsers|
      extensions.each_value do |extension|
        parsers.add(extension.expression_parsers)
      end
    end
  end

  # @return [Hash{String => TwigFilter}]
  def filters
    @filters ||= extensions.
      values.
      map(&:filters).
      flatten.
      to_h { |filter| [filter.name, filter] }
  end

  # @return [Hash{String => TwigFunction}]
  def functions
    @functions ||= extensions.
      values.
      map(&:functions).
      flatten.
      to_h { |function| [function.name, function] }
  end

  # @return [Hash{String => TwigTest}]
  def tests
    @tests ||= extensions.
      values.
      map(&:tests).
      flatten.
      to_h { |test| [test.name, test] }
  end

  # @return [TwigFilter, nil]
  def filter(name)
    return filters[name] if filters.key?(name)

    dynamic_filters.each do |pattern, filter|
      if (match = Regexp.new(pattern).match(name))
        return filter.with_dynamic_arguments(name, filter.name, match.captures)
      end
    end

    nil
  end

  # @return [TwigFunction, nil]
  def function(name)
    return functions[name] if functions.key?(name)

    dynamic_functions.each do |pattern, function|
      if (match = Regexp.new(pattern).match(name))
        return function.with_dynamic_arguments(name, function.name, match.captures)
      end
    end

    nil
  end

  # @return [TwigTest, nil]
  def test(name)
    return tests[name] if tests.key?(name)

    dynamic_tests.each do |pattern, test|
      if (match = Regexp.new(pattern).match(name))
        return test.with_dynamic_arguments(name, test.name, match.captures)
      end
    end

    nil
  end

  # @return [Array<TokenParser::Base>]
  def token_parsers
    @token_parsers ||= extensions.
      values.map(&:token_parsers).reduce([], :concat).
      to_h { |token_parser| [token_parser.tag.to_sym, token_parser] }
  end

  # @return [TokenParser::Base, nil]
  def token_parser(name)
    token_parsers[name.to_sym]
  end

  # @return [Array<NodeVisitor::Base>]
  def node_visitors
    @node_visitors ||= extensions.
      values.map(&:node_visitors).reduce([], :concat)
  end

  def globals
    @globals ||= extensions.
      values.map(&:globals).reduce({}, :merge)
  end

  private

  def dynamic_filters
    @dynamic_filters ||= filters.
      select { |name, _| name.include?('*') }.
      transform_keys { |name| dynamic_callable_regex(name) }
  end

  def dynamic_functions
    @dynamic_functions ||= functions.
      select { |name, _| name.include?('*') }.
      transform_keys { |name| dynamic_callable_regex(name) }
  end

  def dynamic_tests
    @dynamic_tests ||= tests.
      select { |name, _| name.include?('*') }.
      transform_keys { |name| dynamic_callable_regex(name) }
  end

  def dynamic_callable_regex(name)
    "^#{Regexp.quote(name).gsub('\\*', '(.*?)')}$"
  end

  def key(object)
    case object
    when String
      object
    when Class
      object.to_s
    else
      object.class.to_s
    end
  end
end

Instance Method Details

#add(extension) ⇒ Object

Parameters:



17
18
19
20
21
# File 'lib/twig/extension_set.rb', line 17

def add(extension)
  raise "Extension #{extension.class} already added" if has?(extension)

  @extensions[key(extension)] = extension
end

#expression_parsersObject



34
35
36
37
38
39
40
# File 'lib/twig/extension_set.rb', line 34

def expression_parsers
  @expression_parsers ||= ExpressionParser::ExpressionParsers.new.tap do |parsers|
    extensions.each_value do |extension|
      parsers.add(extension.expression_parsers)
    end
  end
end

#filter(name) ⇒ TwigFilter?

Returns:



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/twig/extension_set.rb', line 70

def filter(name)
  return filters[name] if filters.key?(name)

  dynamic_filters.each do |pattern, filter|
    if (match = Regexp.new(pattern).match(name))
      return filter.with_dynamic_arguments(name, filter.name, match.captures)
    end
  end

  nil
end

#filtersHash{String => TwigFilter}

Returns:



43
44
45
46
47
48
49
# File 'lib/twig/extension_set.rb', line 43

def filters
  @filters ||= extensions.
    values.
    map(&:filters).
    flatten.
    to_h { |filter| [filter.name, filter] }
end

#function(name) ⇒ TwigFunction?

Returns:



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/twig/extension_set.rb', line 83

def function(name)
  return functions[name] if functions.key?(name)

  dynamic_functions.each do |pattern, function|
    if (match = Regexp.new(pattern).match(name))
      return function.with_dynamic_arguments(name, function.name, match.captures)
    end
  end

  nil
end

#functionsHash{String => TwigFunction}

Returns:



52
53
54
55
56
57
58
# File 'lib/twig/extension_set.rb', line 52

def functions
  @functions ||= extensions.
    values.
    map(&:functions).
    flatten.
    to_h { |function| [function.name, function] }
end

#get(extension) ⇒ Extension::Base

Returns:



30
31
32
# File 'lib/twig/extension_set.rb', line 30

def get(extension)
  extensions[key(extension)]
end

#globalsObject



126
127
128
129
# File 'lib/twig/extension_set.rb', line 126

def globals
  @globals ||= extensions.
    values.map(&:globals).reduce({}, :merge)
end

#has?(extension) ⇒ Boolean

Parameters:

  • extension (Object, String)

Returns:

  • (Boolean)


25
26
27
# File 'lib/twig/extension_set.rb', line 25

def has?(extension)
  extensions.key?(key(extension))
end

#node_visitorsArray<NodeVisitor::Base>

Returns:



121
122
123
124
# File 'lib/twig/extension_set.rb', line 121

def node_visitors
  @node_visitors ||= extensions.
    values.map(&:node_visitors).reduce([], :concat)
end

#test(name) ⇒ TwigTest?

Returns:



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/twig/extension_set.rb', line 96

def test(name)
  return tests[name] if tests.key?(name)

  dynamic_tests.each do |pattern, test|
    if (match = Regexp.new(pattern).match(name))
      return test.with_dynamic_arguments(name, test.name, match.captures)
    end
  end

  nil
end

#testsHash{String => TwigTest}

Returns:



61
62
63
64
65
66
67
# File 'lib/twig/extension_set.rb', line 61

def tests
  @tests ||= extensions.
    values.
    map(&:tests).
    flatten.
    to_h { |test| [test.name, test] }
end

#token_parser(name) ⇒ TokenParser::Base?

Returns:



116
117
118
# File 'lib/twig/extension_set.rb', line 116

def token_parser(name)
  token_parsers[name.to_sym]
end

#token_parsersArray<TokenParser::Base>

Returns:



109
110
111
112
113
# File 'lib/twig/extension_set.rb', line 109

def token_parsers
  @token_parsers ||= extensions.
    values.map(&:token_parsers).reduce([], :concat).
    to_h { |token_parser| [token_parser.tag.to_sym, token_parser] }
end