personify 1.0.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.
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