curlybars 1.13.0 → 1.14.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ef985c46340022e337318774e4fcf8f36a1f0f7fc6d87788d70ffa3b214f16f
4
- data.tar.gz: 1bd1f9195be76418bc0b416f6466aa73809f39037d93ccdde901d90ffca14baa
3
+ metadata.gz: 2bf7afea132372069b140438296f8686ec486b2759c7fc89552b332ff1aed7ed
4
+ data.tar.gz: e03465297fef9e3c18c817bac1f0daae10d01d9cc051ac295049b7df9ae70158
5
5
  SHA512:
6
- metadata.gz: 443143ccfb796e5cc14f4cb4bf2f5c1958b8de9b271c95f8fdfccc07caa169d520e4563e70b5111109f6d914388d18c8c6bd519f837524371f235cb375b10389
7
- data.tar.gz: fc72c19b12e2084f7e9dab5a01c51d6c6f7ab1614dde449f635356f40fc0841ef3305fd2fb6169763c6333e66324e3486d38f396516325794597b8184801e84a
6
+ metadata.gz: 139398b59fdf16fd1b287a9a6968a304ea99b52bff79592a262ca695942d17e02a5c0a84fb7a278cba1d4f503f394fb1a42794ad90e71e647cb0174331266108
7
+ data.tar.gz: 2ce2c49e86bcdfd99b7754b8b6a48ec7d9ef01ef97b99c179c4a7d466838ce676e40cb82d6f0f80dc748d3eb516a9af8f9c74ac1ce800a68896fd1ae1d6cb49e
@@ -5,9 +5,13 @@ module Curlybars
5
5
  @matches = []
6
6
  end
7
7
 
8
- def find(target_path)
8
+ # Find paths matching +target_path+.
9
+ # +role:+ filters by syntactic role — :output, :helper, :argument, :option,
10
+ # :condition, :collection, :scope, :partial, or an Array of these.
11
+ def find(target_path, role: nil)
9
12
  @matches = []
10
13
  @target_segments = normalize_path(target_path)
14
+ @role_filter = role
11
15
  traverse(@ast.template, [])
12
16
  @matches
13
17
  end
@@ -20,7 +24,7 @@ module Curlybars
20
24
  path.to_s.split('.')
21
25
  end
22
26
 
23
- def traverse(node, context_stack)
27
+ def traverse(node, context_stack, role: nil)
24
28
  return unless node
25
29
 
26
30
  case node
@@ -29,15 +33,15 @@ module Curlybars
29
33
  when Curlybars::Node::Item
30
34
  traverse(node.item, context_stack)
31
35
  when Curlybars::Node::Path
32
- check_path_match(node, context_stack)
36
+ check_path_match(node, context_stack, role)
33
37
  when Curlybars::Node::Output
34
- traverse(node.value, context_stack)
38
+ traverse(node.value, context_stack, role: :output)
35
39
  when Curlybars::Node::Partial
36
- traverse(node.path, context_stack)
40
+ traverse(node.path, context_stack, role: :partial)
37
41
  when Curlybars::Node::SubExpression
38
- traverse(node.helper, context_stack)
39
- node.arguments&.each { |arg| traverse(arg, context_stack) }
40
- node.options&.each { |opt| traverse(opt.expression, context_stack) }
42
+ traverse(node.helper, context_stack, role: :helper)
43
+ node.arguments&.each { |arg| traverse(arg, context_stack, role: :argument) }
44
+ node.options&.each { |opt| traverse(opt.expression, context_stack, role: :option) }
41
45
  when Curlybars::Node::BlockHelperElse
42
46
  handle_block_helper(node, context_stack)
43
47
  when Curlybars::Node::IfElse, Curlybars::Node::UnlessElse
@@ -49,13 +53,25 @@ module Curlybars
49
53
  end
50
54
  end
51
55
 
52
- def check_path_match(path_node, context_stack)
56
+ def check_path_match(path_node, context_stack, role)
57
+ return unless matches_role?(role)
58
+
53
59
  path_segments = path_node.path.split('.')
54
60
  resolved_segments = resolve_path(path_segments, context_stack)
55
61
 
56
62
  @matches << path_node if resolved_segments == @target_segments
57
63
  end
58
64
 
65
+ def matches_role?(role)
66
+ return true if @role_filter.nil?
67
+
68
+ if @role_filter.is_a?(Array)
69
+ @role_filter.include?(role)
70
+ else
71
+ @role_filter == role
72
+ end
73
+ end
74
+
59
75
  def resolve_path(path_segments, context_stack)
60
76
  full_path = path_segments.join('.')
61
77
  stack = context_stack.dup
@@ -71,15 +87,25 @@ module Curlybars
71
87
  end
72
88
 
73
89
  def handle_block_helper(node, context_stack)
74
- traverse(node.helper, context_stack)
90
+ if simple_output?(node)
91
+ traverse(node.helper, context_stack, role: :output)
92
+ else
93
+ traverse(node.helper, context_stack, role: :helper)
94
+ node.arguments&.each { |arg| traverse(arg, context_stack, role: :argument) }
95
+ node.options&.each { |opt| traverse(opt.expression, context_stack, role: :option) }
96
+ end
75
97
  traverse(node.helper_template, context_stack)
76
98
  traverse(node.else_template, context_stack) if node.else_template
77
- node.arguments&.each { |arg| traverse(arg, context_stack) }
78
- node.options&.each { |opt| traverse(opt.expression, context_stack) }
99
+ end
100
+
101
+ def simple_output?(block_helper)
102
+ block_helper.arguments.empty? &&
103
+ block_helper.options.empty? &&
104
+ !block_helper.helper_template.is_a?(Curlybars::Node::Template)
79
105
  end
80
106
 
81
107
  def handle_conditional(node, context_stack)
82
- traverse(node.expression, context_stack)
108
+ traverse(node.expression, context_stack, role: :condition)
83
109
 
84
110
  if node.is_a?(Curlybars::Node::IfElse)
85
111
  traverse(node.if_template, context_stack)
@@ -90,7 +116,7 @@ module Curlybars
90
116
  end
91
117
 
92
118
  def handle_each(node, context_stack)
93
- traverse(node.path, context_stack)
119
+ traverse(node.path, context_stack, role: :collection)
94
120
 
95
121
  # EachElse changes context to the item being iterated
96
122
  collection_path = node.path.respond_to?(:subexpression?) && node.path.subexpression? ? node.path.helper : node.path
@@ -100,7 +126,7 @@ module Curlybars
100
126
  end
101
127
 
102
128
  def handle_with(node, context_stack)
103
- traverse(node.path, context_stack)
129
+ traverse(node.path, context_stack, role: :scope)
104
130
 
105
131
  # WithElse changes context to the specified path
106
132
  presenter_path = node.path.respond_to?(:subexpression?) && node.path.subexpression? ? node.path.helper : node.path
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Curlybars
4
- VERSION = '1.13.0'
4
+ VERSION = '1.14.0'
5
5
  end
data/lib/curlybars.rb CHANGED
@@ -84,12 +84,22 @@ module Curlybars
84
84
  # target_path - The path String to search for (e.g., "user.name" or "user.organizations.id").
85
85
  # source - The source HBS String used to generate an AST.
86
86
  # identifier - The the file name of the template being checked (defaults to `nil`).
87
+ # role - Optional Symbol or Array of Symbols to filter by syntactic role:
88
+ # :output - bare output value {{title}}
89
+ # :helper - helper name {{truncate …}}, {{#block …}}
90
+ # :argument - positional argument {{truncate title}}, (math score)
91
+ # :option - keyword option value key=title
92
+ # :condition - #if / #unless expression {{#if visible}}
93
+ # :collection - #each collection path {{#each posts}}
94
+ # :scope - #with scope path {{#with author}}
95
+ # :partial - partial name {{> header}}
96
+ # When nil (default), all roles match (backward compatible).
87
97
  #
88
98
  # Returns an Array of Curlybars::Node::Path instances that match the target path.
89
- def find(target_path, source, identifier = nil)
99
+ def find(target_path, source, identifier = nil, role: nil)
90
100
  tree = ast(transformed_source(source), identifier, run_processors: true)
91
101
  finder = Curlybars::PathFinder.new(tree)
92
- finder.find(target_path)
102
+ finder.find(target_path, role: role)
93
103
  end
94
104
 
95
105
  def global_helpers_dependency_tree
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curlybars
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.0
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Libo Cannici