personify 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. data/.gitignore +1 -0
  2. data/LICENSE +20 -0
  3. data/README.md +172 -0
  4. data/Rakefile +53 -0
  5. data/VERSION +1 -0
  6. data/doc/syntax_ideas.md +141 -0
  7. data/lib/personify/context.rb +55 -0
  8. data/lib/personify/parser/personify.rb +1071 -0
  9. data/lib/personify/parser/personify.treetop +107 -0
  10. data/lib/personify/parser/personify_node_classes.rb +121 -0
  11. data/lib/personify/template.rb +17 -0
  12. data/lib/personify.rb +8 -0
  13. data/script/generate_parser.rb +6 -0
  14. data/test/context_test.rb +122 -0
  15. data/test/fixtures/multiple_tags.txt +8 -0
  16. data/test/parse_runner.rb +60 -0
  17. data/test/parser_test.rb +291 -0
  18. data/test/test_helper.rb +16 -0
  19. data/vendor/treetop/.gitignore +5 -0
  20. data/vendor/treetop/History.txt +9 -0
  21. data/vendor/treetop/README +164 -0
  22. data/vendor/treetop/Rakefile +20 -0
  23. data/vendor/treetop/Treetop.tmbundle/Snippets/grammar ___ end.tmSnippet +20 -0
  24. data/vendor/treetop/Treetop.tmbundle/Snippets/rule ___ end.tmSnippet +18 -0
  25. data/vendor/treetop/Treetop.tmbundle/Syntaxes/Treetop Grammar.tmLanguage +251 -0
  26. data/vendor/treetop/Treetop.tmbundle/info.plist +10 -0
  27. data/vendor/treetop/bin/tt +28 -0
  28. data/vendor/treetop/doc/contributing_and_planned_features.markdown +103 -0
  29. data/vendor/treetop/doc/grammar_composition.markdown +65 -0
  30. data/vendor/treetop/doc/index.markdown +90 -0
  31. data/vendor/treetop/doc/pitfalls_and_advanced_techniques.markdown +51 -0
  32. data/vendor/treetop/doc/semantic_interpretation.markdown +189 -0
  33. data/vendor/treetop/doc/site.rb +110 -0
  34. data/vendor/treetop/doc/sitegen.rb +60 -0
  35. data/vendor/treetop/doc/syntactic_recognition.markdown +100 -0
  36. data/vendor/treetop/doc/using_in_ruby.markdown +21 -0
  37. data/vendor/treetop/examples/lambda_calculus/arithmetic.rb +551 -0
  38. data/vendor/treetop/examples/lambda_calculus/arithmetic.treetop +97 -0
  39. data/vendor/treetop/examples/lambda_calculus/arithmetic_node_classes.rb +7 -0
  40. data/vendor/treetop/examples/lambda_calculus/arithmetic_test.rb +54 -0
  41. data/vendor/treetop/examples/lambda_calculus/lambda_calculus +0 -0
  42. data/vendor/treetop/examples/lambda_calculus/lambda_calculus.rb +718 -0
  43. data/vendor/treetop/examples/lambda_calculus/lambda_calculus.treetop +132 -0
  44. data/vendor/treetop/examples/lambda_calculus/lambda_calculus_node_classes.rb +5 -0
  45. data/vendor/treetop/examples/lambda_calculus/lambda_calculus_test.rb +89 -0
  46. data/vendor/treetop/examples/lambda_calculus/test_helper.rb +18 -0
  47. data/vendor/treetop/lib/treetop/bootstrap_gen_1_metagrammar.rb +45 -0
  48. data/vendor/treetop/lib/treetop/compiler/grammar_compiler.rb +40 -0
  49. data/vendor/treetop/lib/treetop/compiler/lexical_address_space.rb +17 -0
  50. data/vendor/treetop/lib/treetop/compiler/metagrammar.rb +2955 -0
  51. data/vendor/treetop/lib/treetop/compiler/metagrammar.treetop +404 -0
  52. data/vendor/treetop/lib/treetop/compiler/node_classes/anything_symbol.rb +20 -0
  53. data/vendor/treetop/lib/treetop/compiler/node_classes/atomic_expression.rb +14 -0
  54. data/vendor/treetop/lib/treetop/compiler/node_classes/character_class.rb +22 -0
  55. data/vendor/treetop/lib/treetop/compiler/node_classes/choice.rb +31 -0
  56. data/vendor/treetop/lib/treetop/compiler/node_classes/declaration_sequence.rb +24 -0
  57. data/vendor/treetop/lib/treetop/compiler/node_classes/grammar.rb +28 -0
  58. data/vendor/treetop/lib/treetop/compiler/node_classes/inline_module.rb +27 -0
  59. data/vendor/treetop/lib/treetop/compiler/node_classes/nonterminal.rb +13 -0
  60. data/vendor/treetop/lib/treetop/compiler/node_classes/optional.rb +19 -0
  61. data/vendor/treetop/lib/treetop/compiler/node_classes/parenthesized_expression.rb +9 -0
  62. data/vendor/treetop/lib/treetop/compiler/node_classes/parsing_expression.rb +138 -0
  63. data/vendor/treetop/lib/treetop/compiler/node_classes/parsing_rule.rb +55 -0
  64. data/vendor/treetop/lib/treetop/compiler/node_classes/predicate.rb +45 -0
  65. data/vendor/treetop/lib/treetop/compiler/node_classes/repetition.rb +55 -0
  66. data/vendor/treetop/lib/treetop/compiler/node_classes/sequence.rb +68 -0
  67. data/vendor/treetop/lib/treetop/compiler/node_classes/terminal.rb +20 -0
  68. data/vendor/treetop/lib/treetop/compiler/node_classes/transient_prefix.rb +9 -0
  69. data/vendor/treetop/lib/treetop/compiler/node_classes/treetop_file.rb +9 -0
  70. data/vendor/treetop/lib/treetop/compiler/node_classes.rb +19 -0
  71. data/vendor/treetop/lib/treetop/compiler/ruby_builder.rb +113 -0
  72. data/vendor/treetop/lib/treetop/compiler.rb +6 -0
  73. data/vendor/treetop/lib/treetop/ruby_extensions/string.rb +42 -0
  74. data/vendor/treetop/lib/treetop/ruby_extensions.rb +2 -0
  75. data/vendor/treetop/lib/treetop/runtime/compiled_parser.rb +95 -0
  76. data/vendor/treetop/lib/treetop/runtime/interval_skip_list/head_node.rb +15 -0
  77. data/vendor/treetop/lib/treetop/runtime/interval_skip_list/interval_skip_list.rb +200 -0
  78. data/vendor/treetop/lib/treetop/runtime/interval_skip_list/node.rb +164 -0
  79. data/vendor/treetop/lib/treetop/runtime/interval_skip_list.rb +4 -0
  80. data/vendor/treetop/lib/treetop/runtime/syntax_node.rb +72 -0
  81. data/vendor/treetop/lib/treetop/runtime/terminal_parse_failure.rb +16 -0
  82. data/vendor/treetop/lib/treetop/runtime/terminal_syntax_node.rb +17 -0
  83. data/vendor/treetop/lib/treetop/runtime.rb +5 -0
  84. data/vendor/treetop/lib/treetop/version.rb +9 -0
  85. data/vendor/treetop/lib/treetop.rb +11 -0
  86. data/vendor/treetop/script/generate_metagrammar.rb +14 -0
  87. data/vendor/treetop/script/svnadd +11 -0
  88. data/vendor/treetop/script/svnrm +11 -0
  89. data/vendor/treetop/spec/compiler/and_predicate_spec.rb +36 -0
  90. data/vendor/treetop/spec/compiler/anything_symbol_spec.rb +52 -0
  91. data/vendor/treetop/spec/compiler/character_class_spec.rb +188 -0
  92. data/vendor/treetop/spec/compiler/choice_spec.rb +80 -0
  93. data/vendor/treetop/spec/compiler/circular_compilation_spec.rb +28 -0
  94. data/vendor/treetop/spec/compiler/failure_propagation_functional_spec.rb +21 -0
  95. data/vendor/treetop/spec/compiler/grammar_compiler_spec.rb +84 -0
  96. data/vendor/treetop/spec/compiler/grammar_spec.rb +41 -0
  97. data/vendor/treetop/spec/compiler/nonterminal_symbol_spec.rb +40 -0
  98. data/vendor/treetop/spec/compiler/not_predicate_spec.rb +38 -0
  99. data/vendor/treetop/spec/compiler/one_or_more_spec.rb +35 -0
  100. data/vendor/treetop/spec/compiler/optional_spec.rb +37 -0
  101. data/vendor/treetop/spec/compiler/parenthesized_expression_spec.rb +19 -0
  102. data/vendor/treetop/spec/compiler/parsing_rule_spec.rb +32 -0
  103. data/vendor/treetop/spec/compiler/sequence_spec.rb +115 -0
  104. data/vendor/treetop/spec/compiler/terminal_spec.rb +81 -0
  105. data/vendor/treetop/spec/compiler/terminal_symbol_spec.rb +37 -0
  106. data/vendor/treetop/spec/compiler/test_grammar.treetop +7 -0
  107. data/vendor/treetop/spec/compiler/test_grammar.tt +7 -0
  108. data/vendor/treetop/spec/compiler/test_grammar_do.treetop +7 -0
  109. data/vendor/treetop/spec/compiler/zero_or_more_spec.rb +56 -0
  110. data/vendor/treetop/spec/composition/a.treetop +11 -0
  111. data/vendor/treetop/spec/composition/b.treetop +11 -0
  112. data/vendor/treetop/spec/composition/c.treetop +10 -0
  113. data/vendor/treetop/spec/composition/d.treetop +10 -0
  114. data/vendor/treetop/spec/composition/grammar_composition_spec.rb +26 -0
  115. data/vendor/treetop/spec/ruby_extensions/string_spec.rb +32 -0
  116. data/vendor/treetop/spec/runtime/compiled_parser_spec.rb +101 -0
  117. data/vendor/treetop/spec/runtime/interval_skip_list/delete_spec.rb +147 -0
  118. data/vendor/treetop/spec/runtime/interval_skip_list/expire_range_spec.rb +349 -0
  119. data/vendor/treetop/spec/runtime/interval_skip_list/insert_and_delete_node.rb +385 -0
  120. data/vendor/treetop/spec/runtime/interval_skip_list/insert_spec.rb +660 -0
  121. data/vendor/treetop/spec/runtime/interval_skip_list/interval_skip_list_spec.graffle +6175 -0
  122. data/vendor/treetop/spec/runtime/interval_skip_list/interval_skip_list_spec.rb +58 -0
  123. data/vendor/treetop/spec/runtime/interval_skip_list/palindromic_fixture.rb +23 -0
  124. data/vendor/treetop/spec/runtime/interval_skip_list/palindromic_fixture_spec.rb +164 -0
  125. data/vendor/treetop/spec/runtime/interval_skip_list/spec_helper.rb +84 -0
  126. data/vendor/treetop/spec/runtime/syntax_node_spec.rb +53 -0
  127. data/vendor/treetop/spec/spec_helper.rb +106 -0
  128. data/vendor/treetop/spec/spec_suite.rb +4 -0
  129. data/vendor/treetop/treetop.gemspec +18 -0
  130. metadata +196 -0
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .DS_Store
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Digitpaint, Flurin Egger
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.md ADDED
@@ -0,0 +1,172 @@
1
+ Personify : personalisation template language
2
+ =============================================
3
+
4
+ Personfify is meant for use in environments where templates just need
5
+ to be personalized.
6
+
7
+ Basic syntax
8
+ ------------
9
+
10
+ Alle expressions are wrapped in brackets ([ ]). All code outside
11
+ of brackets will not be evaluated.
12
+
13
+ If the return statement of an expression is nil, it won't be replaced
14
+ by it's output.
15
+
16
+ All whitespace within expressions is ignored.
17
+
18
+ Simple substitution
19
+ -------------------
20
+
21
+ The simplest use of the personify template language is to just use
22
+ the standard substitution expressions. A substitution expression
23
+ exists of a key which will be replaced if it's found in the context.
24
+
25
+ #### Examples:
26
+
27
+ With context:
28
+
29
+ {"key" => "value"}
30
+
31
+ Example:
32
+
33
+ [KEY] => value
34
+ [UNKNOWN] => [UNKNOWN]
35
+
36
+ Substitutions with fallback
37
+ ---------------------------
38
+
39
+ A more advanced feature is to use fallbacks on missing keys. If a key can't
40
+ be found in the context, all alternative keys (separated by a pipe (|))
41
+ will be tried until a non-nil value is found. If a the last alternative
42
+ returns nil, the original expression won't be replaced.
43
+
44
+ You can also specify strings as fallbacks, they will always return the string.
45
+ See also the note on strings below.
46
+
47
+
48
+ #### Examples:
49
+
50
+ With context:
51
+
52
+ {"key" => "value"}
53
+
54
+ Example:
55
+
56
+ [UNKNOWN | KEY] => value
57
+ [UNKNOWN1 | UNKNOWN2 | "default"] => default
58
+ [UNKNOWN1 | UNKNOWN2 | default] => default
59
+
60
+ Boolean logic
61
+ -------------
62
+
63
+ You can use boolean logic parameters && (and) and || (or) to implement simple logic. The logic can be used
64
+ anywhere where you can use a substitution, which means you can use it as a standalone subsitition, within a function
65
+ parameter or as an alternative.
66
+
67
+ **Attention!** We currently do not support operator precedence and parenthesis, the logic will be evaluated
68
+ backwards so the statement A && B || C will actually be evaluated as A && (B || C).
69
+
70
+ #### Examples:
71
+
72
+ with context:
73
+
74
+ {
75
+ "a" => "a",
76
+ "b" => "b",
77
+ "c" => "c",
78
+ "d" => nil
79
+ }
80
+
81
+ Example:
82
+
83
+ [A && B] => a
84
+ [A && D | "default"] => default
85
+
86
+ [A || B] => a
87
+ [B || A] => b
88
+ [D || A] => a
89
+
90
+ [A && B || C] => a
91
+ [A && D || C] => c
92
+
93
+ [A || B && C] => a
94
+ [D || B && C || "default"] => default
95
+
96
+
97
+ Function calls
98
+ --------------
99
+
100
+ For more flexibility, it is possible to put functions in
101
+ the context by means of lamda's and procs. However you need to be very
102
+ carefull with accepting parameters as Personify will just splat all
103
+ parameters into the proc's call method. If an expected function
104
+ doesn't respond to a call method, it just works like a normal substitution.
105
+
106
+ ### Simple Syntax
107
+
108
+ #### Examples:
109
+
110
+ With context:
111
+
112
+ {
113
+ "key1" => "v1",
114
+ "key2" => "v2"
115
+ "ampersandize" => Proc.new{|*c| c.join(" & ") }
116
+ }
117
+
118
+ Example:
119
+
120
+ [AMPERSANDIZE(KEY1,KEY2)] => v1 & v2
121
+ [AMPERSANDIZE(KEY1 , "default")] => v1 & default
122
+ [AMPERSANDIZE("1","2","3")] => 1 & 2 & 3
123
+ [AMPERSANDIZE("1",2,3)] => 1 & 2 & 3
124
+
125
+ ### Block Syntax
126
+
127
+ You can also use a block-style syntax with functions. The content of the block will be passed
128
+ to the function as the last parameter.
129
+
130
+ #### Example: Simple function substitution
131
+
132
+ [FUN(VAR) DO]
133
+ content passed to the IF fn as last parameter, the whole block will be substituted.
134
+ for example lambda{|var,glob| var > 1 ? glob : "" }
135
+ [END]
136
+
137
+ #### Example: Function as alternative
138
+
139
+ [FIRST | FUN() DO]
140
+ if FIRST is available do that, if not pass this text to FUN() call.
141
+ Always replace this text.
142
+ [END]
143
+
144
+ #### Example: Function as an alternative with a fallback string
145
+
146
+ [FIRST | FUN() DO]
147
+ First check FIRST, then try to call the FUN with this content, as a last resort use the
148
+ fallback string
149
+ [END | "fallback"]
150
+
151
+ #### Example: Function as an alternative with another function as fallback
152
+
153
+ [FUN() DO]
154
+ Pass this to FUN and if it returns non false/nil we show the return value
155
+ [END | FUN2() DO]
156
+ If FUN() return a false/nil value we pass this to FUN2() and show it's return value
157
+ [END]
158
+
159
+
160
+ Strings
161
+ -------
162
+
163
+ Strings can be used either as parameters for a function or in an expression
164
+ as an alternative. Strings don't necessarily need to be quoted as long
165
+ as they don't contain any of these characters: "]),|
166
+
167
+ Strings cannot ever contain double qoutes (").
168
+
169
+
170
+ Copyright
171
+ ---------
172
+ Copyright (c) 2011 Digitpaint, Flurin Egger. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "personify"
8
+ gem.summary = %Q{A personalisation template language}
9
+ gem.description = %Q{Personfify is meant for use in environments where templates just need to be personalized.}
10
+ gem.email = "flurin@digitpaint.nl"
11
+ gem.homepage = "http://github.com/digitpaint/personify"
12
+ gem.authors = ["Flurin Egger"]
13
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "personify #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,141 @@
1
+ Current state
2
+ =============
3
+
4
+ ## String
5
+ ["string"]
6
+
7
+ ## Substitution
8
+ [SUBSTITUTE]
9
+
10
+ ## Substitution with alternatives
11
+ [SUBSTITUTE | ALT]
12
+
13
+ ## Function with substitution parameters
14
+ [FUN(SUBSTITUTE)]
15
+
16
+ ## Function with string parameter
17
+ [FUN("string")]
18
+
19
+ ## !? Does this work?
20
+ [FUN(1)]
21
+
22
+
23
+ Proposals for block syntax
24
+ ==========================
25
+
26
+ [FUN() DO]
27
+ passed to function as last parameter
28
+ [END]
29
+
30
+ [START:FUN]
31
+ pass to block?
32
+ [STOP:FUN]
33
+
34
+ [FUN<]
35
+ [>]
36
+
37
+ [VAR<]
38
+ [>VAR]
39
+
40
+ [VAR]
41
+ [/VAR]
42
+
43
+ [FUN>
44
+ some weird stuff
45
+ <]
46
+
47
+ [SUBSTITUTE | >
48
+
49
+ <]
50
+
51
+ [SUBSTITUTE | FUN() >
52
+ <]
53
+
54
+ [FUN()]
55
+ passed to function as last parameter
56
+ [/]
57
+
58
+ [FUN(){
59
+ passed to function as last parameter
60
+ }]
61
+
62
+ [VAR{
63
+ show text if VAR == true
64
+ }]
65
+
66
+ # Context
67
+ {
68
+ :subscriber => {
69
+ :email => "flurin@digitpaint.nl",
70
+ :token => "abcdef",
71
+ :id => 201,
72
+ :newsletters => {
73
+ 1 => {
74
+ :frequency => "day"
75
+ },
76
+ 5 => {
77
+ :frequency => "day"
78
+ }
79
+ }
80
+ }
81
+ }
82
+ # /Context
83
+
84
+ [SUBSCRIBER.EMAIL] #=> "flurin@digitpaint.nl"
85
+ [SUBSCRIBER.NEWSLETTER.1.FREQUENCY] #=> "day"
86
+
87
+ [IF SUBSCRIBER.NEWSLETTER.1]
88
+ ...
89
+ [END]
90
+
91
+ # Capture content to pass to function
92
+ [FUN(VAR) DO]
93
+ content passed to the IF fn as last parameter, the whole block will be substituted.
94
+ for example lambda{|var,glob| var > 1 ? glob : "" }
95
+ [END]
96
+
97
+ [FIRST | FUN() DO]
98
+ if FIRST is available do that, if not pass this text to FUN() call.
99
+ Always replace this text.
100
+ [END]
101
+
102
+ [FIRST | FUN() DO]
103
+ First check FIRST, then try to call the FUN with this content, as a last resort use the
104
+ fallback string
105
+ [END | "fallback"]
106
+
107
+ [FUN() DO]
108
+ Pass this to FUN and if it returns non false/nil we show the return value
109
+ [END | FUN2() DO]
110
+ If FUN() return a false/nil value we pass this to FUN2() and show it's return value
111
+ [END]
112
+
113
+ [VAR DO]
114
+ invalid syntax will not substitue
115
+ [END]
116
+
117
+ # IF as a language construct with ELSIF and ELSE
118
+ [IF EXPR1]
119
+ if EXPR is true do this
120
+ [ELSIF EXPR2]
121
+ if EXPR1 is false and EXPR2 is true, do this
122
+ [ELSE]
123
+ all other cases do this
124
+ [END]
125
+
126
+ COMPARATORS
127
+
128
+ A == "b"
129
+ A > 1
130
+ A < 1
131
+ A <= 1
132
+ A >= 1
133
+ FN(A) == true
134
+
135
+
136
+
137
+ [IF(VAR){
138
+
139
+ [} ELSE {]
140
+
141
+ [}]
@@ -0,0 +1,55 @@
1
+ module Personify
2
+ # This specifies the context we can evaluate in
3
+ class Context
4
+
5
+ class << self
6
+ def allowed_context_methods
7
+ @allowed_methods ||= []
8
+ end
9
+
10
+ def context_method(method_name)
11
+ self.allowed_context_methods << method_name.to_s if self.instance_methods.include?(method_name.to_s)
12
+ end
13
+
14
+ def allow_method?(method_name)
15
+ self.allowed_context_methods.include?(method_name.to_s)
16
+ end
17
+ end
18
+
19
+ def allow_method?(method_name)
20
+ self.class.allow_method?(method_name)
21
+ end
22
+
23
+ def local_assigns=(assigns)
24
+ @local_assigns = assigns
25
+ end
26
+
27
+ def local_assigns
28
+ @local_assigns ||= {}
29
+ end
30
+
31
+ def [](k)
32
+ self.local_assigns[k]
33
+ end
34
+
35
+ def has_key?(k)
36
+ self.local_assigns.has_key?(k)
37
+ end
38
+
39
+
40
+
41
+ end
42
+
43
+ class DefaultContext < Context
44
+
45
+ def if(statement, value)
46
+ if statement
47
+ value
48
+ else
49
+ nil
50
+ end
51
+ end
52
+ context_method :if
53
+
54
+ end
55
+ end