From 71ec0edea3f87fb69222dbb6fe025c2211402ca2 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 12 Feb 2013 21:33:39 -0800 Subject: added capacity for pulling static pages from multiple directory source trees. --- lib/menu.rb | 133 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 95 insertions(+), 38 deletions(-) (limited to 'lib/menu.rb') 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 -- cgit v1.2.3