antlers 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/antlers/lexer.rb +4 -2
- data/lib/antlers/parser.rb +7 -1
- data/lib/antlers/version.rb +1 -1
- data/lib/antlers.rb +1 -1
- data/lib/interfaces/lexeme.rb +1 -1
- data/lib/lexemes/form_lexeme.rb +1 -4
- data/lib/lexemes/var_lexeme.rb +1 -4
- data/lib/modules/props.rb +1 -1
- data/lib/modules/variables.rb +17 -15
- data/lib/nodes/for_node.rb +1 -1
- data/lib/nodes/form_node.rb +10 -2
- data/lib/nodes/if_node.rb +1 -1
- data/lib/nodes/var_node.rb +2 -8
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3c1e20787d49349b0f3df0f6df128650c7214ec53cd697ec66840d6f3884d9e8
|
|
4
|
+
data.tar.gz: 3048610d15b4fe61ff67123aba2b6f81a5ef9019e4ac03dea657995c30501b17
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bc0ff003117d8d08b22146b15a32f32288aef44191ba401080db525ed3125e6a7cc38fd278b64eb96eda1659d7b608cbf41f4b9a1879c8641eecf0f3fa4fc83d
|
|
7
|
+
data.tar.gz: e0a5d0d1c71721a4727b3f6134a1eafb40b75b34cff799cc5f2d94677cbf84b6e41dad3b6d8ad5bee5293ca1b1de10969d8e6af1d8cc19c6889b0dc0dbaca71b
|
data/lib/antlers/lexer.rb
CHANGED
|
@@ -73,7 +73,7 @@ module Antlers
|
|
|
73
73
|
|
|
74
74
|
while (keyword = keywords.shift)
|
|
75
75
|
keyword.strip!
|
|
76
|
-
value = keyword.end_with?(':') && value?(keywords.first
|
|
76
|
+
value = keyword.end_with?(':') && value?(keywords.first) ? keywords.shift.strip : nil
|
|
77
77
|
key_values[keyword] = value
|
|
78
78
|
end
|
|
79
79
|
|
|
@@ -81,7 +81,9 @@ module Antlers
|
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def value?(string)
|
|
84
|
-
|
|
84
|
+
# Support keywords without a value like "<{ form: }>" whose value will become an empty string.
|
|
85
|
+
string = string.to_s.strip
|
|
86
|
+
!string.empty? && !(string.start_with?(':') || string.end_with?(':'))
|
|
85
87
|
end
|
|
86
88
|
|
|
87
89
|
def brackets?(segments:)
|
data/lib/antlers/parser.rb
CHANGED
|
@@ -36,7 +36,13 @@ module Antlers
|
|
|
36
36
|
|
|
37
37
|
def sub_branch(node:, sequence:, end_key:, end_name: nil)
|
|
38
38
|
sub_sequence = []
|
|
39
|
-
|
|
39
|
+
|
|
40
|
+
until sequence.first.is_a?(Hash) && sequence.first[end_key] == end_name
|
|
41
|
+
raise ParserError, "Missing end tag for #{node.class}" if sequence.empty?
|
|
42
|
+
|
|
43
|
+
sub_sequence << sequence.shift
|
|
44
|
+
end
|
|
45
|
+
|
|
40
46
|
# Remove the end tag we just stopped before.
|
|
41
47
|
sequence.shift
|
|
42
48
|
|
data/lib/antlers/version.rb
CHANGED
data/lib/antlers.rb
CHANGED
|
@@ -7,7 +7,7 @@ require_relative 'antlers/parser'
|
|
|
7
7
|
module Antlers
|
|
8
8
|
module_function
|
|
9
9
|
|
|
10
|
-
DEFAULT_ELEMENTS = %i[root html form for if prop slot yield var]
|
|
10
|
+
DEFAULT_ELEMENTS = %i[root html form for if prop slot yield var].freeze
|
|
11
11
|
|
|
12
12
|
def ast(template:, namespace: nil, elements: Elements[*DEFAULT_ELEMENTS])
|
|
13
13
|
sequence = Lexer.new(lexeme_types: elements[:lexeme]).parse(template:)
|
data/lib/interfaces/lexeme.rb
CHANGED
data/lib/lexemes/form_lexeme.rb
CHANGED
|
@@ -14,10 +14,7 @@ module Antlers
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def lexeme(keywords:, **)
|
|
17
|
-
if keywords.key?('form:')
|
|
18
|
-
action = keywords['form:'] ? keywords['form:'][1...-1] : nil
|
|
19
|
-
return { form_def: action }
|
|
20
|
-
end
|
|
17
|
+
return { form_def: keywords['form:'] } if keywords.key?('form:')
|
|
21
18
|
|
|
22
19
|
{ form_end: 'level_1' }
|
|
23
20
|
end
|
data/lib/lexemes/var_lexeme.rb
CHANGED
|
@@ -9,15 +9,12 @@ module Antlers
|
|
|
9
9
|
extend Queries
|
|
10
10
|
extend self
|
|
11
11
|
|
|
12
|
-
# Variables are special and are matched by the lexer.
|
|
12
|
+
# Variables are special and are matched by the lexer in a hard-coded fashion.
|
|
13
13
|
def match?(**)
|
|
14
14
|
false
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def lexeme(segment:, raw:, **)
|
|
18
|
-
# String is already interpolated or not depending on user input on the template layer, now we store it without those template quotes.
|
|
19
|
-
segment = segment[1..-2] if Queries.user_defined_string?(segment)
|
|
20
|
-
|
|
21
18
|
return { raw_var: segment } if raw
|
|
22
19
|
|
|
23
20
|
{ var: segment }
|
data/lib/modules/props.rb
CHANGED
data/lib/modules/variables.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'erb'
|
|
3
4
|
require_relative '../support/queries'
|
|
4
5
|
|
|
5
6
|
module Antlers
|
|
@@ -7,28 +8,29 @@ module Antlers
|
|
|
7
8
|
extend Queries
|
|
8
9
|
|
|
9
10
|
# Evaluation limited to the following for security and to stop a templating language becoming a programming language.
|
|
10
|
-
# 1.
|
|
11
|
-
# 2.
|
|
12
|
-
# 3. A method
|
|
13
|
-
# 4. A
|
|
14
|
-
def evaluate(
|
|
15
|
-
|
|
11
|
+
# 1. A static string
|
|
12
|
+
# 2. An instance variable
|
|
13
|
+
# 3. A method call/local variable
|
|
14
|
+
# 4. A method chain
|
|
15
|
+
def evaluate(value:, current_binding:, escape: true)
|
|
16
|
+
result = result(value:, current_binding:)
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
return ERB::Util.html_escape(result) if escape
|
|
19
|
+
|
|
20
|
+
result
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def result(value:, current_binding:)
|
|
24
|
+
return value[1..-2] if Queries.user_defined_string?(value)
|
|
25
|
+
return value unless current_binding
|
|
26
|
+
|
|
27
|
+
name, *chain = value.split('.')
|
|
18
28
|
|
|
19
29
|
result = method_var(name:, current_binding:)
|
|
20
30
|
return method_chain(result:, chain:) if chain.count > 0
|
|
21
31
|
return result if result
|
|
22
32
|
|
|
23
33
|
nil
|
|
24
|
-
rescue StandardError
|
|
25
|
-
nil
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def fallback(value)
|
|
29
|
-
return value[1..-2] if Queries.user_defined_string?(value)
|
|
30
|
-
|
|
31
|
-
value
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
private
|
data/lib/nodes/for_node.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Antlers
|
|
|
23
23
|
def render(current_binding: nil, parent_binding: nil, slot_node: nil, metadata: {})
|
|
24
24
|
output = ''
|
|
25
25
|
|
|
26
|
-
evaluate(
|
|
26
|
+
evaluate(value: @items, current_binding:, escape: false).each do |value|
|
|
27
27
|
key, value = value if @key
|
|
28
28
|
|
|
29
29
|
# TODO: Parallelize by creating new bindings and ensuring children have any args they need via RenderEvent.
|
data/lib/nodes/form_node.rb
CHANGED
|
@@ -20,7 +20,7 @@ module Antlers
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def render(current_binding: nil, parent_binding: nil, slot_node: nil, metadata: {})
|
|
23
|
-
output = "<form action='#{
|
|
23
|
+
output = "<form action='#{action(current_binding:)}' method='#{@method}'>"
|
|
24
24
|
|
|
25
25
|
@children.each do |child|
|
|
26
26
|
output += child.render(current_binding:, parent_binding:, slot_node:, metadata:) || ''
|
|
@@ -30,9 +30,17 @@ module Antlers
|
|
|
30
30
|
output
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def action(current_binding:)
|
|
36
|
+
return if @action.nil?
|
|
37
|
+
|
|
38
|
+
evaluate(value: @action, current_binding:)
|
|
39
|
+
end
|
|
40
|
+
|
|
33
41
|
class << self
|
|
34
42
|
def match?(segment:)
|
|
35
|
-
segment
|
|
43
|
+
segment.is_a?(Hash) && segment.key?(DEF_KEY)
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
def build(segment:, **)
|
data/lib/nodes/if_node.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Antlers
|
|
|
21
21
|
def render(current_binding: nil, parent_binding: nil, slot_node: nil, metadata: {})
|
|
22
22
|
output = ''.dup
|
|
23
23
|
|
|
24
|
-
if evaluate(
|
|
24
|
+
if evaluate(value: @value, current_binding:, escape: false)
|
|
25
25
|
@children.each do |child|
|
|
26
26
|
output += child.render(current_binding:, parent_binding:, slot_node:, metadata:) || ''
|
|
27
27
|
end
|
data/lib/nodes/var_node.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'erb'
|
|
4
|
-
|
|
5
3
|
require_relative '../interfaces/leaf_node'
|
|
6
4
|
require_relative '../modules/variables'
|
|
7
5
|
|
|
@@ -19,11 +17,7 @@ module Antlers
|
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
def render(current_binding: nil, parent_binding: nil, slot_node: nil, metadata: {})
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return result if @raw
|
|
25
|
-
|
|
26
|
-
ERB::Util.html_escape(result)
|
|
20
|
+
evaluate(value: @value, current_binding:, escape: !@raw)
|
|
27
21
|
end
|
|
28
22
|
|
|
29
23
|
class << self
|
|
@@ -32,7 +26,7 @@ module Antlers
|
|
|
32
26
|
end
|
|
33
27
|
|
|
34
28
|
def build(segment:, **)
|
|
35
|
-
new(value: segment[:var] || segment[:raw_var], raw:
|
|
29
|
+
new(value: segment[:var] || segment[:raw_var], raw: !segment[:raw_var].nil?)
|
|
36
30
|
end
|
|
37
31
|
end
|
|
38
32
|
end
|