renshi 0.0.4 → 0.0.5

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