renshi 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -20,23 +20,33 @@ $foo
20
20
  Attribute Expressions
21
21
  ===================
22
22
  Renshi has a small library of expressions which can be inserted into HTML or XML elements as attributes.
23
- Attribute expressions follow the form of
23
+ Attribute expressions generally follow the form of
24
24
 
25
25
  r:expression_name="expression" - the expression value is treated as a Ruby expression .
26
26
 
27
+ Some expressions, such as r:each, use the quoted value to also hold parameter information.
28
+
27
29
  * Current Attribute Expressions
28
- * If
29
- * Elsif
30
+ * If
31
+ * Unless
32
+ * Elsif
30
33
  * Else
31
34
  * While
32
35
  * For
33
-
36
+ * Each
34
37
 
35
38
  * If
36
- <span r:if="true">hello!</span> would render "<span>hello</span>"
39
+ <span r:if="true">hello</span>
40
+ would render "<span>hello</span>"
37
41
 
38
42
  <span r:if="false">goodbye!</span> will render "".
39
43
 
44
+ * Unless
45
+ <span r:unless="false">hello</span>
46
+ would render "<span>hello</span>"
47
+
48
+ <span r:unless="true">goodbye!</span> will render "".
49
+
40
50
  * Elsif
41
51
 
42
52
  <span r:if="false">hello!</span>
@@ -109,22 +119,32 @@ renders:
109
119
 
110
120
  <div id="content0">
111
121
  hello0
112
- </div><div id="content1">
113
- hello1
114
- </div><div id="content2">
115
- hello2
122
+ </div>
123
+ ...etc
124
+ <div id="content99">
125
+ hello99
126
+ </div>
127
+
128
+ * Each
129
+ <div id="content$foo" r:each="foos, |foo|">
130
+ hello$foo
116
131
  </div>
117
132
 
133
+ <div id="content0">
134
+ hello0
135
+ </div>
136
+ ...etc
137
+ <div id="content99">
138
+ hello99
139
+ </div>
140
+
141
+
118
142
  Further elements will appear as I have time to make them or others want to contribute them. There isn't much to making them.
119
143
 
120
144
  See renshi/lib/renshi/attribute_expressions for how they work.
121
145
 
122
146
  Planned element expressions:
123
147
 
124
- * r:each
125
- * r:unless
126
- * r:def - something like genshi's py:def
127
-
128
148
  Other Rules
129
149
  ===========
130
150
  $ values inside of attributes are only interpreted as Renshi variables for regular attributes (not renshi attributes).
@@ -152,12 +172,9 @@ There is a Rails 2.3.2 example app in the examples directory. Go there, start up
152
172
  I'd welcome integrations for Sinatra and Merb or XYZ framework. See renshi/lib/renshi/frameworks
153
173
 
154
174
 
155
- Gem Building
175
+ Installation
156
176
  ============
157
- run
158
- `rake gem`
159
- then
160
- `sudo gem install pkg/renshi-0.0.2.gem`
177
+ Renshi is hosted on Rubyforge so 'sudo gem install renshi'. Alternatively, use github to do what you want with it.
161
178
 
162
179
 
163
180
  Development
@@ -173,7 +190,7 @@ Firstly, it doesn't need a reason. It's a fun project.
173
190
  But ...
174
191
 
175
192
  I've always found ERB to be a bit cumbersome - <%= is quite tiring to type out when you realise it could be much shorter. I used to think that Velocity, in Java,
176
- was the most fun templating language I'd used, and I had wanted something equally as concise for Ruby.
193
+ was the funnest templating language I'd used, and I had wanted something equally as concise for Ruby.
177
194
 
178
195
  A real need for it emerged in a project which relied upon an external design house handing us HTML. Converting it incessantly into HAML was nightmarish. A colleague
179
196
  mentioned Genshi in Python as ideal, which was when the idea of Renshi was conceived.
@@ -0,0 +1,11 @@
1
+ module Renshi
2
+ module AttributeExpressions
3
+ class Each
4
+ def evaluate(expression, node)
5
+ bits = expression.split(",")
6
+ node.open_clause("#{bits[0]}.each do #{bits[1]}")
7
+ node.close_clause("end")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,10 +1,10 @@
1
1
  module Renshi
2
2
  module AttributeExpressions
3
3
  class Else
4
+
4
5
  def evaluate(expression, node)
5
6
  node.open_clause("else")
6
7
  node.close_clause("end")
7
- node.remove_attribute("r:else")
8
8
  end
9
9
  end
10
10
  end
@@ -1,6 +1,6 @@
1
1
  module Renshi
2
2
  module AttributeExpressions
3
- class Elsif
3
+ class Elsif
4
4
  def evaluate(expression, node)
5
5
  node.open_clause("elsif (#{expression})")
6
6
 
@@ -12,14 +12,12 @@ module Renshi
12
12
  if sibling_commands.first
13
13
  expression = sibling_commands.first[0][2..-1]
14
14
  if expression == "else"
15
- node.remove_attribute("r:elsif")
16
15
  return
17
16
  end
18
17
  end
19
18
  end
20
19
 
21
20
  node.close_clause("end")
22
- node.remove_attribute("r:elsif")
23
21
  end
24
22
  end
25
23
  end
@@ -1,10 +1,10 @@
1
1
  module Renshi
2
2
  module AttributeExpressions
3
3
  class For
4
+
4
5
  def evaluate(expression, node)
5
6
  node.open_clause("for #{expression}")
6
7
  node.close_clause("end")
7
- node.remove_attribute("r:for")
8
8
  end
9
9
  end
10
10
  end
@@ -1,6 +1,6 @@
1
1
  module Renshi
2
2
  module AttributeExpressions
3
- class If
3
+ class If
4
4
  def evaluate(expression, node)
5
5
  node.open_clause("if (#{expression})")
6
6
 
@@ -12,14 +12,12 @@ module Renshi
12
12
  if sibling_commands.first
13
13
  expression = sibling_commands.first[0][2..-1]
14
14
  if expression == "else" or expression == "elsif"
15
- node.remove_attribute("r:if")
16
15
  return
17
16
  end
18
17
  end
19
18
  end
20
19
 
21
20
  node.close_clause("end")
22
- node.remove_attribute("r:if")
23
21
  end
24
22
  end
25
23
  end
@@ -0,0 +1,24 @@
1
+ module Renshi
2
+ module AttributeExpressions
3
+ class Unless
4
+ def evaluate(expression, node)
5
+ node.open_clause("unless (#{expression})")
6
+
7
+ sibling = node.next_real
8
+
9
+ if sibling
10
+ sibling_commands = sibling.commands
11
+
12
+ if sibling_commands.first
13
+ expression = sibling_commands.first[0][2..-1]
14
+ if expression == "else" or expression == "elsif"
15
+ return
16
+ end
17
+ end
18
+ end
19
+
20
+ node.close_clause("end")
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,13 +1,9 @@
1
1
  module Renshi
2
2
  module AttributeExpressions
3
- class While
4
- include Renshi::AttributeExpressions
5
-
6
- def evaluate(expression, node)
7
- expression = encode_xml_entities(expression)
3
+ class While
4
+ def evaluate(expression, node)
8
5
  node.open_clause("while (#{expression})")
9
6
  node.close_clause("end")
10
- node.remove_attribute("r:while")
11
7
  end
12
8
  end
13
9
  end
@@ -3,11 +3,30 @@ require 'renshi/attribute_expressions/elsif'
3
3
  require 'renshi/attribute_expressions/else'
4
4
  require 'renshi/attribute_expressions/while'
5
5
  require 'renshi/attribute_expressions/for'
6
+ require 'renshi/attribute_expressions/unless'
7
+ require 'renshi/attribute_expressions/each'
6
8
 
7
9
  module Renshi
8
10
  module AttributeExpressions
9
11
 
10
- def encode_xml_entities(expression)
12
+ def self.perform_expression(node, command)
13
+ expression = command[0][2..-1]
14
+
15
+ obj = nil
16
+ begin
17
+ obj = eval "Renshi::AttributeExpressions::#{expression.capitalize}.new"
18
+ rescue StandardError
19
+ raise Renshi::SyntaxError, "Could not find attribute expression called #{expression}.rb", caller
20
+ end
21
+
22
+ expression = encode_xml_entities(command[1].to_s)
23
+ obj.evaluate(expression, node)
24
+
25
+ #removes attribute after it's performed so it doesn't appear in end document
26
+ node.remove_attribute(command[0])
27
+ end
28
+
29
+ def self.encode_xml_entities(expression)
11
30
  expression.gsub!("<", Renshi::Parser::XML_LT)
12
31
  expression.gsub!(">", Renshi::Parser::XML_GT)
13
32
  expression.gsub!("&", Renshi::Parser::XML_AMP)
data/lib/renshi/parser.rb CHANGED
@@ -5,17 +5,17 @@ module Renshi
5
5
  # the document, which are finally compiled into Ruby.
6
6
 
7
7
  class Parser
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
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
13
 
14
14
  #these symbols cannot be normally escaped, as we need to differentiate between &lt; as an
15
15
  #escaped string, to be left in the document, and < as a boolean operator
16
- XML_LT = "R_LT"
17
- XML_GT = "R_GT"
18
- XML_AMP = "R_AMP"
16
+ XML_LT = "^R_LT^"
17
+ XML_GT = "^R_GT^"
18
+ XML_AMP = "^R_AMP^"
19
19
 
20
20
  def self.parse(xhtml)
21
21
  doc = Nokogiri::HTML.fragment(xhtml)
@@ -34,7 +34,7 @@ module Renshi
34
34
  if node.attributes
35
35
  expressions = node.commands
36
36
  for expression in expressions
37
- perform_expression(node, expression)
37
+ AttributeExpressions.perform_expression(node, expression)
38
38
  end
39
39
  end
40
40
 
@@ -56,19 +56,6 @@ module Renshi
56
56
 
57
57
  node.children.each {|child| transform_node(child)}
58
58
  end
59
-
60
- def self.perform_expression(node, command)
61
- expression = command[0][2..-1]
62
-
63
- obj = nil
64
- begin
65
- obj = eval "Renshi::AttributeExpressions::#{expression.capitalize}.new"
66
- rescue StandardError
67
- raise Renshi::SyntaxError, "Could not find attribute expression called #{expression}.rb", caller
68
- end
69
-
70
- obj.evaluate(command[1].to_s, node)
71
- end
72
59
 
73
60
  def self.compile(text)
74
61
  idx = text.index("$")
data/lib/renshi.rb CHANGED
@@ -9,7 +9,7 @@ require 'renshi/attribute_expressions'
9
9
  require 'renshi/frameworks'
10
10
 
11
11
  module Renshi
12
- VERSION="0.0.4"
12
+ VERSION="0.0.5"
13
13
 
14
14
  class SyntaxError < StandardError; end
15
15
  end
data/spec/data/if_2.ren CHANGED
@@ -5,3 +5,13 @@
5
5
  </div>
6
6
  </body>
7
7
  </html>
8
+
9
+
10
+ <html xmlns="http://www.w3.org/1999/xhtml">
11
+ <body>
12
+ <div id="content" r:each="foos, |foo|">
13
+ hello
14
+ </div>
15
+ </body>
16
+ </html>
17
+
data/spec/each_spec.rb ADDED
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'nokogiri'
3
+
4
+ describe Renshi::Parser do
5
+ it "should evaluate r:unless(false)" do
6
+ foos = [0,1,2]
7
+ doc = Nokogiri::HTML("<span id='red$foo' r:each='foos, |foo|'/>hello$foo</span>")
8
+ compiled = Renshi::Parser.parse(doc.root.to_s)
9
+ out = eval(compiled, binding)
10
+ (doc/"span[@id='red0']").text.strip.should eql "hello0"
11
+ (doc/"span[@id='red1']").text.strip.should eql "hello1"
12
+ (doc/"span[@id='red2']").text.strip.should eql "hello2"
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'nokogiri'
3
+
4
+ describe Renshi::Parser do
5
+ it "should evaluate r:unless(false)" do
6
+ doc = Nokogiri::HTML("<span id='red' r:unless='false'>hello</span>")
7
+ compiled = Renshi::Parser.parse(doc.root.to_s)
8
+ out = eval(compiled, binding)
9
+ (doc/"span[@id='red']").text.strip.should eql "hello"
10
+ end
11
+ end
@@ -10,4 +10,18 @@ describe Renshi::Parser do
10
10
  (doc/"div[@id='content0']").text.strip.should =~ /hello0/
11
11
  (doc/"div[@id='content1']").text.strip.should =~ /hello1/
12
12
  end
13
+
14
+ it "should evaluate r:if(foo < 2)" do
15
+ doc = Nokogiri::HTML("<span r:if='1 < 2'>hello</div>")
16
+ body = doc.root.children.first
17
+ node = body.children.first
18
+ eval(deliver_compiled(node), binding).should eql "hello"
19
+ end
20
+
21
+ it "should evaluate r:elsif(foo < 2)" do
22
+ doc = Nokogiri::HTML("<span r:if='false'/><span r:elsif='1 < 2'>hello</div>")
23
+ compiled = deliver_compiled(doc.root)
24
+ puts compiled
25
+ eval(compiled, binding).should eql "hello"
26
+ end
13
27
  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.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Faiz
@@ -33,10 +33,12 @@ extra_rdoc_files:
33
33
  files:
34
34
  - lib/renshi
35
35
  - lib/renshi/attribute_expressions
36
+ - lib/renshi/attribute_expressions/each.rb
36
37
  - lib/renshi/attribute_expressions/else.rb
37
38
  - lib/renshi/attribute_expressions/elsif.rb
38
39
  - lib/renshi/attribute_expressions/for.rb
39
40
  - lib/renshi/attribute_expressions/if.rb
41
+ - lib/renshi/attribute_expressions/unless.rb
40
42
  - lib/renshi/attribute_expressions/while.rb
41
43
  - lib/renshi/attribute_expressions.rb
42
44
  - lib/renshi/frameworks
@@ -72,7 +74,7 @@ rubyforge_project:
72
74
  rubygems_version: 1.3.1
73
75
  signing_key:
74
76
  specification_version: 2
75
- summary: Renshi is a lightweight XHTML template language, inspired by Python's Genshi and build on Nokogiri - http://nokogiri.rubyforge.org
77
+ summary: Renshi is a lightweight XHTML template language, inspired by Python's Genshi and build on Nokogiri.
76
78
  test_files:
77
79
  - spec/data
78
80
  - spec/data/attribute_values_parsed.ren
@@ -86,6 +88,7 @@ test_files:
86
88
  - spec/data/while.ren
87
89
  - spec/data/while_lt.ren
88
90
  - spec/data/white_space.ren
91
+ - spec/each_spec.rb
89
92
  - spec/else_spec.rb
90
93
  - spec/elsif_spec.rb
91
94
  - spec/for_spec.rb
@@ -95,5 +98,6 @@ test_files:
95
98
  - spec/renshi_spec.rb
96
99
  - spec/spec.opts
97
100
  - spec/spec_helper.rb
101
+ - spec/unless_spec.rb
98
102
  - spec/while_spec.rb
99
103
  - spec/xml_entities_in_expressions_spec.rb