ember 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/HISTORY +79 -0
  2. data/INSTALL +31 -0
  3. data/MANUAL +25 -0
  4. data/README +54 -0
  5. data/THEORY +151 -0
  6. data/USAGE +250 -0
  7. data/bin/ember +58 -20
  8. data/doc/ann.xml +93 -0
  9. data/doc/api/Ember.html +436 -0
  10. data/doc/api/Ember/Template.html +774 -0
  11. data/doc/api/Ember/Template/Program.html +877 -0
  12. data/doc/api/Ember/Template/Program/Statement.html +181 -0
  13. data/doc/api/_index.html +139 -0
  14. data/doc/api/class_list.html +36 -0
  15. data/doc/api/css/common.css +1 -0
  16. data/doc/api/css/full_list.css +50 -0
  17. data/doc/api/css/style.css +273 -0
  18. data/doc/api/file.LICENSE.html +73 -0
  19. data/doc/api/file_list.html +38 -0
  20. data/doc/api/frames.html +13 -0
  21. data/doc/api/index.html +72 -13
  22. data/doc/api/js/app.js +111 -0
  23. data/doc/api/js/full_list.js +117 -0
  24. data/doc/api/js/{jquery-1.3.2.min.js → jquery.js} +0 -0
  25. data/doc/api/method_list.html +179 -0
  26. data/doc/api/top-level-namespace.html +87 -0
  27. data/doc/index.html +1353 -682
  28. data/inochi.opts +31 -0
  29. data/lib/ember.rb +1 -15
  30. data/lib/ember/inochi.rb +103 -0
  31. data/lib/ember/template.rb +66 -78
  32. data/test/combinatorics.rb +188 -0
  33. data/test/ember/template_test.rb +137 -0
  34. data/test/runner +25 -0
  35. data/test/test_helper.rb +5 -0
  36. metadata +61 -51
  37. data/doc/api/apple-touch-icon.png +0 -0
  38. data/doc/api/classes/Ember.html +0 -61
  39. data/doc/api/classes/Ember/Template.html +0 -413
  40. data/doc/api/classes/Ember/Template/Program.html +0 -60
  41. data/doc/api/created.rid +0 -1
  42. data/doc/api/css/main.css +0 -263
  43. data/doc/api/css/panel.css +0 -383
  44. data/doc/api/css/reset.css +0 -53
  45. data/doc/api/favicon.ico +0 -0
  46. data/doc/api/files/LICENSE.html +0 -76
  47. data/doc/api/files/lib/ember/template_rb.html +0 -66
  48. data/doc/api/files/lib/ember_rb.html +0 -63
  49. data/doc/api/i/arrows.png +0 -0
  50. data/doc/api/i/results_bg.png +0 -0
  51. data/doc/api/i/tree_bg.png +0 -0
  52. data/doc/api/js/jquery-effect.js +0 -593
  53. data/doc/api/js/main.js +0 -22
  54. data/doc/api/js/searchdoc.js +0 -628
  55. data/doc/api/panel/index.html +0 -71
  56. data/doc/api/panel/search_index.js +0 -1
  57. data/doc/api/panel/tree.js +0 -1
  58. data/doc/history.erb +0 -34
  59. data/doc/index.erb +0 -11
  60. data/doc/intro.erb +0 -53
  61. data/doc/setup.erb +0 -78
  62. data/doc/usage.erb +0 -280
  63. data/rakefile +0 -14
  64. data/test/ember.rb +0 -17
  65. data/test/ember/template.rb +0 -141
@@ -0,0 +1,31 @@
1
+ ##
2
+ # Location where project documentation will be uploaded by `inochi pub:doc`.
3
+ # This value can utilize any remote/destination syntax supported by `rsync`.
4
+ #
5
+ :pub_doc_target: ~/www/lib/ember
6
+
7
+ ##
8
+ # Options for the `rsync` command used to upload this project's documentation.
9
+ #
10
+ :pub_doc_options: --verbose --compress --archive --update --delete
11
+
12
+ ##
13
+ # Arbitrary Ruby code that will configure this project's RubyGem before it
14
+ # is built by `inochi gem`. This code has access to a local variable named
15
+ # `gem` which holds a Gem::Specification object representing this project.
16
+ #
17
+ # @example
18
+ #
19
+ # :gem_spec_logic: |
20
+ # # show the Inochi-provided specification for this project's RubyGem
21
+ # puts gem
22
+ #
23
+ # # add files that are outside this project directory to the RubyGem
24
+ # gem.files += FileList['/some/outside/**/*.files']
25
+ #
26
+ # # omit some files in this project's directory from the RubyGem
27
+ # gem.files.exclude '{some*files,in_this,project/**/directory}'
28
+ #
29
+ # # and so on... anything is possible! use your imagination!
30
+ #
31
+ :gem_spec_logic: |
@@ -1,16 +1,2 @@
1
- #--
2
- # Copyright protects this work.
3
- # See LICENSE file for details.
4
- #++
5
-
6
- require 'rubygems'
7
- gem 'inochi', '~> 1'
8
- require 'inochi'
9
-
10
- Inochi.init :Ember,
11
- :version => '0.0.1',
12
- :release => '2009-10-03',
13
- :website => 'http://snk.tuxfamily.org/lib/ember/',
14
- :tagline => 'eRuby template processor'
15
-
1
+ require 'ember/inochi'
16
2
  require 'ember/template'
@@ -0,0 +1,103 @@
1
+ module Ember
2
+
3
+ ##
4
+ # Official name of this project.
5
+ #
6
+ PROJECT = "Ember"
7
+
8
+ ##
9
+ # Short single-line description of this project.
10
+ #
11
+ TAGLINE = "eRuby template processor"
12
+
13
+ ##
14
+ # Address of this project's official home page.
15
+ #
16
+ WEBSITE = "http://snk.tuxfamily.org/lib/ember/"
17
+
18
+ ##
19
+ # Number of this release of this project.
20
+ #
21
+ VERSION = "0.1.0"
22
+
23
+ ##
24
+ # Date of this release of this project.
25
+ #
26
+ RELDATE = "2010-04-03"
27
+
28
+ ##
29
+ # Description of this release of this project.
30
+ #
31
+ def self.inspect
32
+ "#{PROJECT} #{VERSION} (#{RELDATE})"
33
+ end
34
+
35
+ ##
36
+ # Location of this release of this project.
37
+ #
38
+ INSTDIR = File.expand_path('../../..', __FILE__)
39
+
40
+ ##
41
+ # RubyGems required by this project during runtime.
42
+ #
43
+ # @example
44
+ #
45
+ # RUNTIME = {
46
+ # # this project needs exactly version 1.2.3 of the "an_example" gem
47
+ # "an_example" => [ "1.2.3" ],
48
+ #
49
+ # # this project needs at least version 1.2 (but not
50
+ # # version 1.2.4 or newer) of the "another_example" gem
51
+ # "another_example" => [ ">= 1.2" , "< 1.2.4" ],
52
+ #
53
+ # # this project needs any version of the "yet_another_example" gem
54
+ # "yet_another_example" => [],
55
+ # }
56
+ #
57
+ RUNTIME = {}
58
+
59
+ ##
60
+ # RubyGems required by this project during development.
61
+ #
62
+ # @example
63
+ #
64
+ # DEVTIME = {
65
+ # # this project needs exactly version 1.2.3 of the "an_example" gem
66
+ # "an_example" => [ "1.2.3" ],
67
+ #
68
+ # # this project needs at least version 1.2 (but not
69
+ # # version 1.2.4 or newer) of the "another_example" gem
70
+ # "another_example" => [ ">= 1.2" , "< 1.2.4" ],
71
+ #
72
+ # # this project needs any version of the "yet_another_example" gem
73
+ # "yet_another_example" => [],
74
+ # }
75
+ #
76
+ DEVTIME = {
77
+ "inochi" => [ "~> 2" ], # for managing this project
78
+ "dfect" => [ "~> 2" ], # for unit testing
79
+ }
80
+
81
+ ##
82
+ # Loads the correct version (as defined by the {RUNTIME} or {DEVTIME}
83
+ # constant in this module) of the given gem or the gem that contains
84
+ # the given library.
85
+ #
86
+ def self.require gem_name_or_library
87
+ # prepare the correct version of the gem for loading
88
+ if respond_to? :gem
89
+ gem_name = gem_name_or_library.to_s.sub(%r{/.*$}, '')
90
+ if gem_version = RUNTIME[gem_name] || DEVTIME[gem_name]
91
+ begin
92
+ gem gem_name, *gem_version
93
+ rescue LoadError => error
94
+ warn "#{self.inspect}: #{error}"
95
+ end
96
+ end
97
+ end
98
+
99
+ # do the loading
100
+ super
101
+ end
102
+
103
+ end
@@ -1,8 +1,3 @@
1
- #--
2
- # Copyright protects this work.
3
- # See LICENSE file for details.
4
- #++
5
-
6
1
  require 'pathname'
7
2
 
8
3
  module Ember
@@ -13,53 +8,44 @@ module Ember
13
8
  #
14
9
  # This processor transforms the given input
15
10
  # into an executable Ruby program (provided
16
- # by the #program() method) which is then
17
- # executed by the #render() method on demand.
11
+ # by the {#program} method) which is then
12
+ # executed by the {#render} method on demand.
18
13
  #
19
14
  # eRuby directives that contribute to the output of
20
15
  # the given template are called "vocal" directives.
21
16
  # Those that do not are called "silent" directives.
22
17
  #
23
- # ==== Options
18
+ # @option options [String] :result_variable ("_erbout")
24
19
  #
25
- # [:result_variable]
26
20
  # Name of the variable which stores the result of
27
21
  # template evaluation during template evaluation.
28
22
  #
29
- # The default value is "_erbout".
23
+ # @option options [Boolean] :continue_result (false)
30
24
  #
31
- # [:continue_result]
32
25
  # Append to the result variable if it already exists?
33
26
  #
34
- # The default value is false.
27
+ # @option options [String] :source_file ("SOURCE")
35
28
  #
36
- # [:source_file]
37
29
  # Name of the file which contains the given input. This
38
30
  # is shown in stack traces when reporting error messages.
39
31
  #
40
- # The default value is "SOURCE".
32
+ # @option options [Integer] :source_line (1)
41
33
  #
42
- # [:source_line]
43
34
  # Line number at which the given input exists in the :source_file.
44
35
  # This is shown in stack traces when reporting error messages.
45
36
  #
46
- # The default value is 1.
37
+ # @option options [Boolean] :shorthand (false)
47
38
  #
48
- # [:shorthand]
49
39
  # Treat lines beginning with "%" as eRuby directives?
50
40
  #
51
- # The default value is false.
52
- #
53
- # [:infer_end]
54
- # Add missing <% end %> statements based on indentation?
41
+ # @option options [Boolean] :infer_end (false)
55
42
  #
56
- # The default value is false.
43
+ # Add missing +<% end %>+ statements based on indentation?
57
44
  #
58
- # [:unindent]
59
- # Unindent the content of eRuby blocks (everything
60
- # between <% do %> ... <% end %>) hierarchically?
45
+ # @option options [Boolean] :unindent (false)
61
46
  #
62
- # The default value is false.
47
+ # Unindent the content of eRuby blocks---that is everything
48
+ # between the +<% do %>+ and +<% end %>+ tags---hierarchically?
63
49
  #
64
50
  def initialize input, options = {}
65
51
  @options = options
@@ -79,7 +65,7 @@ module Ember
79
65
 
80
66
  ##
81
67
  # Returns the result of executing the Ruby program for this template
82
- # (provided by the #program() method) inside the given context binding.
68
+ # (provided by the {#program} method) inside the given context binding.
83
69
  #
84
70
  def render context = TOPLEVEL_BINDING, parent_context_id = nil
85
71
  context ||= @@contexts[parent_context_id] # inherit parent context
@@ -141,72 +127,71 @@ module Ember
141
127
  OPERATION_EVAL_TEMPLATE_STRING = '~'
142
128
  OPERATION_INSERT_PLAIN_FILE = '<'
143
129
 
144
- #:stopdoc:
130
+ OPERATIONS = [
131
+ OPERATION_COMMENT_LINE,
132
+ OPERATION_BEGIN_LAMBDA,
133
+ OPERATION_EVAL_EXPRESSION,
134
+ OPERATION_EVAL_TEMPLATE_FILE,
135
+ OPERATION_EVAL_TEMPLATE_STRING,
136
+ OPERATION_INSERT_PLAIN_FILE,
137
+ ]
145
138
 
146
- OPERATIONS = [
147
- OPERATION_COMMENT_LINE,
148
- OPERATION_BEGIN_LAMBDA,
149
- OPERATION_EVAL_EXPRESSION,
150
- OPERATION_EVAL_TEMPLATE_FILE,
151
- OPERATION_EVAL_TEMPLATE_STRING,
152
- OPERATION_INSERT_PLAIN_FILE,
153
- ]
139
+ SILENT_OPERATIONS = [
140
+ OPERATION_COMMENT_LINE,
141
+ OPERATION_BEGIN_LAMBDA,
142
+ ]
154
143
 
155
- SILENT_OPERATIONS = [
156
- OPERATION_COMMENT_LINE,
157
- OPERATION_BEGIN_LAMBDA,
158
- ]
144
+ VOCAL_OPERATIONS = OPERATIONS - SILENT_OPERATIONS
159
145
 
160
- VOCAL_OPERATIONS = OPERATIONS - SILENT_OPERATIONS
146
+ DIRECTIVE_HEAD = '<%'
147
+ DIRECTIVE_BODY = '(?:(?#
148
+ there is nothing here, before the alternation,
149
+ because we want to match the "<%%>" base case
150
+ )|[^%](?:.(?!<%))*?)'
151
+ DIRECTIVE_TAIL = '-?%>'
161
152
 
162
- DIRECTIVE_HEAD = '<%'
163
- DIRECTIVE_BODY = '(?:(?#
164
- there is nothing here before the alternation
165
- because we want to match the "<%%>" base case
166
- )|[^%](?:.(?!<%))*?)'
167
- DIRECTIVE_TAIL = '-?%>'
153
+ SHORTHAND_HEAD = '%'
154
+ SHORTHAND_BODY = '(?:(?#
155
+ there is nothing here, before the alternation,
156
+ because we want to match the "<%%>" base case
157
+ )|[^%].*)'
158
+ SHORTHAND_TAIL = '$'
168
159
 
169
- SHORTHAND_HEAD = '%'
170
- SHORTHAND_BODY = '(?:(?#
171
- there is nothing here before the alternation
172
- because we want to match the "<%%>" base case
173
- )|[^%].*)'
174
- SHORTHAND_TAIL = '$'
160
+ NEWLINE = '\r?\n'
161
+ SPACING = '[[:blank:]]*'
175
162
 
176
- NEWLINE = '\r?\n'
177
- SPACING = '[[:blank:]]*'
163
+ MARGIN_REGEXP = /^#{SPACING}(?=\S)/o
178
164
 
179
- MARGIN_REGEXP = /^#{SPACING}(?=\S)/o
165
+ LAMBDA_BEGIN_REGEXP = /\b(do)\b\s*(\|.*?\|)?\s*$/
180
166
 
181
- LAMBDA_BEGIN_REGEXP = /\b(do)\b\s*(\|.*?\|)?\s*$/
167
+ build_keyword_regexp = lambda {|*words| /\A\s*\b(#{words.join '|'})\b/ }
182
168
 
183
- build_keyword_regexp = lambda {|*words| /\A\s*\b(#{words.join '|'})\b/ }
169
+ BLOCK_BEGIN_REGEXP = build_keyword_regexp[
170
+ # generic
171
+ :begin,
184
172
 
185
- BLOCK_BEGIN_REGEXP = build_keyword_regexp[
186
- # generic
187
- :begin,
173
+ # conditional
174
+ :if, :unless, :case,
188
175
 
189
- # conditional
190
- :if, :unless, :case,
176
+ # loops
177
+ :for, :while, :until,
191
178
 
192
- # loops
193
- :for, :while, :until
194
- ]
179
+ # scopes
180
+ :def, :class, :module
181
+ ]
195
182
 
196
183
  BLOCK_CONTINUE_REGEXP = build_keyword_regexp[
197
- # generic
198
- :rescue, :ensure,
184
+ # generic
185
+ :rescue, :ensure,
199
186
 
200
- # conditional
201
- :else, :elsif, :when
202
- ]
187
+ # conditional
188
+ :else, :elsif, :when
189
+ ]
203
190
 
204
- BLOCK_END_REGEXP = build_keyword_regexp[
205
- # generic
206
- :end
207
- ]
208
-
209
- #:startdoc:
191
+ BLOCK_END_REGEXP = build_keyword_regexp[
192
+ # generic
193
+ :end
194
+ ]
210
195
 
211
196
  ##
212
197
  # Transforms the given eRuby template into an executable Ruby program.
@@ -237,6 +222,9 @@ module Ember
237
222
  template = contents.zip(directives).join
238
223
  end
239
224
 
225
+ # convert single-line comment directives into nothing
226
+ template.gsub!(/^#{SPACING}#{DIRECTIVE_HEAD}##{DIRECTIVE_BODY}#{DIRECTIVE_TAIL}#{SPACING}$/, '')
227
+
240
228
  # translate template into Ruby code
241
229
  @margins = []
242
230
  @crowns = []
@@ -593,4 +581,4 @@ module Ember
593
581
  Statement = Struct.new :type, :value
594
582
  end
595
583
  end
596
- end
584
+ end
@@ -0,0 +1,188 @@
1
+ # Simple combinatorics library for Ruby 1.8, 1.9, and (hopefully) beyond.
2
+ #
3
+ # (the ISC license)
4
+ #
5
+ # Copyright 2007 Suraj N. Kurapati <sunaku@gmail.com>
6
+ #
7
+ # Permission to use, copy, modify, and/or distribute this software for any
8
+ # purpose with or without fee is hereby granted, provided that the above
9
+ # copyright notice and this permission notice appear in all copies.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
+ #
19
+ class Array
20
+ unless method_defined? :enumeration
21
+ ##
22
+ # Returns all possible enumerations made from
23
+ # sample_size number of items from this list.
24
+ #
25
+ # @param [Integer] sample_size
26
+ # The length of each enumeration.
27
+ #
28
+ # @param [Proc] sampler
29
+ # If given, each enumeration is passed to this block.
30
+ #
31
+ def enumeration(sample_size = self.length, &sampler)
32
+ return [] if sample_size < 1
33
+
34
+ results = []
35
+
36
+ visitor = lambda do |parents|
37
+ each do |child|
38
+ result = parents + [child]
39
+
40
+ if result.length < sample_size
41
+ visitor.call result
42
+ else
43
+ yield result if block_given?
44
+ results << result
45
+ end
46
+ end
47
+ end
48
+
49
+ visitor.call []
50
+ results
51
+ end
52
+ end
53
+
54
+ unless method_defined? :enumerations
55
+ ##
56
+ # Returns all possible enumerations of all possible lengths.
57
+ #
58
+ # @param [Proc] sampler
59
+ # If given, each enumeration is passed to this block.
60
+ #
61
+ def enumerations &sampler
62
+ all_lengths_impl :enumeration, &sampler
63
+ end
64
+ end
65
+
66
+ unless method_defined? :combination
67
+ ##
68
+ # Returns all possible combinations made from
69
+ # sample_size number of items from this list.
70
+ #
71
+ # @param [Integer] sample_size
72
+ # The length of each combination.
73
+ #
74
+ # @param [Proc] sampler
75
+ # If given, each combination is passed to this block.
76
+ #
77
+ def combination(sample_size = self.length, &sampler)
78
+ pnk_cnk_impl(sample_size, true, &sampler)
79
+ end
80
+ end
81
+
82
+ unless method_defined? :combinations
83
+ ##
84
+ # Returns all possible combinations of all possible lengths.
85
+ #
86
+ # @param [Proc] sampler
87
+ # If given, each combination is passed to this block.
88
+ #
89
+ def combinations &sampler
90
+ all_lengths_impl :combination, &sampler
91
+ end
92
+ end
93
+
94
+ unless method_defined? :permutation
95
+ ##
96
+ # Returns all possible permutations made from
97
+ # sample_size number of items from this list.
98
+ #
99
+ # @param [Integer] sample_size
100
+ # The length of each permutation.
101
+ #
102
+ # @param [Proc] sampler
103
+ # If given, each permutation is passed to this block.
104
+ #
105
+ def permutation(sample_size = self.length, &sampler)
106
+ pnk_cnk_impl(sample_size, false, &sampler)
107
+ end
108
+ end
109
+
110
+ unless method_defined? :permutations
111
+ ##
112
+ # Returns all possible permutations of all possible lengths.
113
+ #
114
+ # @param [Proc] sampler
115
+ # If given, each permutation is passed to this block.
116
+ #
117
+ def permutations &sampler
118
+ all_lengths_impl :permutation, &sampler
119
+ end
120
+ end
121
+
122
+ private
123
+
124
+ ##
125
+ # Returns results of the given method name for all possible sample sizes.
126
+ #
127
+ def all_lengths_impl method_name, &sampler
128
+ results = []
129
+
130
+ 0.upto(length) do |i|
131
+ results << __send__(method_name, i, &sampler)
132
+ end
133
+
134
+ results
135
+ end
136
+
137
+ ##
138
+ # Common implementation for permutation and combination functions.
139
+ #
140
+ # @param [Integer] sample_size
141
+ # Maximum depth of traversal, at which point to stop
142
+ # further traversal and to start collecting results.
143
+ #
144
+ # @param [boolean] exclude_parents
145
+ # Prevent already visited vertices from being
146
+ # visited again in subsequent iterations?
147
+ #
148
+ def pnk_cnk_impl sample_size, exclude_parents
149
+ results = []
150
+
151
+ if sample_size >= 0 && sample_size < self.length
152
+ ##
153
+ # @param [#each] parents
154
+ # list of visited vertices, including the current vertex
155
+ #
156
+ # @param [#each] children
157
+ # list of unvisited vertices adjacent to current vertex
158
+ #
159
+ # @param [Integer] depth
160
+ # current depth of the traversal tree
161
+ #
162
+ visitor = lambda do |parents, children, depth|
163
+ # traverse the graph until we reach the fringe
164
+ # vertices (leaf nodes of the traversal tree)
165
+ if depth < sample_size - 1
166
+ children.each do |c|
167
+ next_children = children - (exclude_parents ? parents : [c])
168
+ next_parents = parents + [c]
169
+ next_depth = depth + 1
170
+
171
+ visitor.call next_parents, next_children, next_depth
172
+ end
173
+ else
174
+ # now we have reached the fringe vertices
175
+ children.each do |c|
176
+ result = parents + [c]
177
+ yield result if block_given?
178
+ results << result
179
+ end
180
+ end
181
+ end
182
+
183
+ visitor.call [], self, 0
184
+ end
185
+
186
+ results
187
+ end
188
+ end