ezamar 2009.06

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/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
+