erbse 0.1.0 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: df7ee95b6879b5591ad8cd4ee86fd374ac12e66d
4
- data.tar.gz: a4c1100201726eebaada8b091c763d1b1925892c
3
+ metadata.gz: deb5a744396c2f7901a545c6c2ae480eb6e7893e
4
+ data.tar.gz: 3738953bcabb49eb00ccd3db0a1feb99e39d63ac
5
5
  SHA512:
6
- metadata.gz: 999650c0c6f0e0ac13d597874b10f62010ae573f04a51964f50a43543808c58b6b1a53456d4f931a6d0cfe41f6272cb22c8cd225e21913edb961a795585663d7
7
- data.tar.gz: 42fb43d4d2de42d32c97e9e752175c1170395a9361be975c6ca59c65f5c6298055aea1430f421b755d850effd776b4c85c809b6c4d7b81af46d63f1f981114be
6
+ metadata.gz: bdf4146a9703c7b3d1254fa3ad865bb3391a3a97b083c1a7424462c02fa470d469a743053b50ce43eccdd51525403ad5e539c0a0dbcb5bdb41486c3893a4ef5a
7
+ data.tar.gz: a4842875cae85c733a006931a84a55e5b7363a53ca62aade95c35c470c2eb07bf1356dcb3b4dd035c8b4a124cf1ee7272b0e7749cbce2b6b9d7c4beb5f0d7728
data/CHANGES.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.1.1
2
+
3
+ * Introduce the `<%@ %>` tag. This is a built-in capture mechanism. It will assign all block content to a local variable but *not* output it.
4
+ * Make comments be recognized before `end`, which fixes a syntax error with `<%# end %>`.
5
+ * Don't recognize ERB tags with a string containing "do" as a block.
6
+
1
7
  # 0.1.0
2
8
 
3
9
  * Internally, we're parsing the ERB template into a SEXP structure and let [Temple](https://github.com/judofyr/temple) compile it to Ruby. Many thanks to the Temple team! 😘
data/README.md CHANGED
@@ -14,6 +14,19 @@ Erbse::Engine.new.call("<% ... %>") #=> string of compiled ruby.
14
14
 
15
15
  The returned string can then be `eval`uated in a certain context.
16
16
 
17
+ ## Output Buffers
18
+
19
+ Erbse does not use instance variables as output buffer, only local variables.
20
+
21
+ | Tag | Behavior |
22
+ | --- | --- |
23
+ | `<% %>` | Executes the code but does not output anything. |
24
+ | `<% .. do %>` | Executes the code but does not output anything. In the block, output is written to the current buffer. |
25
+ | `<%= %>` | Executes the code, outputs to current buffer. |
26
+ | `<%= .. do %>` | Executes the code and appends returned value to the current buffer. In the block, output is written to a new buffer that is returned when `yield`ing. |
27
+ | `<%@ .. do %>` | Executes the code but does not output anything. In the block, output is written to a new buffer that is returned when `yield`ing. |
28
+
29
+
17
30
  ## Block Yielding
18
31
 
19
32
  Erbse supports blocks à la Rails.
@@ -42,12 +55,36 @@ Usually, returning the content from the helper will be sufficient.
42
55
 
43
56
  However, you can totally pass that block to a completely different object and yield it there. Since there's no global state as in ERB, this will work.
44
57
 
58
+ ## Capture
59
+
60
+ With the `<%= helper do %>` tag, block content is assigned to a new output buffer and the result of `helper` rendered.
61
+
62
+ To capture the block without outputting anything, use the `<%@ %>` tag. This will still use a new output buffer for the block, but not output anything.
63
+
64
+ ```erb
65
+ <%@ content = capture do %>
66
+ Whatever
67
+ <% end %>
68
+
69
+ <%= content %>
70
+ ```
71
+
72
+ The `capture` method will receive a block, what you do with it is up to you. It would usually simply yield the block.
73
+
74
+ ```ruby
75
+ def capture(&block)
76
+ yield
77
+ end
78
+ ```
79
+
45
80
  ## Removed Features
46
81
 
47
- Erbse does *not* support any tags other than `<% %>` and `<%= %>`. Tags such as `<%% %>`, `<%== %>`, `<%- %>` or `<% -%>` will be reduced to the supported tags.
82
+ Erbse does *not* support any tags other than `<% %>`, `<%= %>` and `<%@ %>`. Tags such as `<%% %>`, `<%== %>`, `<%- %>` or `<% -%>` will be reduced to the supported tags.
48
83
 
49
84
  ## TODO
50
85
 
86
+ The parser code got drastically reduced and might be missing essential features. [Please report](https://github.com/apotonick/erbse/issues) compiled syntax errors.
87
+
51
88
  * Block comments
52
89
  * Add newlines in compiled Ruby.
53
90
 
@@ -12,11 +12,21 @@ module Erbse
12
12
  # this still needs the Temple::Filters::ControlFlow run-through.
13
13
  [:multi,
14
14
  [:block, "#{outter_i} = #{code}",
15
- [:capture, inner_i, compile(content_ast)] # compile() is recursion on nested block content.
15
+ [:capture, inner_i, compile(content_ast)]
16
16
  ],
17
17
  [:dynamic, outter_i] # return the outter buffer. # DISCUSS: why do we need that, again?
18
18
  ]
19
19
  end
20
+
21
+ # assign all code in the block to new local output buffer without outputting it.
22
+ # handles <%@ do %>
23
+ def on_capture_block(code, content_ast)
24
+ [:multi,
25
+ [:block, code, # var = capture do
26
+ [:capture, unique_name, compile(content_ast)]
27
+ ]
28
+ ]
29
+ end
20
30
  end
21
31
 
22
32
  class Engine < Temple::Engine
@@ -1,9 +1,14 @@
1
1
  module Erbse
2
2
  class Parser
3
3
  # ERB_EXPR = /<%(=|\#)?(.*?)%>(\n)*/m # this is the desired pattern.
4
- ERB_EXPR = /<%(=+|-|\#|%)?(.*?)[-=]?%>(\n)*/m # this is for backward-compatibility.
4
+ ERB_EXPR = /<%(=+|-|\#|@|%)?(.*?)[-=]?%>(\n)*/m # this is for backward-compatibility.
5
5
  # BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
6
- BLOCK_EXPR = /\b(if|unless)\b|\bdo\b/
6
+ BLOCK_EXPR = /\b(if|unless)\b|\sdo\s*$|\sdo\s+\|/
7
+
8
+ # Parsing patterns
9
+ #
10
+ # Blocks will be recognized when written:
11
+ # <% ... do %> or <% ... do |...| %>
7
12
 
8
13
  def initialize(*)
9
14
  end
@@ -34,11 +39,14 @@ module Erbse
34
39
  else
35
40
  buffers.last << [:dynamic, code]
36
41
  end
37
- elsif code =~ /\bend\b/ # <% end %>
38
- buffers.pop
39
42
  elsif ch =~ /#/ # DISCUSS: doesn't catch <% # this %>
40
43
  newlines = code.count("\n")
41
44
  buffers.last.concat [[:newline]] * newlines if newlines > 0
45
+ elsif code =~ /\bend\b/ # <% end %>
46
+ buffers.pop
47
+ elsif ch == ?@
48
+ buffers.last << [:capture, :block, code, block = [:multi]] # picked up by our own BlockFilter. # TODO: merge with %= ?
49
+ buffers << block
42
50
  else # <% %>
43
51
  if code =~ BLOCK_EXPR
44
52
  buffers.last << [:block, code, block = [:multi]] # picked up by Temple's ControlFlow filter.
@@ -1,3 +1,3 @@
1
1
  module Erbse
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -99,6 +99,12 @@ Hi
99
99
  code = %{_buf = []; _buf << ("Hello@@".freeze); @; _buf << ("Hola@@".freeze); @; @; _buf << ("Hi@@".freeze); # this ; @; _buf = _buf.join("".freeze)}
100
100
  ruby.must_equal code
101
101
  end
102
+
103
+ # <%# end %>
104
+ it { Erbse::Parser.new.(%{Yo
105
+ <%# bla do %>
106
+ <%# end %>
107
+ 1}).must_equal [:multi, [:static, "Yo\n"], [:newline], [:newline], [:static, "1"]] }
102
108
  end
103
109
 
104
110
  describe "content after last ERB tag" do
@@ -113,4 +119,32 @@ blubb</b>} }
113
119
  it { Erbse::Parser.new.(%{<%% 1 %>}).must_equal [:multi, [:code, " 1 "]] }
114
120
  it { Erbse::Parser.new.(%{<%% 1 -%>}).must_equal [:multi, [:code, " 1 "]] }
115
121
  end
122
+
123
+ describe "<% var = 1 %>" do
124
+ let (:str) { %{<% var = 1 %><%= var %>} }
125
+ it { eval(Erbse::Engine.new.(str)).must_equal "1" }
126
+ end
127
+
128
+ describe "<% \"string with do\" %>" do
129
+ it { Erbse::Parser.new.(%{<% var = "do 1" %><%= var %>}).must_equal [:multi, [:code, " var = \"do 1\" "], [:dynamic, " var "]] }
130
+ it { Erbse::Parser.new.(%{<% var = " do 1" %><%= var %>}).must_equal [:multi, [:code, " var = \" do 1\" "], [:dynamic, " var "]] }
131
+ end
132
+
133
+ describe "do" do
134
+ it { Erbse::Parser.new.(%{<% form do %>1<% end %>}).must_equal [:multi, [:block, " form do ", [:multi, [:static, "1"]]]] }
135
+ it { Erbse::Parser.new.(%{<% form do |i| %>1<% end %>}).must_equal [:multi, [:block, " form do |i| ", [:multi, [:static, "1"]]]] }
136
+ end
137
+
138
+ describe "capture" do
139
+ let (:str) { %{<%@ content = capture do %>
140
+ Yo!
141
+ <%= 1 %>
142
+ <% end %>} }
143
+
144
+ it do
145
+ ruby = Erbse::Engine.new.(str).gsub("\n", "@").gsub('\n', "@@")
146
+ code = %{_buf = []; content = capture do ; _erbse_blockfilter1 = ''; @; _erbse_blockfilter1 << (\" Yo!@@ \".freeze); _erbse_blockfilter1 << (( 1 ).to_s); @; _erbse_blockfilter1; end; _buf = _buf.join(\"\".freeze)}
147
+ ruby.must_equal code
148
+ end
149
+ end
116
150
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erbse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-05 00:00:00.000000000 Z
11
+ date: 2016-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: temple