moka 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/LICENSE.txt +20 -0
  2. data/Manifest +48 -0
  3. data/README.rdoc +9 -0
  4. data/Rakefile +17 -0
  5. data/bin/moka +21 -0
  6. data/lib/commands.rb +54 -0
  7. data/lib/commands/compile.rb +77 -0
  8. data/lib/commands/delete.rb +47 -0
  9. data/lib/commands/group/delete.rb +59 -0
  10. data/lib/commands/group/group_generator.rb +115 -0
  11. data/lib/commands/group/inspect.rb +40 -0
  12. data/lib/commands/group/new.rb +2 -0
  13. data/lib/commands/group/template/groupdir/variables.yml +1 -0
  14. data/lib/commands/inspect.rb +55 -0
  15. data/lib/commands/lib/compiler.rb +114 -0
  16. data/lib/commands/lib/helpers.rb +156 -0
  17. data/lib/commands/lib/lipsum_constants.rb +159 -0
  18. data/lib/commands/lib/lipsum_helpers.rb +56 -0
  19. data/lib/commands/lib/page_scope.rb +29 -0
  20. data/lib/commands/lib/partials_inclusion.rb +42 -0
  21. data/lib/commands/lib/site_tree.rb +274 -0
  22. data/lib/commands/lib/string_inflectors.rb +13 -0
  23. data/lib/commands/lib/utilities.rb +45 -0
  24. data/lib/commands/new.rb +64 -0
  25. data/lib/commands/order_groups.rb +115 -0
  26. data/lib/commands/order_pages.rb +128 -0
  27. data/lib/commands/page/delete.rb +47 -0
  28. data/lib/commands/page/inspect.rb +35 -0
  29. data/lib/commands/page/new.rb +2 -0
  30. data/lib/commands/page/page_generator.rb +130 -0
  31. data/lib/commands/page/template/pagedir/variables.yml +1 -0
  32. data/lib/commands/server.rb +125 -0
  33. data/lib/commands/site/inspect.rb +28 -0
  34. data/lib/commands/site/new.rb +10 -0
  35. data/lib/commands/site/site_generator.rb +93 -0
  36. data/lib/commands/site/template/manifest.yml +4 -0
  37. data/lib/commands/site/template/project/lib/helpers.rb +1 -0
  38. data/lib/commands/site/template/project/site/content.erb +14 -0
  39. data/lib/commands/site/template/project/site/header.erb +7 -0
  40. data/lib/commands/site/template/project/site/layout.erb +20 -0
  41. data/lib/commands/site/template/project/site/navigation.erb +7 -0
  42. data/lib/commands/site/template/project/site/variables.yml +1 -0
  43. data/lib/commands/site/template/project/styles/style.sass +74 -0
  44. data/lib/commands/site/template/script/config/boot.rb +5 -0
  45. data/lib/commands/site/template/script/moka +4 -0
  46. data/lib/script_moka_loader.rb +14 -0
  47. data/lib/version.rb +10 -0
  48. data/moka.gemspec +39 -0
  49. metadata +182 -0
@@ -0,0 +1,56 @@
1
+ module Moka
2
+ module LipsumHelpers
3
+ require File.expand_path('lipsum_constants.rb', File.dirname(__FILE__))
4
+
5
+ class Lipsum
6
+
7
+ # If called without a block, returns a number of paragraphs of dummy text equal to count (with each paragraph enclosed in <p>...</p>). If a block is given, iteratively calls the block passing each paragraph as argument.
8
+ #
9
+ def self.paragraphs(count, &block)
10
+ if block_given?
11
+ count.to_i.times do |i|
12
+ yield LipsumConstants::PARAGRAPHS[i]
13
+ end
14
+ else
15
+ return LipsumConstants::PARAGRAPHS[0, count].collect{|p| "<p>#{p}</p>\n"}.join
16
+ end
17
+ end
18
+
19
+ # If called without a block, returns a string of dummy text with a number of sentences equal to count (without any markup). If a block is given, iteratively calls the block passing each sentence as argument.
20
+ #
21
+ def self.sentences(count, &block)
22
+ sentences = LipsumConstants::PARAGRAPHS.join.split(/\.\s*/)
23
+ if block_given?
24
+ count.to_i.times do |i|
25
+ yield sentences[i]
26
+ end
27
+ else
28
+ return sentences[0, count].join(". ")
29
+ end
30
+ end
31
+
32
+ # If called without a block, returns a string of dummy text with a number of words equal to count (space-separated and without any markup). If a block is given, iteratively calls the block passing each word as argument.
33
+ #
34
+ # ==== Gotcha:
35
+ #
36
+ # If a block is given, the block is iteratively called passing as arguments only words more than 3 characters long. This way, nice dummy lists and menus can be generated without having to remove very short words.
37
+ #
38
+ def self.words(count, &block)
39
+ words = LipsumConstants::PARAGRAPHS.join.split(/[\W+]/)
40
+ if block_given?
41
+ shifter = 0
42
+ count.to_i.times do |i|
43
+ if words[i].size > 3
44
+ yield words[i].downcase
45
+ else
46
+ shifter += 1
47
+ end
48
+ end
49
+ else
50
+ return words[0, count].join(" ")
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,29 @@
1
+ module Moka
2
+ class PageScope
3
+ require File.expand_path('string_inflectors', File.dirname(__FILE__))
4
+ require File.expand_path('helpers', File.dirname(__FILE__))
5
+ require File.expand_path('partials_inclusion', File.dirname(__FILE__))
6
+ require File.expand_path('lipsum_helpers', File.dirname(__FILE__))
7
+ require File.expand_path('site_tree', File.dirname(__FILE__))
8
+
9
+ include Moka::SiteTree
10
+ include Moka::Helpers
11
+ include Moka::LipsumHelpers
12
+ include Moka::PartialsInclusion
13
+
14
+ $:.unshift(File.expand_path('project/lib', MOKA_ROOT))
15
+ require 'helpers'
16
+
17
+ def initialize(manifest, current_group_name, current_page_name)
18
+ @site = SiteNode.new("site", manifest["site"])
19
+ @current_group = @site.find_group(current_group_name)
20
+ @current_page = @current_group.find_page(current_page_name)
21
+ end
22
+
23
+ # returns a binding to the object
24
+ def get_binding
25
+ binding
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,42 @@
1
+ module Moka
2
+ module PartialsInclusion
3
+
4
+ require File.expand_path('utilities', File.dirname(__FILE__))
5
+
6
+ # Include a partial. The method looks for a partial named as the argument and with extension .erb or .haml searching for it first in the current page directory, then in the current group directory and, finally, in the site directory. In other words, the partial which gets included is always the most specific one. If no partial with that name is found, an empty string is returned.
7
+ def partial(partial_name)
8
+ partial_name = partial_name.to_s
9
+ ext = nil
10
+ partial_dir = File.join [@current_group.name, @current_page.name]
11
+
12
+ partial_string = ""
13
+ partial_file = nil
14
+
15
+ while ext.nil? do
16
+ if File.exist?(File.expand_path("project/site/#{partial_dir}/#{partial_name}.erb", MOKA_ROOT))
17
+ partial_file = File.new(File.expand_path("project/site/#{partial_dir}/#{partial_name}.erb", MOKA_ROOT), "r")
18
+ ext = "erb"
19
+ elsif File.exist?(File.expand_path("project/site/#{partial_dir}/#{partial_name}.haml", MOKA_ROOT))
20
+ partial_file = File.new(File.expand_path("project/site/#{partial_dir}/#{partial_name}.haml", MOKA_ROOT), "r")
21
+ ext = "haml"
22
+ end
23
+ if partial_dir == "" and ext.nil?
24
+ puts "WARNING: cannot find partial file #{partial_name}.erb or #{partial_name}.haml"
25
+ break
26
+ end
27
+ partial_dir = File.dirname partial_dir
28
+ if partial_dir == "."
29
+ partial_dir = ""
30
+ end
31
+ end
32
+
33
+ unless partial_file.nil?
34
+ partial_string = partial_file.read
35
+ partial_file.close
36
+ end
37
+
38
+ return Moka::Utilities.eval_erb_haml(partial_string, ext, self.get_binding)
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,274 @@
1
+ module Moka
2
+ module SiteTree
3
+ RESERVED_NAMES = %w(path order layout name children parent site group groups pages variables vars find_child find_group find_page initialize)
4
+
5
+ class TreeNode
6
+ attr_accessor :name
7
+ attr_accessor :parent
8
+
9
+ def initialize(name, params = {}, parent = nil)
10
+ @name = name
11
+ @parent = parent
12
+ @children = NodeArray.new
13
+ @params = {"name" => @name}
14
+ @variables = {}
15
+ end
16
+
17
+ # Returns a NodeArray object containing all the children nodes of the current node
18
+ def children
19
+ return @children.sort do |a, b|
20
+ if a.respond_to?(:order) and b.respond_to?(:order)
21
+ a.send(:order) <=> b.send(:order)
22
+ else
23
+ if b.respond_to?(:order)
24
+ -1
25
+ else
26
+ 1
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ # Returns the child node having the name equal to the string passed as argument or nil if such child does not exist
33
+ def find_child(child_name)
34
+ children.find(child_name)
35
+ end
36
+
37
+ # Returns a Hash with the node's defined variable names (as keys) and their respective value (as values).
38
+ def variables(include_defined_in_parent = true)
39
+ unless self.parent.nil? or include_defined_in_parent == false
40
+ v = self.parent.variables
41
+ else
42
+ v = {}
43
+ end
44
+ v.merge!(@variables)
45
+ end
46
+
47
+ # Returns a Hash containing the node's parameters (as keys) and their respective value (as values).
48
+ def params
49
+ @params
50
+ end
51
+
52
+ # Alias for variables
53
+ def vars(include_defined_in_parent = true)
54
+ variables(include_defined_in_parent)
55
+ end
56
+
57
+ protected
58
+
59
+ # Creates an INSTANCE method dynamically
60
+ def create_method(name, &block)
61
+ self.metaclass.send(:define_method, name, &block)
62
+ end
63
+ end
64
+
65
+
66
+
67
+ class SiteNode < TreeNode
68
+ def initialize(name, params = {}, parent = nil)
69
+ super(name, params, parent)
70
+ if File.exist? File.expand_path("project/site/variables.yml", MOKA_ROOT)
71
+ site_vars = YAML.load_file(File.expand_path("project/site/variables.yml", MOKA_ROOT)) || {}
72
+ site_vars.each do |key, value|
73
+ unless RESERVED_NAMES.include? key
74
+ self.instance_variable_set "@#{key}", value
75
+ @variables[key.to_s] = value
76
+ self.create_method(key) do self.instance_variable_get("@#{key}") end
77
+ self.create_method("#{key}=") do |v| self.instance_variable_set("@#{key}", v); @variables[key.to_s] = v end
78
+ end
79
+ end
80
+ end
81
+
82
+ params.each do |key, value|
83
+ key.gsub!(/\s/, "_")
84
+ if value.is_a?(Hash)
85
+ self.instance_variable_set "@#{key}", GroupNode.new(key, value, self)
86
+ @children << instance_eval("@#{key}")
87
+ else
88
+ self.instance_variable_set "@#{key}", value
89
+ @params[key.to_s] = value
90
+ end
91
+ self.create_method(key) do self.instance_variable_get("@#{key}") end
92
+ end
93
+ end
94
+
95
+ # Returns a NodeArray object containing all the site's groups (the children of the site node)
96
+ def groups
97
+ self.children
98
+ end
99
+
100
+ # Returns the group having the name equal to the string passed as argument or nil if such group does not exist
101
+ def find_group(group_name)
102
+ children.find(group_name)
103
+ end
104
+
105
+ # Save site variables in the variables.yml file
106
+ def save
107
+ f = File.open( File.expand_path("project/site/variables.yml", MOKA_ROOT), 'w' ) do |out|
108
+ YAML.dump( variables(false), out )
109
+ end
110
+ end
111
+ end
112
+
113
+
114
+
115
+ class GroupNode < TreeNode
116
+ attr_accessor :site
117
+
118
+ def initialize(name, params = {}, parent = nil)
119
+ super(name, params, parent)
120
+ @site = parent
121
+
122
+ if File.exist? File.expand_path("project/site/#{name}/variables.yml", MOKA_ROOT)
123
+ group_vars = YAML.load_file(File.expand_path("project/site/#{name}/variables.yml", MOKA_ROOT)) || {}
124
+ else
125
+ group_vars = {}
126
+ end
127
+ @site.variables.merge(group_vars).each do |key, value|
128
+ unless RESERVED_NAMES.include? key
129
+ self.instance_variable_set "@#{key}", value
130
+ @variables[key.to_s] = value if group_vars.keys.include? key.to_s
131
+ self.create_method(key) do self.instance_variable_get("@#{key}") end
132
+ self.create_method("#{key}=") do |v| self.instance_variable_set("@#{key}", v); @variables[key.to_s] = v end
133
+ end
134
+ end
135
+
136
+ params.each do |key, value|
137
+ key.gsub!(/\s/, "_")
138
+ if value.is_a?(Hash)
139
+ self.instance_variable_set "@#{key}", PageNode.new(key, value, self)
140
+ @children << instance_eval("@#{key}")
141
+ else
142
+ self.instance_variable_set "@#{key}", value
143
+ @params[key.to_s] = value
144
+ end
145
+ self.create_method(key) do self.instance_variable_get("@#{key}") end
146
+ end
147
+ end
148
+
149
+ # Returns a NodeArray object containing all the pages in the group (its children nodes)
150
+ def pages
151
+ self.children
152
+ end
153
+
154
+ # Looks for a page in the group having the name equal to the string passed as argument. Returns the page or nil if no such page was found.
155
+ def find_page(page_name)
156
+ children.find(page_name)
157
+ end
158
+
159
+ # Save group variables in the variables.yml file
160
+ def save
161
+ f = File.open( File.expand_path("project/site/#{self.name}/variables.yml", MOKA_ROOT), 'w' ) do |out|
162
+ YAML.dump( variables(false), out )
163
+ end
164
+ end
165
+ end
166
+
167
+
168
+
169
+ class PageNode < TreeNode
170
+ attr_accessor :group
171
+
172
+ def initialize(name, params = {}, parent = nil)
173
+ super(name, params, parent)
174
+ @group = parent
175
+
176
+ if File.exist? File.expand_path("project/site/#{@group.name}/#{name}/variables.yml", MOKA_ROOT)
177
+ page_vars = YAML.load_file(File.expand_path("project/site/#{@group.name}/#{name}/variables.yml", MOKA_ROOT)) || {}
178
+ else
179
+ page_vars = {}
180
+ end
181
+ @group.variables.merge(page_vars).each do |key, value|
182
+ unless RESERVED_NAMES.include? key
183
+ self.instance_variable_set("@#{key}", value)
184
+ @variables[key.to_s] = value if page_vars.keys.include? key.to_s
185
+ self.create_method(key) do self.instance_variable_get("@#{key}") end
186
+ self.create_method("#{key}=") do |v| self.instance_variable_set("@#{key}", v); @variables[key.to_s] = v end
187
+ end
188
+ end
189
+
190
+ params.each do |key, value|
191
+ key.gsub!(/\s/, "_")
192
+ self.instance_variable_set "@#{key}", value
193
+ @params[key.to_s] = value
194
+ self.create_method(key) do self.instance_variable_get("@#{key}") end
195
+ end
196
+ end
197
+
198
+ # Save page variables in the variables.yml file
199
+ def save
200
+ f = File.open( File.expand_path("project/site/#{@group.name}/#{self.name}/variables.yml", MOKA_ROOT), 'w' ) do |out|
201
+ YAML.dump( variables(false), out )
202
+ end
203
+ end
204
+ end
205
+
206
+ class NodeArray < Array
207
+ # Like an Array, but with some other helpful methods to filter, order and select elements. The methods are intended to work with elements being instances of classes extending TreeNode (like SiteNode, GroupNode or PageNode).
208
+
209
+ # Returns the element having the value of the variable name equal to the argument, or nil if such an element does not exist.
210
+ def find(name)
211
+ self.each do |c|
212
+ if c.respond_to?(:name) and c.name == name.to_s
213
+ return c
214
+ end
215
+ end
216
+ return nil
217
+ end
218
+
219
+ # Orders the elements by a variable. The elements that do not have that variable are placed last.
220
+ def order_by(ordering_var)
221
+ return self.sort do |a, b|
222
+ if a.respond_to?(ordering_var.to_sym) and b.respond_to?(ordering_var.to_sym)
223
+ a.send(ordering_var.to_sym) <=> b.send(ordering_var.to_sym)
224
+ else
225
+ if b.respond_to?(ordering_var.to_sym)
226
+ -1
227
+ else
228
+ 1
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ # Returns another NodeArray containing only the elements satisfying the conditions. conditions can be a Hash containing pairs variable_name => variable_value or a string to be evalued as ruby code.
235
+ #
236
+ # ==== Examples:
237
+ #
238
+ # @site.groups.where({:somevar => somevalue, :another_var => another_value})
239
+ #
240
+ # @site.groups.where("order < 5")
241
+ #
242
+ def where(conditions)
243
+ found = NodeArray.new
244
+ self.each do |c|
245
+ if conditions.is_a? Hash
246
+ satisfied = true
247
+ conditions.each do |var_name, var_value|
248
+ unless c.respond_to?(var_name.to_sym) and c.send(var_name.to_sym) == var_value
249
+ satisfied = false
250
+ break
251
+ end
252
+ end
253
+ if satisfied
254
+ found << c
255
+ end
256
+ else # conditions should be a string (or something that acts like one)
257
+ if c.instance_eval(conditions)
258
+ found << c
259
+ end
260
+ end
261
+ end
262
+ return found
263
+ end
264
+
265
+ end
266
+ end
267
+ end
268
+
269
+ class Object
270
+ # Needed for define_method to add INSTANCE methods dynamically
271
+ def metaclass
272
+ class << self; self; end
273
+ end
274
+ end
@@ -0,0 +1,13 @@
1
+ class String
2
+
3
+ # Returns the string with the first character of each word capitalized, and with underscores substituted by spaces.
4
+ def titleize
5
+ self.humanize.gsub(/\b('?[a-z])/) { $1.capitalize }
6
+ end
7
+
8
+ # Returns the string with the very first character capitalized, and with underscores substituted by spaces.
9
+ def humanize
10
+ self.gsub(/_/, " ").capitalize
11
+ end
12
+
13
+ end
@@ -0,0 +1,45 @@
1
+ module Moka
2
+ class Utilities
3
+
4
+ def self.parse_grouppage(grouppage)
5
+ # parse group:page syntax and return [page, group]
6
+ semicolon = grouppage.index ":"
7
+ unless semicolon.nil?
8
+ return [grouppage[(semicolon + 1)..-1], grouppage[0..(semicolon-1)]]
9
+ else
10
+ return [grouppage, "root"]
11
+ end
12
+ end
13
+
14
+ def self.parse_argvalue(argvalue)
15
+ # parse argument=value syntax and return [argument, value]
16
+ equal = argvalue.index "="
17
+ unless equal.nil?
18
+ arg_name = argvalue[0..(equal-1)]
19
+ arg_value = argvalue[(equal + 1)..-1]
20
+ else
21
+ arg_name = argvalue
22
+ arg_value = nil
23
+ end
24
+ return [arg_name, arg_value]
25
+ end
26
+
27
+ def self.eval_erb_haml(code, ext, scope)
28
+ require "rubygems"
29
+ # evaluates erb or haml code
30
+ if ext == "erb"
31
+ require 'erb'
32
+ eval_string = ERB.new(code).result(scope)
33
+ elsif ext == "haml"
34
+ require 'haml'
35
+ eval_string = Haml::Engine.new(code).render(scope)
36
+ end
37
+ return eval_string
38
+ end
39
+
40
+ def self.deepcopy(obj)
41
+ Marshal::load(Marshal::dump(obj))
42
+ end
43
+
44
+ end
45
+ end