erbse 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +6 -0
- data/README.md +38 -1
- data/lib/erbse.rb +11 -1
- data/lib/erbse/parser.rb +12 -4
- data/lib/erbse/version.rb +1 -1
- data/test/erbse_test.rb +34 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: deb5a744396c2f7901a545c6c2ae480eb6e7893e
|
4
|
+
data.tar.gz: 3738953bcabb49eb00ccd3db0a1feb99e39d63ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
|
data/lib/erbse.rb
CHANGED
@@ -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)]
|
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
|
data/lib/erbse/parser.rb
CHANGED
@@ -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 = /<%(
|
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|\
|
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.
|
data/lib/erbse/version.rb
CHANGED
data/test/erbse_test.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2016-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: temple
|