ember 0.0.1 → 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.
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