merb_comatose 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +4 -0
- data/Rakefile +52 -0
- data/TODO +5 -0
- data/lib/class_options.rb +36 -0
- data/lib/comatose/comatose_drop.rb +64 -0
- data/lib/comatose/configuration.rb +69 -0
- data/lib/comatose/page_wrapper.rb +119 -0
- data/lib/comatose/processing_context.rb +69 -0
- data/lib/comatose/version.rb +4 -0
- data/lib/liquid/block.rb +96 -0
- data/lib/liquid/context.rb +190 -0
- data/lib/liquid/document.rb +17 -0
- data/lib/liquid/drop.rb +48 -0
- data/lib/liquid/errors.rb +7 -0
- data/lib/liquid/extensions.rb +53 -0
- data/lib/liquid/file_system.rb +62 -0
- data/lib/liquid/htmltags.rb +64 -0
- data/lib/liquid/standardfilters.rb +111 -0
- data/lib/liquid/standardtags.rb +399 -0
- data/lib/liquid/strainer.rb +42 -0
- data/lib/liquid/tag.rb +25 -0
- data/lib/liquid/template.rb +88 -0
- data/lib/liquid/variable.rb +39 -0
- data/lib/liquid.rb +52 -0
- data/lib/merb_comatose/merbtasks.rb +6 -0
- data/lib/merb_comatose.rb +30 -0
- data/lib/redcloth.rb +1129 -0
- data/lib/support/class_options.rb +36 -0
- data/lib/text_filters/markdown.rb +14 -0
- data/lib/text_filters/markdown_smartypants.rb +15 -0
- data/lib/text_filters/none.rb +8 -0
- data/lib/text_filters/rdoc.rb +13 -0
- data/lib/text_filters/simple.rb +8 -0
- data/lib/text_filters/textile.rb +15 -0
- data/lib/text_filters.rb +138 -0
- data/spec/merb_comatose_spec.rb +7 -0
- data/spec/spec_helper.rb +1 -0
- metadata +97 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 YOUR NAME
|
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
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
require 'merb-core'
|
5
|
+
require 'merb-core/tasks/merb'
|
6
|
+
|
7
|
+
GEM_NAME = "merb_comatose"
|
8
|
+
GEM_VERSION = "0.0.2"
|
9
|
+
AUTHOR = "Jacques Crocker"
|
10
|
+
EMAIL = "merbjedi@gmail.com"
|
11
|
+
HOMEPAGE = "http://merbjedi.com/"
|
12
|
+
SUMMARY = "Partial Port of Comatose with focus on rendering from Comatose Pages (no admin yet)"
|
13
|
+
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
s.rubyforge_project = 'merb'
|
16
|
+
s.name = GEM_NAME
|
17
|
+
s.version = GEM_VERSION
|
18
|
+
s.platform = Gem::Platform::RUBY
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
|
21
|
+
s.summary = SUMMARY
|
22
|
+
s.description = s.summary
|
23
|
+
s.author = AUTHOR
|
24
|
+
s.email = EMAIL
|
25
|
+
s.homepage = HOMEPAGE
|
26
|
+
|
27
|
+
# s.add_dependency('merb', '>= 1.0')
|
28
|
+
|
29
|
+
s.require_path = 'lib'
|
30
|
+
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
|
31
|
+
end
|
32
|
+
|
33
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
34
|
+
pkg.gem_spec = spec
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "install the plugin as a gem"
|
38
|
+
task :install do
|
39
|
+
Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Uninstall the gem"
|
43
|
+
task :uninstall do
|
44
|
+
Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Create a gemspec file"
|
48
|
+
task :gemspec do
|
49
|
+
File.open("#{GEM_NAME}.gemspec", "w") do |file|
|
50
|
+
file.puts spec.to_ruby
|
51
|
+
end
|
52
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
class Class
|
2
|
+
def define_option(name, default=nil)
|
3
|
+
sym = name.to_sym
|
4
|
+
cattr_reader(sym)
|
5
|
+
cattr_writer(sym)
|
6
|
+
send("#{name.to_s}=", default)
|
7
|
+
end
|
8
|
+
|
9
|
+
def blockable_attr_accessor(sym)
|
10
|
+
module_eval(<<-EVAL, __FILE__, __LINE__)
|
11
|
+
def #{sym}(&block)
|
12
|
+
if block_given?
|
13
|
+
@#{sym} = block
|
14
|
+
else
|
15
|
+
@#{sym}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def #{sym}=(value)
|
19
|
+
@#{sym} = value
|
20
|
+
end
|
21
|
+
EVAL
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Module
|
26
|
+
def attr_accessor_with_default(sym, default = nil, &block)
|
27
|
+
raise 'Default value or block required' unless !default.nil? || block
|
28
|
+
define_method(sym, block_given? ? block : Proc.new { default })
|
29
|
+
module_eval(<<-EVAL, __FILE__, __LINE__)
|
30
|
+
def #{sym}=(value)
|
31
|
+
class << self; attr_reader :#{sym} end
|
32
|
+
@#{sym} = value
|
33
|
+
end
|
34
|
+
EVAL
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Comatose
|
2
|
+
|
3
|
+
class ComatoseDrop < ::Liquid::Drop
|
4
|
+
|
5
|
+
private :initialize
|
6
|
+
|
7
|
+
def before_method(method)
|
8
|
+
self.send(method.to_sym)
|
9
|
+
rescue
|
10
|
+
ComatoseController.logger.debug "Error calling #{method}: #{$!}"
|
11
|
+
raise $!
|
12
|
+
end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
# Define a new ComatoseDrop by name
|
16
|
+
def define( name, &block )
|
17
|
+
d = ComatoseDrop.new
|
18
|
+
d.instance_eval(&block)
|
19
|
+
Comatose.registered_drops[name] = d
|
20
|
+
rescue
|
21
|
+
ComatoseController.logger.debug "Drop '#{name}' was not included: #{$!}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
|
28
|
+
# Returns/initializes a hash for storing ComatoseDrops
|
29
|
+
def registered_drops
|
30
|
+
@registered_drops ||= {}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Simple wrapper around the ProcessingContext.define method
|
34
|
+
# I think Comatose.define_drop is probably simpler to remember too
|
35
|
+
def define_drop(name, &block)
|
36
|
+
ComatoseDrop.define(name, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Registers a 'filter' for Liquid use
|
40
|
+
def register_filter(module_name)
|
41
|
+
Liquid::Template.register_filter(module_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
#
|
49
|
+
# Some Default Filters/Drops
|
50
|
+
#
|
51
|
+
|
52
|
+
module IncludeFilter
|
53
|
+
def include(input)
|
54
|
+
page = ComatosePage.find_by_path(input)
|
55
|
+
params = @context['params']
|
56
|
+
# TODO: Add more of the context into the included page's context...
|
57
|
+
page.to_html( { 'params' => params } )
|
58
|
+
rescue
|
59
|
+
"Page at <tt>#{input}</tt> could not be found. <pre>#{$!}</pre>"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
Comatose.register_filter IncludeFilter
|
64
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Comatose
|
2
|
+
|
3
|
+
def self.config
|
4
|
+
@@config ||= Configuration.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.configure(&block)
|
8
|
+
raise "#configure must be sent a block" unless block_given?
|
9
|
+
yield config
|
10
|
+
config.validate!
|
11
|
+
end
|
12
|
+
|
13
|
+
# All of the 'mount' points for Comatose
|
14
|
+
def self.mount_points
|
15
|
+
@@mount_points ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
# Adds a 'mount' point to the list of known roots...
|
19
|
+
def self.add_mount_point(path, info={:index=>''})
|
20
|
+
path = "/#{path}" unless path.starts_with? '/'
|
21
|
+
info[:root]=path
|
22
|
+
mount_points << info
|
23
|
+
end
|
24
|
+
|
25
|
+
class Configuration
|
26
|
+
|
27
|
+
attr_accessor_with_default :admin_title, 'Comatose'
|
28
|
+
attr_accessor_with_default :admin_includes, []
|
29
|
+
attr_accessor_with_default :admin_helpers, []
|
30
|
+
attr_accessor_with_default :admin_sub_title, 'The Micro CMS'
|
31
|
+
attr_accessor_with_default :content_type, 'utf-8'
|
32
|
+
attr_accessor_with_default :default_filter, '[No Filter]'
|
33
|
+
attr_accessor_with_default :default_processor, :liquid
|
34
|
+
attr_accessor_with_default :default_tree_level, 2
|
35
|
+
attr_accessor_with_default :disable_caching, false
|
36
|
+
attr_accessor_with_default :hidden_meta_fields, []
|
37
|
+
attr_accessor_with_default :helpers, []
|
38
|
+
attr_accessor_with_default :includes, []
|
39
|
+
attr_accessor_with_default :allow_import_export, true
|
40
|
+
|
41
|
+
# 'Blockable' setters
|
42
|
+
blockable_attr_accessor :authorization
|
43
|
+
blockable_attr_accessor :admin_authorization
|
44
|
+
blockable_attr_accessor :admin_get_author
|
45
|
+
blockable_attr_accessor :admin_get_root_page
|
46
|
+
blockable_attr_accessor :after_setup
|
47
|
+
|
48
|
+
def initialize
|
49
|
+
# Default procs for blockable attrs....
|
50
|
+
@authorization = Proc.new { true }
|
51
|
+
@admin_authorization = Proc.new { true }
|
52
|
+
@admin_get_author = Proc.new { request.env['REMOTE_ADDR'] }
|
53
|
+
@admin_get_root_page = Proc.new { ComatosePage.root }
|
54
|
+
@after_setup = Proc.new { true }
|
55
|
+
end
|
56
|
+
|
57
|
+
def validate!
|
58
|
+
# Rips through the config and validates it's, er, valid
|
59
|
+
raise ConfigurationError.new( "admin_get_author must be a Proc or Symbol" ) unless @admin_get_author.is_a? Proc or @admin_get_author.is_a? Symbol
|
60
|
+
raise ConfigurationError.new( "admin_authorization must be a Proc or Symbol" ) unless @admin_authorization.is_a? Proc or @admin_authorization.is_a? Symbol
|
61
|
+
raise ConfigurationError.new( "authorization must be a Proc or Symbol" ) unless @authorization.is_a? Proc or @authorization.is_a? Symbol
|
62
|
+
true
|
63
|
+
end
|
64
|
+
|
65
|
+
class ConfigurationError < StandardError; end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# Giving direct access to the AR model is disconcerting, so this wraps the AR
|
2
|
+
# Model to prevent access to certain, destructive behavior
|
3
|
+
class Comatose::PageWrapper
|
4
|
+
|
5
|
+
@@allowed_methods = %w(id full_path uri slug keywords title to_html filter_type author updated_on created_on)
|
6
|
+
@@custom_methods = %w(link content parent next previous children rchildren first_child last_child has_keyword)
|
7
|
+
|
8
|
+
attr_accessor :page
|
9
|
+
private :page
|
10
|
+
|
11
|
+
def initialize( page, locals={} )
|
12
|
+
@page = page
|
13
|
+
@keyword_lst = []
|
14
|
+
@keyword_hsh = {}
|
15
|
+
unless page.nil?
|
16
|
+
@keyword_lst = (page.keywords || '').downcase.split(',').map {|k| k.strip }
|
17
|
+
@keyword_lst.each {|kw| @keyword_hsh[kw] = true}
|
18
|
+
end
|
19
|
+
@locals = locals
|
20
|
+
end
|
21
|
+
|
22
|
+
def has_keyword?(keyword)
|
23
|
+
@page.has_keyword?(keyword)
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_keyword
|
27
|
+
@keyword_hsh
|
28
|
+
end
|
29
|
+
|
30
|
+
def next
|
31
|
+
@next_page ||= begin
|
32
|
+
if @page.lower_item.nil?
|
33
|
+
nil
|
34
|
+
else
|
35
|
+
Comatose::PageWrapper.new( @page.lower_item )
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def previous
|
41
|
+
@prev_page ||= begin
|
42
|
+
if @page.higher_item.nil?
|
43
|
+
nil
|
44
|
+
else
|
45
|
+
Comatose::PageWrapper.new( @page.higher_item )
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def first_child
|
51
|
+
children.first
|
52
|
+
end
|
53
|
+
|
54
|
+
def def last_child
|
55
|
+
children.last
|
56
|
+
end
|
57
|
+
|
58
|
+
# Generates a link to this page... You can pass in the link text,
|
59
|
+
# otherwise it will default to the page title.
|
60
|
+
def link( title=nil )
|
61
|
+
title = @page.title if title.nil?
|
62
|
+
TextFilters[@page.filter_type].create_link(title, @page.uri)
|
63
|
+
end
|
64
|
+
|
65
|
+
def content
|
66
|
+
@page.to_html( @locals )
|
67
|
+
end
|
68
|
+
|
69
|
+
def parent
|
70
|
+
@parent ||= begin
|
71
|
+
if @page.parent.nil?
|
72
|
+
nil
|
73
|
+
else
|
74
|
+
Comatose::PageWrapper.new( @page.parent )
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def children
|
80
|
+
# Cache the results so that you can have multiple calls to #children without a penalty
|
81
|
+
@children ||= @page.children.to_a.collect {|child| Comatose::PageWrapper.new( child, @locals )}
|
82
|
+
end
|
83
|
+
|
84
|
+
# Children, in reverse order
|
85
|
+
def rchildren
|
86
|
+
children.reverse
|
87
|
+
end
|
88
|
+
|
89
|
+
def [](key)
|
90
|
+
if @@allowed_methods.include? key.to_s #or page.attributes.has_key? key.to_s
|
91
|
+
page.send( key )
|
92
|
+
elsif @@custom_methods.include? key
|
93
|
+
self.send(key.to_sym)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def has_key?(key)
|
98
|
+
@@allowed_methods.include? key or @@custom_methods.include? key
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
@page.title
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_liquid
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
def method_missing(method_id, *args)
|
110
|
+
#STDERR.puts "Looking for method: #{method_id} (#{method_id.class.to_s}) in [#{@@allowed_methods.join(', ')}] or [#{page.attributes.keys.join(', ')}]"
|
111
|
+
if @@allowed_methods.include? method_id.to_s or page.attributes.has_key? method_id.to_s
|
112
|
+
page.send( method_id, *args)
|
113
|
+
else
|
114
|
+
# Access nazi says: NO ACCESS FOR YOU!!
|
115
|
+
# but he says it silently...
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# This is the rendering context object you have access to in text processing...
|
2
|
+
class Comatose::ProcessingContext
|
3
|
+
@@supported_methods = %w(page include)
|
4
|
+
|
5
|
+
def initialize( page, locals={} )
|
6
|
+
@locals = locals.stringify_keys if locals.respond_to? :stringify_keys
|
7
|
+
@page = Comatose::PageWrapper.new(page, @locals)
|
8
|
+
end
|
9
|
+
|
10
|
+
def page
|
11
|
+
@page
|
12
|
+
end
|
13
|
+
|
14
|
+
def include(path, locals={})
|
15
|
+
begin
|
16
|
+
page = ComatosePage.find_by_path(path)
|
17
|
+
page.to_html( @locals.merge(locals) )
|
18
|
+
rescue
|
19
|
+
"<p>Page at <tt>#{path}</tt> could not be found.</p>"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_by_path(path)
|
24
|
+
begin
|
25
|
+
page = ComatosePage.find_by_path(path)
|
26
|
+
Comatose::PageWrapper.new(page, @locals)
|
27
|
+
rescue
|
28
|
+
"<p>Page at <tt>#{path}</tt> could not be found.</p>"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def [](key)
|
33
|
+
if key.to_s.downcase == 'page'
|
34
|
+
@page
|
35
|
+
elsif @locals.has_key? key
|
36
|
+
@locals[key]
|
37
|
+
elsif Comatose.registered_drops.has_key? key
|
38
|
+
Comatose.registered_drops[key]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_key?(key)
|
43
|
+
@@supported_methods.include?(key) or @locals.has_key?(key) or Comatose.registered_drops.has_key?(key)
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_liquid
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_binding
|
51
|
+
binding
|
52
|
+
end
|
53
|
+
|
54
|
+
def method_missing(method_id, *args)
|
55
|
+
method_name = method_id.to_s
|
56
|
+
if @locals.has_key? method_name
|
57
|
+
@locals[method_name]
|
58
|
+
elsif Comatose.registered_drops.has_key? method_name
|
59
|
+
Comatose.registered_drops[method_name].context = self
|
60
|
+
Comatose.registered_drops[method_name]
|
61
|
+
else
|
62
|
+
"<!-- ProcessingContext: Couldn't find #{method_id} -->"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
|
data/lib/liquid/block.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
module Liquid
|
2
|
+
|
3
|
+
class Block < Tag
|
4
|
+
def parse(tokens)
|
5
|
+
@nodelist ||= []
|
6
|
+
@nodelist.clear
|
7
|
+
|
8
|
+
while token = tokens.shift
|
9
|
+
|
10
|
+
case token
|
11
|
+
when /^#{TagStart}/
|
12
|
+
if token =~ /^#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}$/
|
13
|
+
|
14
|
+
# if we found the proper block delimitor just end parsing here and let the outer block
|
15
|
+
# proceed
|
16
|
+
if block_delimiter == $1
|
17
|
+
end_tag
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
21
|
+
# fetch the tag from registered blocks
|
22
|
+
if tag = Template.tags[$1]
|
23
|
+
@nodelist << tag.new($2, tokens)
|
24
|
+
else
|
25
|
+
# this tag is not registered with the system
|
26
|
+
# pass it to the current block for special handling or error reporting
|
27
|
+
unknown_tag($1, $2, tokens)
|
28
|
+
end
|
29
|
+
else
|
30
|
+
raise SyntaxError, "Tag '#{token}' was not properly terminated with regexp: #{TagEnd.inspect} "
|
31
|
+
end
|
32
|
+
when /^#{VariableStart}/
|
33
|
+
@nodelist << create_variable(token)
|
34
|
+
when ''
|
35
|
+
# pass
|
36
|
+
else
|
37
|
+
@nodelist << token
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Make sure that its ok to end parsing in the current block.
|
42
|
+
# Effectively this method will throw and exception unless the current block is
|
43
|
+
# of type Document
|
44
|
+
assert_missing_delimitation!
|
45
|
+
end
|
46
|
+
|
47
|
+
def end_tag
|
48
|
+
end
|
49
|
+
|
50
|
+
def unknown_tag(tag, params, tokens)
|
51
|
+
case tag
|
52
|
+
when 'else'
|
53
|
+
raise SyntaxError, "#{block_name} tag does not expect else tag"
|
54
|
+
when 'end'
|
55
|
+
raise SyntaxError, "'end' is not a valid delimiter for #{block_name} tags. use #{block_delimiter}"
|
56
|
+
else
|
57
|
+
raise SyntaxError, "Unknown tag '#{tag}'"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def block_delimiter
|
62
|
+
"end#{block_name}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def block_name
|
66
|
+
self.class.name.scan(/\w+$/).first.downcase
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_variable(token)
|
70
|
+
token.scan(/^#{VariableStart}(.*)#{VariableEnd}$/) do |content|
|
71
|
+
return Variable.new(content.first)
|
72
|
+
end
|
73
|
+
raise SyntaxError.new("Variable '#{token}' was not properly terminated with regexp: #{VariableEnd.inspect} ")
|
74
|
+
end
|
75
|
+
|
76
|
+
def render(context)
|
77
|
+
render_all(@nodelist, context)
|
78
|
+
end
|
79
|
+
|
80
|
+
protected
|
81
|
+
|
82
|
+
def assert_missing_delimitation!
|
83
|
+
raise SyntaxError.new("#{block_name} tag was never closed")
|
84
|
+
end
|
85
|
+
|
86
|
+
def render_all(list, context)
|
87
|
+
list.collect do |token|
|
88
|
+
if token.respond_to?(:render)
|
89
|
+
token.render(context)
|
90
|
+
else
|
91
|
+
token.to_s
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|