renshi 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README +9 -11
- data/lib/renshi/parser.rb +26 -17
- data/lib/renshi.rb +1 -1
- data/spec/parser_spec.rb +26 -0
- metadata +2 -2
data/README
CHANGED
@@ -1,36 +1,34 @@
|
|
1
|
-
Renshi is a templating language for Ruby which is unobtrusive in HTML and XHTML structures. It
|
1
|
+
Renshi is a templating language for Ruby which is unobtrusive in HTML and XHTML structures. It has a conciser syntax than ERB and an 'attribute expression' library which lets you build and combine sets of inline Ruby instructions upon HTML elements.
|
2
2
|
|
3
3
|
Renshi templates are appended with the suffix of .ren, e.g. index.html.ren or index.ren
|
4
4
|
|
5
|
+
Renshi was designed to give the Ruby dev. flexibility when creating templates; the use of attribute expressions creates well-formed XHTML, $ interpretation can be used however the dev. wishes.
|
6
|
+
|
5
7
|
$ Ruby Insertion
|
6
8
|
================
|
7
|
-
|
9
|
+
Very much like ERB.
|
8
10
|
|
9
|
-
$
|
11
|
+
Use $ or ${..} where you would use <%= ... %> . The single $ is used for one word phrases.
|
10
12
|
|
11
|
-
|
13
|
+
$foo[0], $1+1, $Time.now - ERB equiv. <%= foo[0] %>, <%= 1+1 %>, <%= Time.now %>
|
12
14
|
|
13
15
|
${some_function "takes this string as input"} (ERB equiv. - <%= some_function "takes this string as input" %>)
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
$[foo = "hello world"]
|
17
|
+
Use $[] instead of <% ... -%>
|
18
18
|
|
19
19
|
$[if foo]
|
20
20
|
$foo
|
21
21
|
$[end]
|
22
22
|
|
23
|
-
(The ERB equiv. should be obvious by now.)
|
24
|
-
|
25
23
|
Attribute Expressions
|
26
24
|
===================
|
27
25
|
Renshi has 'attribute expressions', which may be inserted into HTML elements as attributes.
|
28
26
|
|
29
|
-
Attribute expressions can be combined on elements and are interpreted in the order of appearance and are cumulative, allowing you to
|
27
|
+
Attribute expressions can be combined on elements and are interpreted in the order of appearance and are cumulative, allowing you to program inline on the HTML structure (the element and everything within it).
|
30
28
|
|
31
29
|
For e.g.
|
32
30
|
<ul>
|
33
|
-
<li r:for="section in @section.sections" r:if="authorized?(current_user, section)
|
31
|
+
<li r:for="section in @section.sections" r:if="authorized?(current_user, section)" id="section_$section.name">$section.name
|
34
32
|
<ul>
|
35
33
|
<li r:for="page in section.pages">${link_to page.name, "#{page.path}"}</li>
|
36
34
|
</ul>
|
data/lib/renshi/parser.rb
CHANGED
@@ -5,13 +5,13 @@ module Renshi
|
|
5
5
|
# the document, which are finally compiled into Ruby.
|
6
6
|
|
7
7
|
class Parser
|
8
|
-
STRING_END = "
|
9
|
-
STRING_START = "
|
8
|
+
STRING_END = "_R_END" #maybe replace this with a funky unicode char
|
9
|
+
STRING_START = "_R_START" #maybe replace this with a funky unicode char
|
10
10
|
BUFFER_CONCAT_OPEN = "@output_buffer.concat(\""
|
11
11
|
BUFFER_CONCAT_CLOSE = "\");"
|
12
12
|
NEW_LINE = "@output_buffer.concat('\n');"
|
13
|
-
INSTRUCTION_START = "
|
14
|
-
INSTRUCTION_END = "
|
13
|
+
INSTRUCTION_START = "_R_INSTR_IDX_START_"
|
14
|
+
INSTRUCTION_END = "_R_INSTR_IDX_END_"
|
15
15
|
|
16
16
|
#these symbols cannot be normally escaped, as we need to differentiate between < as an
|
17
17
|
#escaped string, to be left in the document, and < as a boolean operator
|
@@ -45,7 +45,6 @@ module Renshi
|
|
45
45
|
|
46
46
|
inner_html = @doc.inner_html
|
47
47
|
compiled = compile_to_buffer(inner_html) if inner_html
|
48
|
-
# puts "\n", compiled, "\n"
|
49
48
|
return compiled
|
50
49
|
end
|
51
50
|
|
@@ -62,7 +61,8 @@ module Renshi
|
|
62
61
|
for attribute in node.attributes()
|
63
62
|
compiled = compile(attribute[1].to_s)
|
64
63
|
if compiled
|
65
|
-
|
64
|
+
key = store_instruction_for_buffer(compiled)
|
65
|
+
node[attribute[0]]= key
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -71,11 +71,7 @@ module Renshi
|
|
71
71
|
if node.text?
|
72
72
|
compiled = compile(node.text)
|
73
73
|
if compiled
|
74
|
-
|
75
|
-
key = "#{INSTRUCTION_START}#{@instr_idx}#{INSTRUCTION_END}"
|
76
|
-
@instr_idx = @instr_idx + 1
|
77
|
-
# node.content = compiled if compiled
|
78
|
-
node.content = key
|
74
|
+
node.content = store_instruction_for_buffer(compiled)
|
79
75
|
end
|
80
76
|
end
|
81
77
|
|
@@ -83,12 +79,23 @@ module Renshi
|
|
83
79
|
end
|
84
80
|
|
85
81
|
|
82
|
+
def store_instruction_for_buffer(compiled)
|
83
|
+
@instructions << compiled
|
84
|
+
key = "#{INSTRUCTION_START}#{@instr_idx}#{INSTRUCTION_END}"
|
85
|
+
@instr_idx = @instr_idx + 1
|
86
|
+
return key
|
87
|
+
end
|
88
|
+
|
86
89
|
def compile(text)
|
87
90
|
idx = text.index("$")
|
88
91
|
return text if idx.nil?
|
89
92
|
|
90
93
|
bits = []
|
91
|
-
|
94
|
+
|
95
|
+
if idx != 0
|
96
|
+
before_str = text[0..(idx -1)]
|
97
|
+
bits << escape_quot_mark(before_str)
|
98
|
+
end
|
92
99
|
|
93
100
|
while idx != nil do
|
94
101
|
next_char = text[(idx + 1)..(idx + 1)]
|
@@ -132,7 +139,7 @@ module Renshi
|
|
132
139
|
else #$foo
|
133
140
|
|
134
141
|
#divide with a delimiter for anything which is not a name character - alpa-numeric and underscore
|
135
|
-
words = text[(idx +1)..-1].split(/[^\w."'{}()+=*\/\-@\[\]]/)
|
142
|
+
words = text[(idx +1)..-1].split(/[^\w."'{}()+=*\/\-@\[\]:]/)
|
136
143
|
words[0] = "'$'" if words[0] == "$"
|
137
144
|
statement_str = words.first
|
138
145
|
statement = Statement.new(statement_str)
|
@@ -144,16 +151,14 @@ module Renshi
|
|
144
151
|
|
145
152
|
if next_statement_idx
|
146
153
|
gap = text[end_statement_idx..(next_statement_idx -1)]
|
147
|
-
bits << gap
|
154
|
+
bits << escape_quot_mark(gap)
|
148
155
|
else
|
149
|
-
bits << text[end_statement_idx..-1]
|
156
|
+
bits << escape_quot_mark(text[end_statement_idx..-1])
|
150
157
|
end
|
151
158
|
idx = next_statement_idx
|
152
159
|
end
|
153
|
-
|
154
160
|
return bits.join
|
155
161
|
end
|
156
|
-
|
157
162
|
|
158
163
|
def close_of_phrase_ending_with(char, text, idx)
|
159
164
|
phrase_end = (text[(idx + 1)..-1].index("$"))
|
@@ -167,6 +172,10 @@ module Renshi
|
|
167
172
|
return closing_brace_idx
|
168
173
|
end
|
169
174
|
|
175
|
+
def escape_quot_mark(str)
|
176
|
+
return (str == '"' ? '\"' : str)
|
177
|
+
end
|
178
|
+
|
170
179
|
def compile_to_buffer(str)
|
171
180
|
compiled = "@output_buffer ='';" << BUFFER_CONCAT_OPEN
|
172
181
|
str = compile_print_flags(str)
|
data/lib/renshi.rb
CHANGED
data/spec/parser_spec.rb
CHANGED
@@ -155,4 +155,30 @@ end
|
|
155
155
|
|
156
156
|
html.should eql "hello world"
|
157
157
|
end
|
158
|
+
|
159
|
+
|
160
|
+
it "should interpret \"${@foo}\" " do
|
161
|
+
raw = Renshi::Parser.parse(%Q!"${@foo}"!)
|
162
|
+
puts raw
|
163
|
+
@foo = "hello world"
|
164
|
+
html = eval(raw, binding)
|
165
|
+
|
166
|
+
html.should eql %Q!"hello world"!
|
167
|
+
end
|
168
|
+
|
169
|
+
class R
|
170
|
+
attr_accessor :path
|
171
|
+
|
172
|
+
def initialize
|
173
|
+
@path = "/hello/world"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should interpret <a href='{$r.path}'>hello</a>" do
|
178
|
+
r = R.new
|
179
|
+
raw = Renshi::Parser.parse(%Q!<a href="${r.path}">hello</a>!)
|
180
|
+
html = eval(raw, binding)
|
181
|
+
|
182
|
+
html.should eql "<a href=\"#{r.path}\">hello</a>"
|
183
|
+
end
|
158
184
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: renshi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Faiz
|
@@ -9,7 +9,7 @@ autorequire: renshi
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-25 00:00:00 +10:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|