masover-re_template 0.0.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.
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,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.to_s
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
@@ -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
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: masover-re_template
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - David Masover
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-10 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: masover-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.1
24
+ version:
25
+ description:
26
+ email: dave@3mix.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - README
35
+ - lib/re_template.rb
36
+ - lib/re_template/text.rb
37
+ - lib/re_template/html.rb
38
+ has_rdoc: false
39
+ homepage:
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ requirements: []
58
+
59
+ rubyforge_project:
60
+ rubygems_version: 1.2.0
61
+ signing_key:
62
+ specification_version: 2
63
+ summary: Simple, Regular Expression powered template engine. Intelligently handles HTML input.
64
+ test_files: []
65
+