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 +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
|