re_template 0.0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,64 @@
1
+ A very simple template engine based on Regular Expressions
2
+
3
+
4
+ Features
5
+ ========
6
+
7
+ * Regular expressions or plain text
8
+ * Can be used for HTML->HTML (read on)
9
+ * Tested on Ruby 1.8.7 and 1.9.1
10
+
11
+
12
+
13
+ Usage
14
+ =====
15
+
16
+ template = ReTemplate::Text.new
17
+ template.expressions = {/\{foo\}/ => :foo, /\{bar\}/ => :bar}
18
+ template.parse! 'A {foo} is not a {bar}.'
19
+ template.render :foo => 'plant', :bar => 'rhinocerous', :other_expression => 'ignored'
20
+ => 'A plant is not a rhinocerous.'
21
+
22
+ Expressions must be set before parsing.
23
+ Multiple calls to parse! can be done with the same expressions (this may change).
24
+ Multiple calls to 'render' will work by design.
25
+ It also works with HTML:
26
+
27
+ template = ReTemplate::Html.new
28
+ template.add_text_expressions '<foo>' => :foo, '|lang|' => :lang
29
+ template.parse! '<p>&lt;foo&gt; is not a valid |lang| tag.</p>'
30
+ template.render :foo => '<bar>', :lang => 'HTML'
31
+ => '<p>&lt;bar&gt; is not a valid HTML tag.</p>'
32
+
33
+ Actually, I lied, as this will currently attach a doctype, and wrap things in html and body tags, if any of these things are missing. I blame Nokogiri.
34
+
35
+ Read the specs for more.
36
+
37
+
38
+
39
+ Motivation/Examples
40
+ ===================
41
+
42
+ Mail merge. A user can prepare an email like this, in their mail client:
43
+
44
+ Dear {customer_name},
45
+ Lorem ipsum dolor sit amet...
46
+
47
+ The curly brackets are merely a convention, because {user} is unlikely to be intended in the body of a message. The important point is that this can also be applied to an HTML message, even if the pattern or replacement text is not valid HTML. For example:
48
+
49
+ Dear <customer_name>,
50
+
51
+ A simple text replacement would only see &lt;user&gt;. While we're at it, the replacement text is automatically escaped.
52
+
53
+ I also looked at Liquid. It is very cool, but it was overkill for this project, and it didn't look like it would behave well with WYSIWYG-generated HTML.
54
+
55
+
56
+
57
+ CAVEATS
58
+ =======
59
+
60
+ This is brand spanking this-afternoon new. The API is pretty much guaranteed to change. If you're using this for anything important, either fork it or lock to a specific version.
61
+
62
+ The expressions hash is unordered. If you have a chunk of text that could match two different regular expressions, one of them is going to be applied first, and it's undefined which one. If this matters to you, you're probably using the wrong tool -- personally, I won't be using the regexes directly at all, they just seem to be faster (for some bizarre reason) than string#split.
63
+
64
+ Someone MUST have done a better job of this somewhere. If you find it, let me know!
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'autoloader'
3
+ require 'pathname'
4
+ AutoLoader << Pathname(__FILE__).dirname
5
+
6
+ class ReTemplate
7
+ include AutoLoader
8
+
9
+ attr_accessor :nodes
10
+ attr_writer :expressions
11
+ def expressions
12
+ @expressions ||= {}
13
+ end
14
+
15
+ def add_text_expressions *args
16
+ hash = args.last.kind_of?(Hash) ? args.pop : {}
17
+ args.each do |field|
18
+ hash[field] = field
19
+ end
20
+ hash.each_pair do |key, value|
21
+ self.expressions[/#{Regexp.escape key}/] = value
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,49 @@
1
+ require 'nokogiri'
2
+
3
+ class ReTemplate::Html < ReTemplate
4
+ attr_accessor :doc
5
+ def parse! given_doc
6
+ if given_doc.kind_of? String
7
+ self.doc = Nokogiri::HTML.parse(given_doc)
8
+ else
9
+ self.doc = given_doc.dup
10
+ end
11
+
12
+ self.nodes = []
13
+
14
+ parse_children! doc
15
+ end
16
+
17
+ def render values
18
+ nodes.each do |node|
19
+ node.render! values
20
+ end
21
+ doc.dup
22
+ end
23
+
24
+ class SubTemplate < Text
25
+ attr_accessor :node
26
+ def initialize node, expressions
27
+ self.node = node
28
+ self.expressions = expressions
29
+ self.parse! node.text
30
+ end
31
+
32
+ def render! values
33
+ new_node = Nokogiri::XML::Text.new(render(values), node.document)
34
+ node.replace(new_node)
35
+ self.node = new_node
36
+ end
37
+ end
38
+
39
+ protected
40
+ def parse_children! node
41
+ if node.kind_of? Nokogiri::XML::Text
42
+ nodes << SubTemplate.new(node, expressions)
43
+ else
44
+ node.children.each do |n|
45
+ parse_children! n
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,35 @@
1
+ class ReTemplate::Text < ReTemplate
2
+ def parse! string
3
+ self.nodes = [string]
4
+ expressions.each_key do |expression|
5
+ self.nodes = self.nodes.map do |node|
6
+ if node.kind_of? String
7
+ result = []
8
+ rest = node
9
+ while match = expression.match(rest)
10
+ result << match.pre_match
11
+ result << expression
12
+ rest = match.post_match
13
+ end
14
+ result << rest
15
+ result.reject{|x| x == ''}
16
+ else
17
+ # It's not a string, so leave it alone
18
+ node
19
+ end
20
+ end.flatten
21
+ end
22
+ end
23
+
24
+ def render values
25
+ result = ''
26
+ nodes.each do |node|
27
+ if node.kind_of? String
28
+ result << node
29
+ else
30
+ result << values[expressions[node]]
31
+ end
32
+ end
33
+ result
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: re_template
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - David Masover
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-15 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: autoloader
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: "0.0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: nokogiri
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: "1.4"
34
+ version:
35
+ description: Intelligently handles HTML input, and is meant to safely handle untrusted templates and substitution variables. Basically, it's designed for mail merge.
36
+ email: ninja@slaphack.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - README
45
+ - lib/re_template.rb
46
+ - lib/re_template/text.rb
47
+ - lib/re_template/html.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/masover/re_template
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options: []
54
+
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 2
75
+ summary: Simple, Regular Expression powered template engine.
76
+ test_files: []
77
+