instrument 0.1.0
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/CHANGELOG +0 -0
- data/LICENSE +20 -0
- data/README +97 -0
- data/Rakefile +45 -0
- data/lib/instrument.rb +27 -0
- data/lib/instrument/control.rb +269 -0
- data/lib/instrument/control_builder.rb +71 -0
- data/lib/instrument/errors.rb +35 -0
- data/lib/instrument/version.rb +35 -0
- data/spec/control_templates/image_control.xhtml.haml +1 -0
- data/spec/control_templates/select_control.atom.rxml +19 -0
- data/spec/control_templates/select_control.directory.haml/explanation.txt +2 -0
- data/spec/control_templates/select_control.html.mab +5 -0
- data/spec/control_templates/select_control.json.erb +14 -0
- data/spec/control_templates/select_control.txt.bogus +2 -0
- data/spec/control_templates/select_control.xhtml.haml +4 -0
- data/spec/control_templates/select_control.xml.haml +2 -0
- data/spec/instrument/control_builder_spec.rb +37 -0
- data/spec/instrument/control_spec.rb +179 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +13 -0
- data/tasks/browse.rake +43 -0
- data/tasks/clobber.rake +2 -0
- data/tasks/gem.rake +62 -0
- data/tasks/git.rake +27 -0
- data/tasks/metrics.rake +22 -0
- data/tasks/rdoc.rake +29 -0
- data/tasks/rubyforge.rake +77 -0
- data/tasks/spec.rake +43 -0
- data/website/index.html +95 -0
- metadata +104 -0
data/CHANGELOG
ADDED
File without changes
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Instrument, Copyright (c) 2008 Day Automation Systems, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
== Instrument
|
2
|
+
|
3
|
+
Homepage:: instrument.rubyforge.org[http://instrument.rubyforge.org/]
|
4
|
+
Author:: Bob Aman (mailto:bob@sporkmonger.com)
|
5
|
+
Copyright:: Copyright © 2008 Day Automation Systems, Inc.
|
6
|
+
License:: MIT
|
7
|
+
|
8
|
+
== Description
|
9
|
+
|
10
|
+
Instrument is a simple library for producing dynamically generated "controls"
|
11
|
+
with various templating languages.
|
12
|
+
|
13
|
+
== Features
|
14
|
+
|
15
|
+
* Generate controls with Erb, Haml, Markaby, or XML Builder. Instrument
|
16
|
+
doesn't care what template language you prefer.
|
17
|
+
* Output XHTML, XML, or JSON. Instrument doesn't care what your output
|
18
|
+
format is.
|
19
|
+
|
20
|
+
== Example Usage
|
21
|
+
|
22
|
+
select_control = SelectControl.new(:name => "base", :selections => [
|
23
|
+
{:label => "One", :value => "1"},
|
24
|
+
{:label => "Two", :value => "2"},
|
25
|
+
{:label => "Three", :value => "3"},
|
26
|
+
{:label => "Four", :value => "4"}
|
27
|
+
])
|
28
|
+
xhtml_output = select_control.to_xhtml
|
29
|
+
|
30
|
+
or
|
31
|
+
|
32
|
+
include Instrument::ControlBuilder
|
33
|
+
|
34
|
+
select_control(:name => "base", :selections => [
|
35
|
+
{:label => "One", :value => "1"},
|
36
|
+
{:label => "Two", :value => "2"},
|
37
|
+
{:label => "Three", :value => "3"},
|
38
|
+
{:label => "Four", :value => "4"}
|
39
|
+
]).to_xhtml
|
40
|
+
|
41
|
+
select_control.rb:
|
42
|
+
|
43
|
+
require "instrument"
|
44
|
+
|
45
|
+
class SelectControl < Instrument::Control
|
46
|
+
class Option
|
47
|
+
def initialize(label, value)
|
48
|
+
@label, @value = label, value
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_accessor :label
|
52
|
+
attr_accessor :value
|
53
|
+
end
|
54
|
+
|
55
|
+
def element_id
|
56
|
+
return self.options[:id] || self.options[:name]
|
57
|
+
end
|
58
|
+
|
59
|
+
def element_name
|
60
|
+
return self.options[:name]
|
61
|
+
end
|
62
|
+
|
63
|
+
def selections
|
64
|
+
if !defined?(@selections) || @selections == nil
|
65
|
+
@selections = []
|
66
|
+
for selection in self.options[:selections]
|
67
|
+
if selection.kind_of?(Hash)
|
68
|
+
@selections << Option.new(selection[:label], selection[:value])
|
69
|
+
else
|
70
|
+
@selections << Option.new(selection, selection)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
return @selections
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
select.xhtml.haml:
|
79
|
+
|
80
|
+
%select{:id => element_id, :name => element_name}
|
81
|
+
- for selection in selections
|
82
|
+
%option{:value => selection.value}
|
83
|
+
= selection.label
|
84
|
+
|
85
|
+
== Requirements
|
86
|
+
|
87
|
+
* Instrument has no explicit dependencies. If you want to output Haml, you
|
88
|
+
will need the Haml library installed. Same goes for any of the other
|
89
|
+
template languages.
|
90
|
+
|
91
|
+
== Install
|
92
|
+
|
93
|
+
* sudo gem install instrument
|
94
|
+
* sudo gem install haml (optional)
|
95
|
+
* sudo gem install erubis (optional)
|
96
|
+
* sudo gem install markaby (optional)
|
97
|
+
* sudo gem install builder (optional)
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
lib_dir = File.expand_path(File.join(File.dirname(__FILE__), "lib"))
|
2
|
+
$:.unshift(lib_dir)
|
3
|
+
$:.uniq!
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'rake'
|
7
|
+
require 'rake/testtask'
|
8
|
+
require 'rake/rdoctask'
|
9
|
+
require 'rake/packagetask'
|
10
|
+
require 'rake/gempackagetask'
|
11
|
+
require 'rake/contrib/rubyforgepublisher'
|
12
|
+
require 'spec/rake/spectask'
|
13
|
+
|
14
|
+
require File.join(File.dirname(__FILE__), 'lib/instrument', 'version')
|
15
|
+
|
16
|
+
PKG_DISPLAY_NAME = 'Instrument'
|
17
|
+
PKG_NAME = PKG_DISPLAY_NAME.downcase
|
18
|
+
PKG_VERSION = Instrument::VERSION::STRING
|
19
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
20
|
+
|
21
|
+
RELEASE_NAME = "REL #{PKG_VERSION}"
|
22
|
+
|
23
|
+
RUBY_FORGE_PROJECT = PKG_NAME
|
24
|
+
RUBY_FORGE_USER = "sporkmonger"
|
25
|
+
RUBY_FORGE_PATH = "/var/www/gforge-projects/#{RUBY_FORGE_PROJECT}"
|
26
|
+
RUBY_FORGE_URL = "http://#{RUBY_FORGE_PROJECT}.rubyforge.org/"
|
27
|
+
|
28
|
+
PKG_SUMMARY = "Template-based Controls"
|
29
|
+
PKG_DESCRIPTION = <<-TEXT
|
30
|
+
Instrument is a simple library for producing dynamically generated
|
31
|
+
"controls" with various templating languages.
|
32
|
+
TEXT
|
33
|
+
|
34
|
+
PKG_FILES = FileList[
|
35
|
+
"lib/**/*", "spec/**/*", "vendor/**/*",
|
36
|
+
"tasks/**/*", "website/**/*",
|
37
|
+
"[A-Z]*", "Rakefile"
|
38
|
+
].exclude(/database\.yml/).exclude(/[_\.]git$/)
|
39
|
+
|
40
|
+
task :default => "spec:verify"
|
41
|
+
|
42
|
+
WINDOWS = (RUBY_PLATFORM =~ /mswin|win32|mingw|bccwin|cygwin/) rescue false
|
43
|
+
SUDO = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS'])
|
44
|
+
|
45
|
+
Dir['tasks/**/*.rake'].each { |rake| load rake }
|
data/lib/instrument.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# ++
|
2
|
+
# Instrument, Copyright (c) 2008 Day Automation Systems, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
# --
|
23
|
+
|
24
|
+
require "instrument/version"
|
25
|
+
require "instrument/errors"
|
26
|
+
require "instrument/control"
|
27
|
+
require "instrument/control_builder"
|
@@ -0,0 +1,269 @@
|
|
1
|
+
# ++
|
2
|
+
# Instrument, Copyright (c) 2008 Day Automation Systems, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
# --
|
23
|
+
|
24
|
+
require "instrument/version"
|
25
|
+
require "instrument/errors"
|
26
|
+
|
27
|
+
# This variable stores a list of all paths to search for when locating a
|
28
|
+
# named control.
|
29
|
+
$CONTROL_PATH = ["."]
|
30
|
+
if defined?(RAILS_ROOT)
|
31
|
+
$CONTROL_PATH.unshift(File.join(RAILS_ROOT, "app/controls"))
|
32
|
+
end
|
33
|
+
|
34
|
+
module Instrument
|
35
|
+
##
|
36
|
+
# The Instrument::Control class provides a simple way to render nested
|
37
|
+
# templates.
|
38
|
+
#
|
39
|
+
# == Example
|
40
|
+
#
|
41
|
+
# select_control = SelectControl.new(:name => "base", :selections => [
|
42
|
+
# {:label => "One", :value => "1"},
|
43
|
+
# {:label => "Two", :value => "2"},
|
44
|
+
# {:label => "Three", :value => "3"},
|
45
|
+
# {:label => "Four", :value => "4"}
|
46
|
+
# ])
|
47
|
+
# xhtml_output = select_control.to_xhtml
|
48
|
+
class Control
|
49
|
+
##
|
50
|
+
# Registers a template type. Takes a symbol naming the type, and a
|
51
|
+
# block which takes a String as input and an Object to use as the
|
52
|
+
# execution context and returns the rendered template output as a
|
53
|
+
# String. The block should ensure that all necessary libraries are
|
54
|
+
# loaded.
|
55
|
+
#
|
56
|
+
# @param [Array] type_list the template types being registered
|
57
|
+
# @yield the block generates the template output
|
58
|
+
# @yieldparam [String] the template input
|
59
|
+
# @yieldparam [Object] the execution context for the template
|
60
|
+
def self.register_type(*type_list, &block)
|
61
|
+
# Ensure the @@type_map is initialized.
|
62
|
+
self.types
|
63
|
+
|
64
|
+
for type in type_list
|
65
|
+
# Normalize to symbol
|
66
|
+
type = type.to_s.to_sym
|
67
|
+
@@type_map[type] = block
|
68
|
+
end
|
69
|
+
return nil
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Returns a list of registered template types.
|
74
|
+
#
|
75
|
+
# @return [Array] a list of Symbols for the registered template types
|
76
|
+
# @see Instrument::Control.register_type
|
77
|
+
def self.types
|
78
|
+
if !defined?(@@type_map) || @@type_map == nil
|
79
|
+
@@type_map = {}
|
80
|
+
end
|
81
|
+
return @@type_map.keys
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Returns the processor Proc for the specified type.
|
86
|
+
#
|
87
|
+
# @param [Array] type_list the template types being registered
|
88
|
+
# @raise ArgumentError raises an error if the type is invalid.
|
89
|
+
# @return [Proc] the proc that handles template execution
|
90
|
+
# @see Instrument::Control.register_type
|
91
|
+
def self.processor(type)
|
92
|
+
# Normalize to symbol
|
93
|
+
type = type.to_s.to_sym
|
94
|
+
|
95
|
+
if !self.types.include?(type)
|
96
|
+
raise ArgumentError,
|
97
|
+
"Unrecognized template type: #{type.inspect}\n" +
|
98
|
+
"Valid types: " +
|
99
|
+
"#{(self.types.map {|t| t.inspect}).join(", ")}"
|
100
|
+
end
|
101
|
+
|
102
|
+
return @@type_map[type]
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# Registers subclasses with the Control base class. Called automatically.
|
107
|
+
#
|
108
|
+
# @param [Class] klass the subclass that is extending Control
|
109
|
+
def self.inherited(klass)
|
110
|
+
if !defined?(@@control_subclasses) || @@control_subclasses == nil
|
111
|
+
@@control_subclasses = []
|
112
|
+
end
|
113
|
+
@@control_subclasses << klass
|
114
|
+
@@control_subclasses.uniq!
|
115
|
+
super
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Looks up a Control by name.
|
120
|
+
#
|
121
|
+
# @param [String] control_name the control name of the Control
|
122
|
+
# @return [Instrument::Control, NilClass] the desired control or nil
|
123
|
+
# @see Instrument::Control.control_name
|
124
|
+
def self.lookup(control_name)
|
125
|
+
for control_subclass in (@@control_subclasses || [])
|
126
|
+
if control_subclass.control_name == control_name
|
127
|
+
return control_subclass
|
128
|
+
end
|
129
|
+
end
|
130
|
+
return nil
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# Creates a new Control object. Subclasses should not override this.
|
135
|
+
#
|
136
|
+
# @param [Hash] options a set of options required by the control
|
137
|
+
# @return [Instrument::Control] the instanitated control
|
138
|
+
def initialize(options={})
|
139
|
+
@options = options
|
140
|
+
end
|
141
|
+
|
142
|
+
##
|
143
|
+
# Returns the options that were used to create the Control.
|
144
|
+
#
|
145
|
+
# @return [Hash] a set of options required by the control
|
146
|
+
attr_reader :options
|
147
|
+
|
148
|
+
##
|
149
|
+
# Returns the Control's name. By default, this is the control's class
|
150
|
+
# name, tranformed into This method may be overridden by a Control.
|
151
|
+
#
|
152
|
+
# @return [String] the control name
|
153
|
+
def self.control_name
|
154
|
+
return nil if self.name == "Instrument::Control"
|
155
|
+
return self.name.
|
156
|
+
gsub(/^.*::/, "").
|
157
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, "\\1_\\2").
|
158
|
+
gsub(/([a-z\d])([A-Z])/, "\\1_\\2").
|
159
|
+
tr("-", "_").
|
160
|
+
downcase
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
# Relays to_format messages to the render method.
|
165
|
+
#
|
166
|
+
# @param [Symbol] method the method being called
|
167
|
+
# @param [Array] params the method's parameters
|
168
|
+
# @param [Proc] block the block being passed to the method
|
169
|
+
# @return [Object] the return value
|
170
|
+
# @raise NoMethodError if the method wasn't handled
|
171
|
+
# @see Instrument::Control#render
|
172
|
+
def method_missing(method, *params, &block)
|
173
|
+
if method.to_s =~ /^to_/
|
174
|
+
format = method.to_s.gsub(/^to_/, "")
|
175
|
+
self.send(:render, format, *params, &block)
|
176
|
+
else
|
177
|
+
control_class = self.class.lookup(method.to_s)
|
178
|
+
if control_class != nil
|
179
|
+
control_class.new(*params, &block)
|
180
|
+
else
|
181
|
+
raise NoMethodError,
|
182
|
+
"undefined method `#{method}' for " +
|
183
|
+
"#{self.inspect}:#{self.class.name}"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
##
|
189
|
+
# Renders a control in a specific format.
|
190
|
+
#
|
191
|
+
# @param [String] format the format name for the template output
|
192
|
+
# @return [String] the rendered output in the desired format
|
193
|
+
# @raise Instrument::ResourceNotFoundError if the template is missing
|
194
|
+
# @raise Instrument::InvalidTemplateEngineError if type isn't registered
|
195
|
+
def render(format)
|
196
|
+
# Locate the template.
|
197
|
+
path = nil
|
198
|
+
for load_path in $CONTROL_PATH
|
199
|
+
full_name = File.expand_path(
|
200
|
+
File.join(load_path, self.class.control_name))
|
201
|
+
|
202
|
+
# Check to make sure the requested template is within the load path
|
203
|
+
# to avoid inadvertent rendering of say, /etc/passwd
|
204
|
+
next if full_name.index(File.expand_path(load_path)) != 0
|
205
|
+
|
206
|
+
templates = Dir.glob(full_name + ".#{format}.*")
|
207
|
+
|
208
|
+
# Select the first template matched. If there's more than one,
|
209
|
+
# the extras will be ignored.
|
210
|
+
template = templates.first
|
211
|
+
if template != nil
|
212
|
+
path = template
|
213
|
+
break
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
if path == nil
|
218
|
+
raise Instrument::ResourceNotFoundError,
|
219
|
+
"Template not found: '#{self.class.control_name}.#{format}.*'"
|
220
|
+
elsif File.directory?(path)
|
221
|
+
raise Instrument::ResourceNotFoundError,
|
222
|
+
"Template not found: '#{self.class.control_name}.#{format}.*'"
|
223
|
+
end
|
224
|
+
|
225
|
+
# Normalize to symbol
|
226
|
+
type = File.extname(path).gsub(/^\./, "").to_s
|
227
|
+
if type != "" && !self.class.types.include?(type.to_sym)
|
228
|
+
raise Instrument::InvalidTemplateEngineError,
|
229
|
+
"Unrecognized template type: #{type.inspect}\n" +
|
230
|
+
"Valid types: [" +
|
231
|
+
"#{(self.class.types.map {|t| t.inspect}).join(", ")}]"
|
232
|
+
end
|
233
|
+
raw_content = File.open(path, "r") do |file|
|
234
|
+
file.read
|
235
|
+
end
|
236
|
+
|
237
|
+
begin
|
238
|
+
return self.class.processor(type).call(raw_content, self)
|
239
|
+
rescue Exception => e
|
240
|
+
e.message <<
|
241
|
+
"\nError occurred while rendering " +
|
242
|
+
"'#{self.class.control_name}.#{format}.#{type}'"
|
243
|
+
raise e
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
# Register the default types.
|
250
|
+
Instrument::Control.register_type(:haml) do |input, context|
|
251
|
+
require "haml"
|
252
|
+
Haml::Engine.new(input, {:attr_wrapper => "\""}).render(context)
|
253
|
+
end
|
254
|
+
Instrument::Control.register_type(:erb, :rhtml) do |input, context|
|
255
|
+
begin; require "erubis"; rescue LoadError; require "erb"; end
|
256
|
+
erb = Erubis::Eruby.new(input) rescue ERB.new(input)
|
257
|
+
erb.result(context.send(:binding))
|
258
|
+
end
|
259
|
+
Instrument::Control.register_type(:mab) do |input, context|
|
260
|
+
require "markaby"
|
261
|
+
Markaby::Builder.new({}, context).capture do
|
262
|
+
eval(input)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
Instrument::Control.register_type(:rxml) do |input, context|
|
266
|
+
require "builder"
|
267
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
268
|
+
eval(input, context.send(:binding))
|
269
|
+
end
|