ezamar 2009.06

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS ADDED
@@ -0,0 +1,4 @@
1
+ Following persons have contributed to ezamar.
2
+ (Sorted by number of submitted patches, then alphabetically)
3
+
4
+ 3 Michael Fellinger <mf@rubyists.com>
@@ -0,0 +1,12 @@
1
+ [e7baafa | 2009-06-04 02:49:32 UTC] Michael Fellinger <m.fellinger@gmail.com>
2
+
3
+ * Version 2009.06
4
+
5
+ [0c58a0e | 2009-06-04 02:48:32 UTC] Michael Fellinger <m.fellinger@gmail.com>
6
+
7
+ * Make it grow
8
+
9
+ [52b4c7c | 2009-03-09 13:43:46 UTC] Michael Fellinger <m.fellinger@gmail.com>
10
+
11
+ * Extract Ezamar from Ramaze
12
+
@@ -0,0 +1,28 @@
1
+ AUTHORS
2
+ CHANGELOG
3
+ MANIFEST
4
+ README
5
+ README.md
6
+ Rakefile
7
+ ezamar.gemspec
8
+ lib/ezamar.rb
9
+ lib/ezamar/element.rb
10
+ lib/ezamar/engine.rb
11
+ lib/ezamar/morpher.rb
12
+ lib/ezamar/render_partial.rb
13
+ lib/ezamar/version.rb
14
+ misc/textpow.syntax
15
+ spec/helper.rb
16
+ tasks/authors.rake
17
+ tasks/bacon.rake
18
+ tasks/changelog.rake
19
+ tasks/copyright.rake
20
+ tasks/gem.rake
21
+ tasks/gem_installer.rake
22
+ tasks/install_dependencies.rake
23
+ tasks/manifest.rake
24
+ tasks/rcov.rake
25
+ tasks/release.rake
26
+ tasks/reversion.rake
27
+ tasks/setup.rake
28
+ tasks/yard.rake
data/README ADDED
@@ -0,0 +1,15 @@
1
+ ==Michael Fellinger
2
+ ----------
3
+
4
+ A light-weight and simple templating engine for Ruby.
5
+
6
+ == Download
7
+
8
+
9
+
10
+ ==Usage
11
+ -------
12
+
13
+ We're getting there.
14
+
15
+ Copyright(c) 2009 by Michael Fellinger
@@ -0,0 +1,95 @@
1
+ # Ezamar
2
+
3
+ Ezamar is a light-weight and simple templating engine for Ruby.
4
+
5
+ The first versions date back to 2006 when Ramaze was created, but I extracted
6
+ it from Ramaze to level the playfield for more competitve engines.
7
+
8
+ It is based on a number of so-called pipes that perform evaluation and
9
+ substitution on a String.
10
+
11
+
12
+ ## Features
13
+
14
+ * Simple implementation
15
+ * No dependencies
16
+ * Elements for easy encapsulation of partial functionality
17
+ * Template compilation
18
+ * (X)HTML compatible
19
+
20
+
21
+ ## Dependencies
22
+
23
+ Ezamar should work with any Ruby implementation that conforms to MRI versions
24
+ since 1.8.4 and possibly earlier versions as well.
25
+
26
+
27
+ ## Basic usage
28
+
29
+ require 'ezamar'
30
+
31
+ string = 'The Answer is #{21 + 21}'
32
+ template = Ezamar::Template.new(string, :file => '<eval>')
33
+ template.result(binding)
34
+
35
+
36
+ ## Syntax
37
+
38
+ Since Ezamar is based on Ruby String interpolation you can use any valid
39
+ interpolation syntax inside your templates and it will be put into the result.
40
+ There are 3 special instructions that will result in string substitutions
41
+ during template compilation.
42
+
43
+
44
+ ### Evaluate without interpolation
45
+
46
+ <?r rubycode ?>
47
+
48
+ Evaluates the code inside the tag, this is considered XHTML-valid and so is the
49
+ preferred method for executing code inside your templates.
50
+ The return-value is ignored.
51
+
52
+
53
+ ### Evaluate with interpolation
54
+
55
+ #{ rubycode }
56
+
57
+ You know this from normal ruby already and it's actually nothing else.
58
+ Interpolation at the position in the template, isn't any special taggy format
59
+ and therefor safe to use.
60
+
61
+ ### Evaluate without interpolation (ERB style)
62
+
63
+ <% rubycode %>
64
+
65
+ The same as `<?r ?>`, ERB-style and not valid XHTML, but should give someone
66
+ who is already familiar with ERB some common ground
67
+
68
+
69
+ ### Evaluate with interpolation
70
+
71
+ <%= rubycode %>
72
+
73
+ The result of this will be interpolated at the position in the template. Not
74
+ valid XHTML either.
75
+
76
+
77
+ ## Thanks to
78
+
79
+ * Jonathan Buch
80
+
81
+ Who is of the first users of Ezamar, found a ton of bugs and provided the
82
+ RenderPartial pipeline.
83
+
84
+ * Zenix
85
+
86
+ Who provided documentation.
87
+
88
+ * The folks in #ramaze on irc.freenode.net
89
+
90
+ Who kept pushing Ezamar to new limits and contributed a lot.
91
+
92
+ * George Moschovitis a.k.a gmosx
93
+
94
+ Who inspired the Ramaze project and Ezamar through his awesome work on the
95
+ original Nitro framework.
@@ -0,0 +1,95 @@
1
+ begin; require 'rubygems'; rescue LoadError; end
2
+
3
+ require 'rake'
4
+ require 'rake/clean'
5
+ require 'rake/gempackagetask'
6
+ require 'time'
7
+ require 'date'
8
+ require "lib/ezamar"
9
+
10
+ PROJECT_SPECS = FileList[
11
+ 'spec/*/**/*.rb'
12
+ ]
13
+
14
+ PROJECT_MODULE = 'Ezamar'
15
+ PROJECT_README = 'README'
16
+ #PROJECT_RUBYFORGE_GROUP_ID = 3034
17
+ PROJECT_COPYRIGHT_SUMMARY = [
18
+ "# Copyright (c) 2008-#{Time.now.year} The Rubyists, LLC (effortless systems) <rubyists@rubyists.com>",
19
+ "# Distributed under the terms of the MIT license.",
20
+ "# See the LICENSE file which accompanies this software for the full text",
21
+ "#"
22
+ ]
23
+ PROJECT_COPYRIGHT = PROJECT_COPYRIGHT_SUMMARY + [
24
+ "# Permission is hereby granted, free of charge, to any person obtaining a copy",
25
+ '# of this software and associated documentation files (the "Software"), to deal',
26
+ "# in the Software without restriction, including without limitation the rights",
27
+ "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
28
+ "# copies of the Software, and to permit persons to whom the Software is",
29
+ "# furnished to do so, subject to the following conditions:",
30
+ "#",
31
+ "# The above copyright notice and this permission notice shall be included in",
32
+ "# all copies or substantial portions of the Software.",
33
+ "#",
34
+ '# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR',
35
+ "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
36
+ "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
37
+ "# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
38
+ "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
39
+ "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN",
40
+ "# THE SOFTWARE."
41
+ ]
42
+
43
+ PROJECT_VERSION =
44
+ if version = ENV['PROJECT_VERSION'] || ENV['VERSION']
45
+ version
46
+ else
47
+ Ezamar::VERSION rescue Date.today.strftime("%Y.%m.%d")
48
+ end
49
+
50
+ # To release the monthly version do:
51
+ # $ PROJECT_VERSION=2009.03 rake release
52
+
53
+ PROJECT_FILES = FileList[`git ls-files`.split("\n")].exclude('.gitignore')
54
+
55
+ GEMSPEC = Gem::Specification.new{|s|
56
+ s.name = "ezamar"
57
+ s.author = "Michael Fellinger"
58
+ s.summary = "A light-weight and simple templating engine for Ruby."
59
+ s.description = "A light-weight and simple templating engine for Ruby."
60
+ s.email = "manveru@rubyists.com"
61
+ s.homepage = "http://github.com/manveru/ezamar"
62
+ s.platform = Gem::Platform::RUBY
63
+ s.version = PROJECT_VERSION
64
+ s.files = PROJECT_FILES
65
+ s.has_rdoc = true
66
+ s.require_path = "lib"
67
+
68
+ s.rubyforge_project = "ezamar"
69
+
70
+
71
+ s.post_install_message = <<MESSAGE
72
+ ============================================================
73
+
74
+ Thank you for installing Ezamar!
75
+
76
+ ============================================================
77
+ MESSAGE
78
+ }
79
+
80
+ Dir.glob('tasks/*.rake'){|f| import(f) }
81
+
82
+ task :default => [:bacon]
83
+
84
+ CLEAN.include %w[
85
+ **/.*.sw?
86
+ *.gem
87
+ .config
88
+ **/*~
89
+ **/{data.db,cache.yaml}
90
+ *.yaml
91
+ pkg
92
+ rdoc
93
+ ydoc
94
+ *coverage*
95
+ ]
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{ezamar}
5
+ s.version = "2009.06"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Michael Fellinger"]
9
+ s.date = %q{2009-06-04}
10
+ s.description = %q{A light-weight and simple templating engine for Ruby.}
11
+ s.email = %q{manveru@rubyists.com}
12
+ s.files = ["AUTHORS", "CHANGELOG", "MANIFEST", "README", "README.md", "Rakefile", "ezamar.gemspec", "lib/ezamar.rb", "lib/ezamar/element.rb", "lib/ezamar/engine.rb", "lib/ezamar/morpher.rb", "lib/ezamar/render_partial.rb", "lib/ezamar/version.rb", "misc/textpow.syntax", "spec/helper.rb", "tasks/authors.rake", "tasks/bacon.rake", "tasks/changelog.rake", "tasks/copyright.rake", "tasks/gem.rake", "tasks/gem_installer.rake", "tasks/install_dependencies.rake", "tasks/manifest.rake", "tasks/rcov.rake", "tasks/release.rake", "tasks/reversion.rake", "tasks/setup.rake", "tasks/yard.rake"]
13
+ s.homepage = %q{http://github.com/manveru/ezamar}
14
+ s.post_install_message = %q{============================================================
15
+
16
+ Thank you for installing Ezamar!
17
+
18
+ ============================================================
19
+ }
20
+ s.require_paths = ["lib"]
21
+ s.rubyforge_project = %q{ezamar}
22
+ s.rubygems_version = %q{1.3.3}
23
+ s.summary = %q{A light-weight and simple templating engine for Ruby.}
24
+
25
+ if s.respond_to? :specification_version then
26
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
27
+ s.specification_version = 3
28
+
29
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
30
+ else
31
+ end
32
+ else
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+
6
+ require 'ezamar/engine'
7
+ require 'ezamar/element'
@@ -0,0 +1,162 @@
1
+ # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ # Example:
5
+ #
6
+ # Your Element called Page:
7
+ #
8
+ # class Page < Ezamar::Element
9
+ # def render
10
+ # %{
11
+ # <html>
12
+ # <h1>
13
+ # #@title
14
+ # </h1>
15
+ # #{content}
16
+ # </html>
17
+ # }
18
+ # end
19
+ # end
20
+ #
21
+ # and one called SideBar
22
+ #
23
+ # class SideBar < Ezamar::Element
24
+ # def render
25
+ # %{
26
+ # <a href="http://something.com">something</a>
27
+ # }
28
+ # end
29
+ # end
30
+ #
31
+ # and your template (any template for any action):
32
+ #
33
+ # <Page title="Test">
34
+ # <SideBar />
35
+ # <p>
36
+ # Hello, World!
37
+ # </p>
38
+ # </Page>
39
+ #
40
+ # would result in:
41
+ #
42
+ # <html>
43
+ # <h1>
44
+ # Test
45
+ # </h1>
46
+ # <p>
47
+ # Hello, World!
48
+ # </p>
49
+ # </html>
50
+
51
+ module Ezamar
52
+ class Element
53
+ attr_accessor :content
54
+
55
+ # this will be called by #transform, passes along the
56
+ # stuff inside the tags for the element
57
+
58
+ def initialize(content)
59
+ @content = content
60
+ end
61
+
62
+ # The method that will be called upon to render the things
63
+ # inside the element, you can access #content from here, which
64
+ # contains the contents between the tags.
65
+ #
66
+ # It should answer with a String.
67
+
68
+ def render *args
69
+ @content
70
+ end
71
+
72
+ class << self
73
+ # transforms all <Element> tags within the string, takes also
74
+ # a binding to be compatible to the transform-pipeline, won't have
75
+ # any use for it though.
76
+
77
+ def transform template
78
+ matches = template.scan(/<([A-Z][a-zA-Z0-9]*)(.*?)?>/)
79
+
80
+ matches.each do |(klass, params)|
81
+ transformer = (params[-1,1] == '/' ? :without : :with)
82
+ template = send("transform_#{transformer}_content", template, klass)
83
+ end
84
+ template
85
+ end
86
+
87
+ # transforms elements like:
88
+ # <Page> some content </Page>
89
+
90
+ def transform_with_content(template, klass)
91
+ template.gsub(/<#{klass}( .*?)?>(.*?)<\/#{klass}>/m) do |m|
92
+ params, content = $1.to_s, $2.to_s
93
+ finish_transform(klass, params, content)
94
+ end
95
+ end
96
+
97
+ # transforms elements like:
98
+ # <Page />
99
+
100
+ def transform_without_content(template, klass)
101
+ template.gsub(/<#{klass}( .*?)?\/>/) do |m|
102
+ params = $1.to_s
103
+ finish_transform(klass, params, content = '')
104
+ end
105
+ end
106
+
107
+ # find the element, create an instance, pass it the content
108
+ # check if it responds to :render and sets instance-variables
109
+ # that are named after the keys and hold the values of the parameters
110
+ # you passed to the Element
111
+ #
112
+ # Parameters look like:
113
+ # <Page foo="true"> bar </Page>
114
+ # <Page foo="true" />
115
+
116
+ def finish_transform(klass, params, content)
117
+ scope =
118
+ if Ramaze::Action.current
119
+ Ramaze::Action.current.controller
120
+ else
121
+ self.class
122
+ end
123
+ instance = scope.constant(klass).new(content)
124
+
125
+ demunge_passed_variables(params).each do |key, value|
126
+ instance.instance_variable_set("@#{key}", value)
127
+ end
128
+
129
+ instance.render
130
+ rescue => ex
131
+ Ramaze::Log.debug(ex.message)
132
+ ''
133
+ end
134
+
135
+ # basically processes stuff like
136
+ # 'foo="bar" foobar="baz"'
137
+ # do NOT pass actual objects that cannot be simply read as a string
138
+ # here, the information will be lost.
139
+ #
140
+ # Exceptions are true, false, Integers and Floats. They will appear
141
+ # in their real form (this again is also valid for strings that contain
142
+ # these values in a way that makes Integer/Float possible to parse them)
143
+ #
144
+ # Just remember, walk like a duck, talk like a duck.
145
+
146
+ def demunge_passed_variables(template)
147
+ template.scan(/\s?(.*?)=["'](.*?)["']/).inject({}) do |hash, (key, value)|
148
+ value =
149
+ case value
150
+ when 'true'
151
+ true
152
+ when 'false'
153
+ false
154
+ else
155
+ Integer(value) rescue Float(value) rescue value
156
+ end
157
+ hash.merge key => value
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,74 @@
1
+ # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'digest/sha1'
5
+
6
+ # Ezamar is a very simple (and at no means complete) reimplementation of the
7
+ # Templating-engine found in Nitro.
8
+ #
9
+ # Since Nitros templating is based on REXML and Ezamar is not there are vast
10
+ # differences, but it tries to keep the look and feel as close as possible.
11
+
12
+ module Ezamar
13
+
14
+ # This class is responsible for initializing and compiling the template.
15
+
16
+ class Template
17
+
18
+ # Take a template (anything that responds to ::to_str) and options.
19
+ # At the moment the only option used is :file, which is used to tell
20
+ # Kernel::eval how to produce better backtraces.
21
+
22
+ def initialize(template, options = {})
23
+ @template, @options = template, options
24
+ compile
25
+ end
26
+
27
+ # All ye who seek magic, look elsewhere, this method is ASAP (as simple as possible)
28
+ #
29
+ # There are some simple gsubs that build a final template which is evaluated
30
+ #
31
+ # The rules are following:
32
+ # <?r rubycode ?>
33
+ # evaluate the code inside the tag, this is considered XHTML-valid and so is the
34
+ # preferred method for executing code inside your templates.
35
+ # The return-value is ignored
36
+ # <% rubycode %>
37
+ # The same as <?r ?>, ERB-style and not valid XHTML, but should give someone who
38
+ # is already familiar with ERB some common ground
39
+ # #{ rubycode }
40
+ # You know this from normal ruby already and it's actually nothing else.
41
+ # Interpolation at the position in the template, isn't any special taggy format
42
+ # and therefor safe to use.
43
+ # <%= rubycode %>
44
+ # The result of this will be interpolated at the position in the template.
45
+ # Not valid XHTML either.
46
+ #
47
+ # TODO
48
+ # - provide C version or maybe use erbuis
49
+
50
+ def compile
51
+ temp = @template.dup
52
+ start_heredoc = "T" << Digest::SHA1.hexdigest(temp)
53
+ start_heredoc, end_heredoc = "\n<<#{start_heredoc}\n", "\n#{start_heredoc}\n"
54
+ bufadd = "_out_ << "
55
+
56
+ temp.gsub!(/<%(?!=)\s*(.*?)\s*%>/m,
57
+ "#{end_heredoc} \\1; #{bufadd} #{start_heredoc}")
58
+ temp.gsub!(/<\?r\s+(.*?)\s+\?>/m,
59
+ "#{end_heredoc} \\1; #{bufadd} #{start_heredoc}")
60
+ temp.gsub!(/<%=\s*(.*?)\s*%>/m,
61
+ "#{end_heredoc} #{bufadd} (\\1); #{bufadd} #{start_heredoc}")
62
+
63
+ @compiled = "_out_ = ''
64
+ #{bufadd} #{start_heredoc} #{temp} #{end_heredoc}
65
+ _out_"
66
+ end
67
+
68
+ # Takes a binding and evals it with the previously set options.
69
+
70
+ def result(binding)
71
+ eval(@compiled, binding, @options[:file]).strip
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,135 @@
1
+ # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ begin
5
+ require 'hpricot'
6
+ rescue LoadError => ex
7
+ warn "Please install hpricot (for example via `gem install hpricot`) to get morphing"
8
+ raise ex
9
+ end
10
+
11
+ # This applies a morphing-replace for the template.
12
+ #
13
+ # To use the functionality of Morpher you will need to have hpricot installed,
14
+ # you will get one error in case you don't and the method will be replaced by a
15
+ # stub that simply returns the template.
16
+ #
17
+ # The method first checks if you use any morphers and just skips the step if
18
+ # you don't, this should give quite some speedup for smaller templates that
19
+ # don't use this functionality at all. the check works by searching the morphs
20
+ # with appended '=' in the template. There may be a few cases where this won't
21
+ # work since we cannot make any assumptions on the format.
22
+ #
23
+ # If you want to turn this functionality off, either remove Morpher from:
24
+ # Ramaze::Template::Ezamar::TRANSFORM_PIPELINE
25
+ # or do:
26
+ # Ramaze::Morpher::MORPHS.clear
27
+ #
28
+ # The latter is a tad slower, but i mention the possibility in case you find
29
+ # good use for it.
30
+ #
31
+ # You can add your own morphers in Ramaze::Morpher::MORPHS
32
+ #
33
+ # For Example:
34
+ #
35
+ # Morpher::MORPHS['if'] = '<?r %morph %expression ?>%content<?r end ?>'
36
+ #
37
+ # Now, assuming that some tag in your template is '<a if="@foo">x</a>'
38
+ #
39
+ # %morph stands for the name of your morph: 'if'
40
+ # %expression is the stuff you write in the attribute: '@foo'
41
+ # %content is the tag without the attribute (and all inside): '<a>x</a>'
42
+
43
+ module Ezamar
44
+ module Morpher
45
+
46
+ # Use this trait to define your custom morphs.
47
+ MORPHS = {
48
+ 'if' => '<?r %morph %expression ?>%content<?r end ?>',
49
+ 'unless' => '<?r %morph %expression ?>%content<?r end ?>',
50
+ 'for' => '<?r %morph %expression ?>%content<?r end ?>',
51
+ 'each' => '<?r %expression.%morph do |_e| ?>%content<?r end ?>',
52
+ 'times' => '<?r %expression.%morph do |_t| ?>%content<?r end ?>',
53
+ }
54
+
55
+ # Since the functionality is best explained by examples, here they come.
56
+ #
57
+ # Example:
58
+ #
59
+ # if:
60
+ # <div if="@name">#@name</div>
61
+ # morphs to:
62
+ # <?r if @name ?>
63
+ # <div>#@name</div>
64
+ # <?r end ?>
65
+ #
66
+ # unless:
67
+ # <div unless="@name">No Name</div>
68
+ # morphs to:
69
+ # <?r unless @name ?>
70
+ # <div>No Name</div>
71
+ # <?r end ?>
72
+ #
73
+ # for:
74
+ # <div for="name in @names">#{name}</div>
75
+ # morphs to:
76
+ # <?r for name in @names ?>
77
+ # <div>#{name}</div>
78
+ # <?r end ?>
79
+ #
80
+ # times:
81
+ # <div times="3">#{_t}<div>
82
+ # morphs to:
83
+ # <?r 3.times do |_t| ?>
84
+ # <div>#{_t}</div>
85
+ # <?r end ?>
86
+ #
87
+ # each:
88
+ # <div each="[1,2,3]">#{_e}</div>
89
+ # morphs to:
90
+ # <?r [1,2,3].each do |_e| ?>
91
+ # <div>#{_e}</div>
92
+ # <?r end ?>
93
+ #
94
+ # The latter two examples show you also one standard introduced by a
95
+ # limitation of the replacement-system.
96
+ #
97
+ # When you yield a value, please name it by the first character(s) of the
98
+ # morphs name, with an underscore prefixed.
99
+ #
100
+ # for each an _e, for times a _t.
101
+ #
102
+ # This is by far not the best way to handle it and might lead to problems
103
+ # due to the lack of proper scoping in ruby (if you define an _e or _t
104
+ # before the block it will be overwritten).
105
+ #
106
+ # So please be careful, I tried to come up with something that is both easy
107
+ # to write and doesn't look outright awful while keeping an easy to
108
+ # remember mnemonic.
109
+ #
110
+ # TODO:
111
+ # - Add pure Ruby implementation as a fall-back.
112
+
113
+ def self.transform(template)
114
+ template = template.to_s
115
+ hp = Hpricot(template)
116
+
117
+ MORPHS.each do |morph, replacement|
118
+ hp.search("[@#{morph}]") do |elem|
119
+ expr = elem[morph]
120
+
121
+ elem.remove_attribute(morph)
122
+
123
+ repl = replacement.
124
+ sub('%morph', morph).
125
+ sub('%expression', expr).
126
+ sub('%content', elem.to_html)
127
+
128
+ elem.swap(repl)
129
+ end
130
+ end
131
+
132
+ hp.to_html
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,36 @@
1
+ # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ module Ezamar
5
+
6
+ # A transformer for <render /> tags.
7
+ #
8
+ # Setup:
9
+ #
10
+ # pipeline = Ramaze::Template::Ezamar::TRANSFORM_PIPELINE
11
+ # pipeline.put_after(::Ezamar::Element, ::Ezamar::RenderPartial)
12
+ # pipline.uniq!
13
+ #
14
+ # See /examples/basic/partial.rb for usage.
15
+
16
+ class RenderPartial
17
+ extend Ramaze::Helper::Partial
18
+
19
+ # Renders <render src="/path" [optional="option", ...]> in place.
20
+ #
21
+ # Other options than `src` will be transformed to session parameters for the
22
+ # rendered action to use.
23
+
24
+ def self.transform(template)
25
+ template.gsub!(/<render (.*?) \/>/) do |m|
26
+ args = Hash[*$1.scan(/(\S+)=["'](.*?)["']/).flatten]
27
+ if src = args.delete('src')
28
+ render_partial(src, args)
29
+ end
30
+ end
31
+
32
+ template
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module Ezamar
2
+ VERSION = "2009.06"
3
+ end
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: HTML (Ezamar)
3
+ fileTypes:
4
+ - xhtml
5
+ scopeName: text.html.ruby
6
+ uuid: 45D7E1FC-7D0B-4205-A1A2-3D10BB555A5C
7
+ foldingStartMarker: |-
8
+ (?x)
9
+ (<(?i:head|body|table|thead|tbody|tfoot|tr|div|select|fieldset|style|script|ul|ol|form|dl)\b.*?>
10
+ |<!--(?!.*-->)
11
+ |\{\s*($|\?>\s*$|//|/\*(.*\*/\s*$|(?!.*?\*/)))
12
+ )
13
+ patterns:
14
+ - name: source.ruby.ezamar.embedded.html
15
+ captures:
16
+ "0":
17
+ name: punctuation.section.embedded.ruby
18
+ begin: "<?r"
19
+ end: "?>"
20
+ patterns:
21
+ - name: comment.line.number-sign.ruby
22
+ captures:
23
+ "1":
24
+ name: punctuation.definition.comment.ruby
25
+ match: (#).*?(?=-?\?>)
26
+ - include: source.ruby.ezamar
27
+ - include: text.html.basic
28
+ foldingStopMarker: |-
29
+ (?x)
30
+ (</(?i:head|body|table|thead|tbody|tfoot|tr|div|select|fieldset|style|script|ul|ol|form|dl)>
31
+ |^\s*-->
32
+ |(^|\s)\}
33
+ )
34
+ keyEquivalent: ^~R
@@ -0,0 +1,28 @@
1
+ require "pathname"
2
+ begin
3
+ require "bacon"
4
+ rescue LoadError
5
+ require "rubygems"
6
+ require "bacon"
7
+ end
8
+
9
+ begin
10
+ if (local_path = Pathname.new(__FILE__).dirname.join("..", "lib", "ezamar.rb")).file?
11
+ require local_path
12
+ else
13
+ require "ezamar"
14
+ end
15
+ rescue LoadError
16
+ require "rubygems"
17
+ require "ezamar"
18
+ end
19
+
20
+ Bacon.summary_on_exit
21
+
22
+ describe "Spec Helper" do
23
+ it "Should bring our library namespace in" do
24
+ Ezamar.should == Ezamar
25
+ end
26
+ end
27
+
28
+
@@ -0,0 +1,33 @@
1
+ # Once git has a fix for the glibc in handling .mailmap and another fix for
2
+ # allowing empty mail address to be mapped in .mailmap we won't have to handle
3
+ # them manually.
4
+
5
+ desc 'Update AUTHORS'
6
+ task :authors do
7
+ authors = Hash.new(0)
8
+
9
+ `git shortlog -nse`.scan(/(\d+)\s(.+)\s<(.*)>$/) do |count, name, email|
10
+ # Examples of mappping, replace with your own or comment this out/delete it
11
+ case name
12
+ when /^(?:bougyman$|TJ Vanderpoel)/
13
+ name, email = "TJ Vanderpoel", "tj@rubyists.com"
14
+ when /^(?:manveru$|Michael Fellinger)/
15
+ name, email = "Michael Fellinger", "mf@rubyists.com"
16
+ when /^(?:deathsyn$|Kevin Berry)/
17
+ name, email = "Kevin Berry", "kb@rubyists.com"
18
+ when /^(?:(?:jayson|thedonvaughn|jvaughn)$|Jayson Vaughn)/
19
+ name, email = "Jayson Vaughn", "jv@rubyists.com"
20
+ end
21
+
22
+ authors[[name, email]] += count.to_i
23
+ end
24
+
25
+ File.open('AUTHORS', 'w+') do |io|
26
+ io.puts "Following persons have contributed to #{GEMSPEC.name}."
27
+ io.puts '(Sorted by number of submitted patches, then alphabetically)'
28
+ io.puts ''
29
+ authors.sort_by{|(n,e),c| [-c, n.downcase] }.each do |(name, email), count|
30
+ io.puts("%6d %s <%s>" % [count, name, email])
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,70 @@
1
+ desc 'Run all bacon specs with pretty output'
2
+ task :bacon => :install_dependencies do
3
+ require 'open3'
4
+ require 'scanf'
5
+ require 'matrix'
6
+
7
+ specs = PROJECT_SPECS
8
+
9
+ some_failed = false
10
+ specs_size = specs.size
11
+ if specs.size == 0
12
+ $stderr.puts "You have no specs! Put a spec in spec/ before running this task"
13
+ exit 1
14
+ end
15
+ len = specs.map{|s| s.size }.sort.last
16
+ total_tests = total_assertions = total_failures = total_errors = 0
17
+ totals = Vector[0, 0, 0, 0]
18
+
19
+ red, yellow, green = "\e[31m%s\e[0m", "\e[33m%s\e[0m", "\e[32m%s\e[0m"
20
+ left_format = "%4d/%d: %-#{len + 11}s"
21
+ spec_format = "%d specifications (%d requirements), %d failures, %d errors"
22
+
23
+ specs.each_with_index do |spec, idx|
24
+ print(left_format % [idx + 1, specs_size, spec])
25
+
26
+ Open3.popen3(RUBY, spec) do |sin, sout, serr|
27
+ out = sout.read.strip
28
+ err = serr.read.strip
29
+
30
+ # this is conventional, see spec/innate/state/fiber.rb for usage
31
+ if out =~ /^Bacon::Error: (needed .*)/
32
+ puts(yellow % ("%6s %s" % ['', $1]))
33
+ else
34
+ total = nil
35
+
36
+ out.each_line do |line|
37
+ scanned = line.scanf(spec_format)
38
+
39
+ next unless scanned.size == 4
40
+
41
+ total = Vector[*scanned]
42
+ break
43
+ end
44
+
45
+ if total
46
+ totals += total
47
+ tests, assertions, failures, errors = total_array = total.to_a
48
+
49
+ if tests > 0 && failures + errors == 0
50
+ puts((green % "%6d passed") % tests)
51
+ else
52
+ some_failed = true
53
+ puts(red % " failed")
54
+ puts out unless out.empty?
55
+ puts err unless err.empty?
56
+ end
57
+ else
58
+ some_failed = true
59
+ puts(red % " failed")
60
+ puts out unless out.empty?
61
+ puts err unless err.empty?
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ total_color = some_failed ? red : green
68
+ puts(total_color % (spec_format % totals.to_a))
69
+ exit 1 if some_failed
70
+ end
@@ -0,0 +1,18 @@
1
+ desc 'update changelog'
2
+ task :changelog do
3
+ File.open('CHANGELOG', 'w+') do |changelog|
4
+ `git log -z --abbrev-commit`.split("\0").each do |commit|
5
+ next if commit =~ /^Merge: \d*/
6
+ ref, author, time, _, title, _, message = commit.split("\n", 7)
7
+ ref = ref[/commit ([0-9a-f]+)/, 1]
8
+ author = author[/Author: (.*)/, 1].strip
9
+ time = Time.parse(time[/Date: (.*)/, 1]).utc
10
+ title.strip!
11
+
12
+ changelog.puts "[#{ref} | #{time}] #{author}"
13
+ changelog.puts '', " * #{title}"
14
+ changelog.puts '', message.rstrip if message
15
+ changelog.puts
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2008-2009 The Rubyists, LLC (effortless systems) <rubyists@rubyists.com>
2
+ # Distributed under the terms of the MIT license.
3
+ # See the LICENSE file that accompanied this software for the full MIT License text
4
+ #
5
+ require "pathname"
6
+ task :legal do
7
+ license = Pathname("LICENSE")
8
+ license.open("w+") do |f|
9
+ f.puts PROJECT_COPYRIGHT
10
+ end unless license.file? and license.read == PROJECT_COPYRIGHT
11
+ doc = Pathname("doc/LEGAL")
12
+ doc.open("w+") do |f|
13
+ f.puts "LICENSE"
14
+ end unless doc.file?
15
+ end
16
+
17
+ desc "add copyright summary to all .rb files in the distribution"
18
+ task :copyright => [:legal] do
19
+ doc = Pathname("doc/LEGAL")
20
+ ignore = doc.readlines.
21
+ select { |line| line.strip!; Pathname(line).file? }.
22
+ map { |file| Pathname(file).expand_path }
23
+
24
+ puts "adding copyright summary to files that don't have it currently"
25
+ puts PROJECT_COPYRIGHT_SUMMARY
26
+ puts
27
+
28
+ (Pathname.glob('{controller,model,app,lib,test,spec}/**/*{.rb}') +
29
+ Pathname.glob("tasks/*.rake") +
30
+ Pathname.glob("Rakefile")).each do |file|
31
+ next if ignore.include? file.expand_path
32
+ lines = file.readlines.map{ |l| l.chomp }
33
+ unless lines.first(PROJECT_COPYRIGHT_SUMMARY.size) == PROJECT_COPYRIGHT_SUMMARY
34
+ oldlines = file.readlines
35
+ file.open("w+") { |f| f.puts PROJECT_COPYRIGHT_SUMMARY + oldlines }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ require 'rake/gempackagetask'
2
+
3
+ desc "make a gemspec"
4
+ task :gemspec => [:manifest, :changelog, :authors] do
5
+ gemspec_file = "#{GEMSPEC.name}.gemspec"
6
+ File.open(gemspec_file, 'w+'){|gs| gs.puts(GEMSPEC.to_ruby) }
7
+ end
8
+
9
+ desc "package and install from gemspec"
10
+ task :install => [:gemspec] do
11
+ sh "gem build #{GEMSPEC.name}.gemspec"
12
+ sh "gem install #{GEMSPEC.name}-#{GEMSPEC.version}.gem"
13
+ end
14
+
15
+ desc "uninstall the gem"
16
+ task :uninstall => [:clean] do
17
+ sh %{gem uninstall -x #{GEMSPEC.name}}
18
+ end
19
+
20
+ Rake::GemPackageTask.new(GEMSPEC) do |p|
21
+ p.need_tar = true
22
+ p.need_zip = true
23
+ end
@@ -0,0 +1,76 @@
1
+ task :gem_installer do
2
+ class GemInstaller
3
+ def initialize(options = {}, &block)
4
+ @gems = []
5
+ @options = options
6
+
7
+ run(&block)
8
+ end
9
+
10
+ def run(&block)
11
+ instance_eval(&block) if block_given?
12
+ end
13
+
14
+ def gem(name, version = nil, options = {})
15
+ if version.respond_to?(:merge!)
16
+ options = version
17
+ else
18
+ options[:version] = version
19
+ end
20
+
21
+ @gems << [name, options]
22
+ end
23
+
24
+ def setup_gemspec(gemspec)
25
+ gemspec.dependencies.each do |dependency|
26
+ dependency.version_requirements.as_list.each do |version|
27
+ gem(dependency.name, version)
28
+ end
29
+ end
30
+
31
+ setup
32
+ end
33
+
34
+ def setup
35
+ require 'rubygems'
36
+ require 'rubygems/dependency_installer'
37
+
38
+ @gems.each do |name, options|
39
+ setup_gem(name, options)
40
+ end
41
+ end
42
+
43
+ def setup_gem(name, options, try_install = true)
44
+ print "activating #{name} ... "
45
+ Gem.activate(name, *[options[:version]].compact)
46
+ require(options[:lib] || name)
47
+ puts "success."
48
+ rescue LoadError => error
49
+ puts error
50
+ install_gem(name, options) if try_install
51
+ setup_gem(name, options, try_install = false)
52
+ end
53
+
54
+ def install_gem(name, options)
55
+ installer = Gem::DependencyInstaller.new(options)
56
+
57
+ temp_argv(options[:extconf]) do
58
+ print "Installing #{name} ... "
59
+ installer.install(name, options[:version])
60
+ puts "done."
61
+ end
62
+ end
63
+
64
+ def temp_argv(extconf)
65
+ if extconf ||= @options[:extconf]
66
+ old_argv = ARGV.clone
67
+ ARGV.replace(extconf.split(' '))
68
+ end
69
+
70
+ yield
71
+
72
+ ensure
73
+ ARGV.replace(old_argv) if extconf
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,6 @@
1
+ desc 'install dependencies'
2
+ task :install_dependencies => [:gem_installer] do
3
+ GemInstaller.new do
4
+ setup_gemspec(GEMSPEC)
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ desc 'update manifest'
2
+ task :manifest do
3
+ File.open('MANIFEST', 'w+'){|io| io.puts(*GEMSPEC.files) }
4
+ end
@@ -0,0 +1,23 @@
1
+ desc 'code coverage'
2
+ task :rcov => :clean do
3
+ specs = PROJECT_SPECS
4
+
5
+ ignore = %w[ gem rack bacon innate hpricot nagoro/lib/nagoro ]
6
+
7
+ if RUBY_VERSION >= '1.8.7'
8
+ ignore << 'begin_with' << 'end_with'
9
+ end
10
+ if RUBY_VERSION < '1.9'
11
+ ignore << 'fiber'
12
+ end
13
+
14
+ ignored = ignore.join(',')
15
+
16
+ cmd = "rcov --aggregate coverage.data --sort coverage -t --%s -x '#{ignored}' %s"
17
+
18
+ while spec = specs.shift
19
+ puts '', "Gather coverage for #{spec} ..."
20
+ html = specs.empty? ? 'html' : 'no-html'
21
+ sh(cmd % [html, spec])
22
+ end
23
+ end
@@ -0,0 +1,53 @@
1
+ namespace :release do
2
+ task :all => [:release_github, :release_rubyforge]
3
+
4
+ desc 'Display instructions to release on github'
5
+ task :github => [:reversion, :gemspec] do
6
+ name, version = GEMSPEC.name, GEMSPEC.version
7
+
8
+ puts <<INSTRUCTIONS
9
+ First add the relevant files:
10
+
11
+ git add AUTHORS MANIFEST CHANGELOG #{name}.gemspec lib/#{name}/version.rb
12
+
13
+ Then commit them, tag the commit, and push:
14
+
15
+ git commit -m 'Version #{version}'
16
+ git tag -a -m '#{version}' '#{version}'
17
+ git push
18
+
19
+ INSTRUCTIONS
20
+
21
+ end
22
+
23
+ # TODO: Not tested
24
+ desc 'Display instructions to release on rubyforge'
25
+ task :rubyforge => [:reversion, :gemspec, :package] do
26
+ name, version = GEMSPEC.name, GEMSPEC.version.to_s
27
+
28
+ puts <<INSTRUCTIONS
29
+ To publish to rubyforge do following:
30
+
31
+ rubyforge login
32
+ rubyforge add_release #{name} #{name} #{version.dump} pkg/#{name}-#{version}.gem
33
+
34
+ After you have done these steps, see:
35
+
36
+ VERSION=#{version.dump} rake release:rubyforge_archives
37
+
38
+ INSTRUCTIONS
39
+ end
40
+
41
+ desc 'Display instructions to add archives after release:rubyforge'
42
+ task :rubyforge_archives do
43
+ name, version = GEMSPEC.name, GEMSPEC.version.to_s
44
+ p name => version
45
+ puts "Adding archives for distro packagers is:", ""
46
+
47
+ Dir["pkg/#{name}-#{version}.{tgz,zip}"].each do |file|
48
+ puts "rubyforge add_file %s %s %p %p" % [name, name, version, file]
49
+ end
50
+
51
+ puts
52
+ end
53
+ end
@@ -0,0 +1,8 @@
1
+ desc "update version.rb"
2
+ task :reversion do
3
+ File.open("lib/#{GEMSPEC.name}/version.rb", 'w+') do |file|
4
+ file.puts("module #{PROJECT_MODULE}")
5
+ file.puts(' VERSION = %p' % GEMSPEC.version.to_s)
6
+ file.puts('end')
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ desc 'install all possible dependencies'
2
+ task :setup => :gem_installer do
3
+ GemInstaller.new do
4
+ # core
5
+
6
+ # spec
7
+ gem 'bacon'
8
+ gem 'rcov'
9
+
10
+ # doc
11
+ gem 'yard'
12
+
13
+ setup
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ desc 'Generate YARD documentation'
2
+ task :yard => :clean do
3
+ sh("yardoc -o ydoc --protected -r #{PROJECT_README} lib/**/*.rb tasks/*.rake")
4
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ezamar
3
+ version: !ruby/object:Gem::Version
4
+ version: "2009.06"
5
+ platform: ruby
6
+ authors:
7
+ - Michael Fellinger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-04 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A light-weight and simple templating engine for Ruby.
17
+ email: manveru@rubyists.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - AUTHORS
26
+ - CHANGELOG
27
+ - MANIFEST
28
+ - README
29
+ - README.md
30
+ - Rakefile
31
+ - ezamar.gemspec
32
+ - lib/ezamar.rb
33
+ - lib/ezamar/element.rb
34
+ - lib/ezamar/engine.rb
35
+ - lib/ezamar/morpher.rb
36
+ - lib/ezamar/render_partial.rb
37
+ - lib/ezamar/version.rb
38
+ - misc/textpow.syntax
39
+ - spec/helper.rb
40
+ - tasks/authors.rake
41
+ - tasks/bacon.rake
42
+ - tasks/changelog.rake
43
+ - tasks/copyright.rake
44
+ - tasks/gem.rake
45
+ - tasks/gem_installer.rake
46
+ - tasks/install_dependencies.rake
47
+ - tasks/manifest.rake
48
+ - tasks/rcov.rake
49
+ - tasks/release.rake
50
+ - tasks/reversion.rake
51
+ - tasks/setup.rake
52
+ - tasks/yard.rake
53
+ has_rdoc: true
54
+ homepage: http://github.com/manveru/ezamar
55
+ licenses: []
56
+
57
+ post_install_message: |
58
+ ============================================================
59
+
60
+ Thank you for installing Ezamar!
61
+
62
+ ============================================================
63
+
64
+ rdoc_options: []
65
+
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ version:
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ version:
80
+ requirements: []
81
+
82
+ rubyforge_project: ezamar
83
+ rubygems_version: 1.3.3
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: A light-weight and simple templating engine for Ruby.
87
+ test_files: []
88
+