express_templates 0.3.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16e00189a36058717818d7a7c66638c0164fcef6
4
- data.tar.gz: 559bf6b66e66bf2caacd9c7594a9227ed2208cee
3
+ metadata.gz: fa578b4bff63a2306c2281d561cf315fa245230c
4
+ data.tar.gz: e717b4ddb4f8d244ed21cd48a39c4613c98f3738
5
5
  SHA512:
6
- metadata.gz: bfbbac386e1b3db30466f8517dc7c9a82f65ebce01c548357ba2754399f3808ef9601eb157cc78775fc67f571930f06dfc4da57ed7ee57e267b5624ad9a82b83
7
- data.tar.gz: 20b4d748cb8780f9366ae4875f1795af827ce0db5b59c128d096a5cb47de38d7639bb90d55d53183ce4df2349341d68d52e6084f328e510090cc899ae706fb07
6
+ metadata.gz: 76620daed87fdd884e9ea2089858c76d7fb1bac437af8c8983bea28c904b718f98f63cab711ce41762d40a59e709eced84744a17431d6d56076c0fc45ae39337
7
+ data.tar.gz: f5f198c833e6afbb2dd92eda33deb1fe81f384947ccf5972f4dc11825d675a30e84105bfa010a978729ea15f8bda89e5161684309fbb087f26e8d3ce17b31016
@@ -15,8 +15,8 @@ module ExpressTemplates
15
15
  Thread.current[:first_whitepace_removed] = nil if Thread.current[:first_whitepace_removed].eql?(0)
16
16
  end
17
17
 
18
- return compiled.join("+").gsub('"+"', '').tap do |s|
19
- puts("\n"+template.inspect+"\n"+s) if ENV['DEBUG'].eql?('true')
18
+ return Interpolator.transform(compiled.join("+").gsub('"+"', '')).tap do |s|
19
+ puts("\n"+template.inspect+"\nSource:\n#{template.try(:source)}\nInterpolated:\n#{s}\n") if ENV['DEBUG'].eql?('true')
20
20
  end
21
21
  end
22
22
 
@@ -54,7 +54,7 @@ module ExpressTemplates
54
54
  Indenter.for(:compile) do |indent, indent_with_newline|
55
55
  compiled_children = children.map do |child|
56
56
  indent_with_newline +
57
- (child.compile rescue %Q("#{child}")) # Bare strings may be children
57
+ (child.respond_to?(:compile) ? child.compile : child.inspect) # Bare strings may be children
58
58
  end.join("+\n")
59
59
  compiled_children.gsub!('"+"', '') # avoid unnecessary string concatenation
60
60
  end
@@ -136,7 +136,7 @@ module ExpressTemplates
136
136
  define_method(:#{name}) do |*args|
137
137
  helper_args = %w(self)
138
138
  helper_args += args.map(&:inspect)
139
- '\#\{#{self.to_s}._#{name}('+_interpolate(helper_args).join(', ')+')\}'
139
+ '{{#{self.to_s}._#{name}('+_interpolate(helper_args).join(', ')+')}}'
140
140
  end
141
141
 
142
142
  # called during rendering in view context
@@ -15,21 +15,23 @@ module ExpressTemplates
15
15
  def compile
16
16
  children_markup = compile_children
17
17
  content_label = @args[0]
18
- result = %Q|content_for(:#{content_label}|
18
+ result = %Q|\ncontent_for(:#{content_label}|
19
19
  if children_markup.empty?
20
20
  if @args[1].kind_of?(String)
21
21
  children_markup = @args[1]
22
22
  # append children as argument
23
- result << %Q|, "#{children_markup}".html_safe)|
23
+ result << %Q|, "#{children_markup}".html_safe).to_s|
24
24
  else
25
25
  # no markup specified - must be referencing the content
26
- result << ")"
26
+ result << ").to_s"
27
27
  end
28
28
  else
29
29
  # append children in block form
30
- result << %Q|) { (#{children_markup.gsub(/^\s+/, '')}).html_safe }|
30
+ result << %Q|) {
31
+ (#{children_markup.gsub(/^\s+/, '')}).html_safe
32
+ }.to_s|
31
33
  end
32
- %Q("\#\{#{result}\}")
34
+ result
33
35
  end
34
36
  end
35
37
  end
@@ -0,0 +1,36 @@
1
+ require 'parslet'
2
+
3
+ module ExpressTemplates
4
+ class Interpolator < Parslet::Parser
5
+ rule(:lbrace) { str('{{') }
6
+ rule(:rbrace) { str('}}') }
7
+ rule(:delim) { lbrace | rbrace }
8
+ rule(:lpart) { (lbrace.absnt? >> any).repeat.as(:lpart) }
9
+ rule(:rpart) { (rbrace.absnt? >> any).repeat.as(:rpart) }
10
+ rule(:expression) { (text_with_interpolations).as(:expression) }
11
+ rule(:interpolation) { (lbrace>>expression>>rbrace).as(:interpolation) }
12
+ rule(:text) { (delim.absnt? >> any).repeat(1) }
13
+ rule(:text_with_interpolations) { (text.as(:text) | interpolation).repeat }
14
+ root(:text_with_interpolations)
15
+
16
+ def self.transform(s)
17
+ begin
18
+ Transformer.new.apply(new.parse(s)).flatten.join
19
+ rescue Parslet::ParseFailed => failure
20
+ puts s
21
+ puts failure.cause.ascii_tree
22
+ raise failure
23
+ end
24
+ end
25
+ end
26
+
27
+ class Transformer < Parslet::Transform
28
+ rule(:interpolation => simple(:expression)) {
29
+ '#{'+expression+'}'
30
+ }
31
+ rule(:expression => sequence(:exp)) do
32
+ exp.map(&:to_s).join.gsub('\\"', '"')
33
+ end
34
+ rule(:text => simple(:s)) { s.to_s }
35
+ end
36
+ end
@@ -24,8 +24,6 @@ module ExpressTemplates
24
24
  value.each_pair.map {|k,v| %Q(data-#{k}=\\"#{v}\\") }.join(" ")
25
25
  when value.kind_of?(Proc)
26
26
  %Q(#{name}=\\"\#{(#{value.source}).call}\\")
27
- when code = value.to_s.match(/^\{\{(.*)\}\}$/).try(:[], 1)
28
- %Q(#{name}=\\"\#{#{code}}\\")
29
27
  else
30
28
  %Q(#{name}=\\"#{value}\\")
31
29
  end
@@ -73,11 +71,7 @@ module ExpressTemplates
73
71
  if child.respond_to?(:compile)
74
72
  child.compile
75
73
  else
76
- if code = child.to_s.match(/\{\{(.*)\}\}/).try(:[], 1)
77
- %Q("\#\{#{code}\}")
78
- else
79
- %Q("#{child}")
80
- end
74
+ %Q("#{child}")
81
75
  end
82
76
  end
83
77
  unless ruby_fragments.empty?
@@ -13,7 +13,7 @@ module ExpressTemplates
13
13
 
14
14
  def compile
15
15
  # insure nils do not blow up view
16
- %Q("\#\{#{_compile}\}")
16
+ %Q(%Q({{#{_compile}}}))
17
17
  end
18
18
 
19
19
  def to_template
@@ -29,12 +29,24 @@ module ExpressTemplates
29
29
  string = "#{name}"
30
30
 
31
31
  if !@args.empty?
32
- args_string = args.slice(0..-2).map(&:inspect).map(&:_remove_double_braces).join(', ')
32
+
33
+ args_string = args.slice(0..-2).map do |arg|
34
+ if arg.respond_to?(:gsub) && arg.match(/^\{\{(.*)\}\}$/)
35
+ # strip double braces because otherwise these will be converted
36
+ # to "#{arg}" during final interpolation which is generally not
37
+ # the intention for arguments to helpers as these are ruby expressions
38
+ # not necessarily returning strings
39
+ $1
40
+ else
41
+ arg.inspect # 'value' or :value or ['a', 'b', 'c'] or {:key => 'value'}
42
+ end
43
+ end.join(', ')
44
+
33
45
  last_arg = ''
34
46
  if args.last.is_a?(Hash) # expand a hash
35
47
  last_arg = _convert_hash_to_argument_string(args.last)
36
48
  else
37
- last_arg = args.last.inspect._remove_double_braces
49
+ last_arg = args.last.inspect
38
50
  end
39
51
  args_string << (args_string.empty? ? last_arg : ", #{last_arg}")
40
52
  string << "(#{args_string})"
@@ -80,9 +92,3 @@ module ExpressTemplates
80
92
  end
81
93
  end
82
94
  end
83
-
84
- class String
85
- def _remove_double_braces
86
- match(/\{\{(.*)\}\}/).try(:[], 1) || self
87
- end
88
- end
@@ -1,3 +1,3 @@
1
1
  module ExpressTemplates
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -8,6 +8,7 @@ module ExpressTemplates
8
8
  require 'express_templates/renderer'
9
9
  require 'express_templates/expander'
10
10
  require 'express_templates/compiler'
11
+ require 'express_templates/interpolator'
11
12
  extend Renderer
12
13
  extend Compiler
13
14
  if defined?(Rails)
@@ -38,7 +38,7 @@ class BaseTest < ActiveSupport::TestCase
38
38
 
39
39
  test "helpers defined in component are evaluated in context" do
40
40
  compiled = Helpers.new.compile
41
- assert_equal "<h1>bar</h1>", Context.new.instance_eval(compiled)
41
+ assert_equal "<h1>bar</h1>", Context.new.instance_eval(Interpolator.transform(compiled))
42
42
  end
43
43
 
44
44
  end
@@ -30,7 +30,7 @@ class ConditionalityTest < ActiveSupport::TestCase
30
30
  end
31
31
 
32
32
  test "when supplied condition is true, renders the component" do
33
- compiled_src = ConditionalRenderer.new.compile
33
+ compiled_src = Interpolator.transform(ConditionalRenderer.new.compile)
34
34
  assert_equal '<h1>Something</h1>', present_title_context.instance_eval(compiled_src)
35
35
  end
36
36
 
@@ -17,13 +17,14 @@ class IteratingTest < ActiveSupport::TestCase
17
17
  test "#for_each expands to view logic" do
18
18
  compiled = ForEachLogic.new.compile
19
19
  assert_equal %q((@things.each_with_index.map do |thing, thing_index|
20
- "<span>#{thing}</span>"
21
- end).join), compiled
20
+ "<span>"+%Q(#{thing})+"</span>"
21
+ end).join), Interpolator.transform(compiled)
22
22
  end
23
23
 
24
24
  test "#for_each iterates markup for each value" do
25
25
  compiled = ForEachLogic.new.compile
26
- assert_equal '<span>bar</span><span>baz</span>', Context.new.instance_eval(compiled)
26
+ assert_equal '<span>bar</span><span>baz</span>',
27
+ Context.new.instance_eval(Interpolator.transform(compiled))
27
28
  end
28
29
 
29
30
  class ForEachDeclarativeForm < ECB
@@ -36,7 +37,8 @@ end).join), compiled
36
37
 
37
38
  test ".for_each offers declarative form" do
38
39
  compiled = ForEachLogic.new.compile
39
- assert_equal '<span>bar</span><span>baz</span>', Context.new.instance_eval(compiled)
40
+ assert_equal '<span>bar</span><span>baz</span>',
41
+ Context.new.instance_eval(Interpolator.transform(compiled))
40
42
  end
41
43
 
42
44
 
@@ -60,7 +62,8 @@ end).join), compiled
60
62
 
61
63
  test ".wrap_with wraps via _yield special handler" do
62
64
  compiled = MultiFragments.new.compile
63
- assert_equal "<ul><li>bar</li><li>baz</li></ul>", Context.new.instance_eval(compiled)
65
+ assert_equal "<ul><li>bar</li><li>baz</li></ul>",
66
+ Context.new.instance_eval(Interpolator.transform(compiled))
64
67
  end
65
68
 
66
69
  class EmptyState < ECB