summaryrefslogtreecommitdiff
path: root/lib/menu.rb
diff options
context:
space:
mode:
authorelijah <elijah@riseup.net>2013-02-12 21:33:39 -0800
committerelijah <elijah@riseup.net>2013-02-12 21:33:39 -0800
commit71ec0edea3f87fb69222dbb6fe025c2211402ca2 (patch)
tree5490323e8686df14165ccf5f37fa2d691fc99b88 /lib/menu.rb
parent00c785b728c5d97335b87e3eb7d10b9ad0c46d35 (diff)
added capacity for pulling static pages from multiple directory source trees.
Diffstat (limited to 'lib/menu.rb')
-rw-r--r--lib/menu.rb133
1 files changed, 95 insertions, 38 deletions
diff --git a/lib/menu.rb b/lib/menu.rb
index 71690a4..c156e07 100644
--- a/lib/menu.rb
+++ b/lib/menu.rb
@@ -1,47 +1,45 @@
-class Menu < Array
- attr_accessor :parent
+#
+# A navigation menu class
+#
- #
- # class methods
- #
+class Menu
+ attr_accessor :parent
+ attr_accessor :children
+ attr_accessor :name
#
- # load the menu.txt file, recursively, and build the in-memory menu array
+ # load the menu.txt file and build the in-memory menu array
#
- def self.load(menu_file_path)
- @menu = Menu.new
+ def load(menu_file_path)
File.open(menu_file_path) do |file|
- append_menu_item(@menu, file)
+ parse_menu(file)
end
end
- def self.menu
- @menu || Menu.new
+ def initialize(name, parent=nil)
+ self.name = name
+ self.parent = parent
+ self.children = []
end
- def self.create(elements=[], parent=nil)
- menu = Menu[elements]
- menu.parent = parent
- return menu
- end
+ ##
+ ## public methods
+ ##
#
- # public methods
+ # returns the menu under the item that matches item_name.
#
-
def submenu(item_name=nil)
if item_name
- submenu = detect {|item| item[0] == item_name} || Menu.new
+ self.children.detect {|child| child.name == item_name} || Menu.new
else
- submenu = self
+ self.children
end
- return submenu[1..-1] # strip of first element
- end
-
- def name
- first
end
+ #
+ # returns path from root to this leaf as an array
+ #
def path
@path ||= begin
if parent == nil
@@ -52,27 +50,86 @@ class Menu < Array
end
end
+ def each(&block)
+ children.each(&block)
+ end
+
+ def size
+ children.size
+ end
+
+ #
+ # returns true if menu's path starts with +path_prefix+
+ #
+ def path_starts_with?(path_prefix)
+ array_starts_with?(path, path_prefix)
+ end
+
+ def path_prefix_of?(full_path)
+ array_starts_with?(full_path, path)
+ end
+
+ #
+ # returns true if this menu item is the terminus menu item for path.
+ # (meaning that there are no children that match more path segments)
+ #
+ def leaf_for_path?(path)
+ return false unless path_prefix_of?(path)
+ next_path_segment = (path - self.path).first
+ return false if next_path_segment.nil?
+ return !children.detect {|i| i.name == next_path_segment}
+ end
+
+ def inspect(indent=0)
+ lines = []
+ lines << ' '*indent + '- ' + self.name
+ self.children.each do |child|
+ lines << child.inspect(indent+1)
+ end
+ lines.join("\n")
+ end
+
+ #
+ # private & protected methods
+ #
+
+ protected
+
+ def add_child(name)
+ self.children << Menu.new(name, self)
+ end
+
private
- def self.append_menu_item(menu, file)
- begin
+ def array_starts_with?(big_array, small_array)
+ small_array.length.times do |i|
+ if small_array[i] != big_array[i]
+ return false
+ end
+ end
+ return true
+ end
+
+
+ def parse_menu(file)
+ while true
item = file.readline
- rescue EOFError
- # do nothing
- else
- if item !~ /^\s*#/
+ if item.strip.chars.any? && item !~ /^\s*#/
depth = item.scan(" ").size
- sub_menu = sub_menu_for_depth(menu, depth)
- sub_menu << Menu.create(item.strip, sub_menu)
+ last_menu_at_depth(depth).add_child(item.strip)
end
- append_menu_item(menu, file)
end
+ rescue EOFError
+ # done loading
end
- def self.sub_menu_for_depth(menu, depth)
- sub_menu = menu
- depth.times { sub_menu = sub_menu[-1] }
- sub_menu
+ #
+ # returns the last list of children at the specified depth
+ #
+ def last_menu_at_depth(depth)
+ menu = self
+ depth.times { menu = menu.children.last }
+ menu
end
end \ No newline at end of file