<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>Rakefile</filename>
    </added>
    <added>
      <filename>test/example_site/pages/about.html.erb</filename>
    </added>
    <added>
      <filename>test/example_site/pages/index.html.erb</filename>
    </added>
    <added>
      <filename>test/example_site/pages/things/a.html.erb</filename>
    </added>
    <added>
      <filename>test/example_site/public/images/.gitignore</filename>
    </added>
    <added>
      <filename>test/example_site/public/javascripts/.gitignore</filename>
    </added>
    <added>
      <filename>test/example_site/public/stylesheets/.gitignore</filename>
    </added>
    <added>
      <filename>test/example_site/public/videos/.gitignore</filename>
    </added>
    <added>
      <filename>test/test_bones.rb</filename>
    </added>
    <added>
      <filename>test/test_cache.rb</filename>
    </added>
    <added>
      <filename>test/test_example_site.rb</filename>
    </added>
    <added>
      <filename>test/test_helper.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -14,7 +14,7 @@ path = File.expand_path(path)
 FileUtils.mkdir(path) unless File.directory?(path)
 
 # Set the root to the path
-ROOT = path
+BONES_ROOT = path
 
 require 'boot.rb'
 require 'init.rb'</diff>
      <filename>bin/bones</filename>
    </modified>
    <modified>
      <diff>@@ -3,11 +3,41 @@
 # do the dirty work.
 class Bones
   class &lt;&lt; self
-    attr_accessor :base
+    attr_accessor :base, :root
+    attr_accessor :system_path, :pages_path, :layouts_path
+    attr_accessor :booted
     
     def base
       @base || ''
     end
+    
+    # Path to the root of the bones project
+    # Defaults to current directory
+    def root
+      @root ||= File.expand_path('.')
+    end
+    
+    # Path to the bones system files
+    # Defaults to the directory containing this file
+    def system_path
+      @system_path ||= File.expand_path(File.dirname(__FILE__))
+    end
+    
+    # Path to the directory containing the page templates
+    #   [root]/pages
+    def pages_path
+      @pages_path || root / 'pages'
+    end
+    
+    # Path to the directory containing the layout templates
+    #   [root]/layouts
+    def layouts_path
+      @layouts_path || root / 'layouts'
+    end
+    
+    def booted?
+      @booted
+    end
   end
   
   # Process incoming request (for real this time!)
@@ -29,7 +59,7 @@ class Bones
   
   # Returns array of all pages (excluding partials)
   def self.pages
-    Dir.chdir(PAGES) do
+    Dir.chdir(Bones.pages_path) do
       Dir.glob('**/*.html.erb').map do |f|
         f.starts_with?('_') ? nil : f.gsub('.html.erb', '')
       end.compact
@@ -48,8 +78,8 @@ class Bones
     # Load all available helpers
     def self.include_helpers
       files = [
-        Dir.glob(SYSTEM / 'helpers/*_helper.rb'),
-        Dir.glob(ROOT / 'helpers/*_helper.rb')
+        Dir.glob(Bones.system_path / 'helpers/*_helper.rb'),
+        Dir.glob(Bones.root / 'helpers/*_helper.rb')
       ].flatten
       
       # Include each helper
@@ -61,7 +91,7 @@ class Bones
     end
     
     # Load the helpers
-    include_helpers if Object.const_defined?(:SYSTEM)
+    include_helpers if Bones.booted?
     
     # Initialize template with path and optional layout
     def initialize(path, layout=-1, options={})
@@ -80,9 +110,9 @@ class Bones
     def filename
       if @path =~ /raw$/
         layout false
-        path = SYSTEM / 'pages' / 'directory.html.erb'
+        path = Bones.system_path / 'pages' / 'directory.html.erb'
       else
-        path = PAGES / @path
+        path = Bones.pages_path / @path
         path /= 'index' if File.directory?(path) or path.ends_with?('/')
         path += '.html.erb'
       end
@@ -95,7 +125,7 @@ class Bones
     
     # Full path to layout file
     def layout_filename
-      path = LAYOUTS / layout.to_s + '.html.erb'
+      path = Bones.layouts_path / layout.to_s + '.html.erb'
     end
     
     # Gets/sets layout
@@ -114,7 +144,7 @@ class Bones
       src = (local_assigns_source || '') + (src || '')
       @content_for_layout = eval(src) # erb.result(binding)
       
-      if layout
+      if layout &amp;&amp; File.file?(layout_filename)
         erb = ERB.new(File.read(layout_filename))
         erb.result(binding)
       else</diff>
      <filename>lib/bones.rb</filename>
    </modified>
    <modified>
      <diff>@@ -15,13 +15,13 @@ class Bones
     end
     
     def original_destination
-      @original_destination || (ROOT / 'public')
+      @original_destination || (Bones.root / 'public')
     end
   
     # Copies all public directories to the new release directory
     def copy_public_directories
       public_directories.each do |src|
-        FileUtils.copy_entry ROOT / 'public' / src, destination / src
+        FileUtils.copy_entry Bones.root / 'public' / src, destination / src
       end
     end  
   end
@@ -41,7 +41,7 @@ class Bones
     # $&gt; Bones::Versioned.directories
     # $&gt; =&gt; [&quot;/v1&quot;, &quot;/v2&quot;, ... &quot;/vN&quot;]
     def self.directories(base=nil)
-      base ||= ROOT / 'public'
+      base ||= Bones.root / 'public'
       FileUtils.mkdir_p(base) unless File.directory?(base)
       Dir.chdir(base) do
         Dir.glob(&quot;#{DIR_PREFIX}**&quot;).inject([]) do |dirs, dir|</diff>
      <filename>lib/bones/release.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,9 @@
-SYSTEM  = File.dirname(__FILE__)
-ROOT    = File.expand_path('.') unless Object.const_defined?(:ROOT)
-PAGES   = File.join(ROOT, 'pages')
-LAYOUTS = File.join(ROOT, 'layouts')
+require File.join(File.dirname(__FILE__), 'bones.rb')
 
-$:.unshift(SYSTEM)
-$:.unshift(File.join(ROOT, 'lib'))
+Bones.root = BONES_ROOT if Object.const_defined?(:BONES_ROOT)
+
+$:.unshift(Bones.system_path)
+$:.unshift(File.join(Bones.root, 'lib'))
 
 require 'rubygems'
 require 'yaml'
@@ -17,17 +16,19 @@ require 'erb'
 require 'bones'
 require 'bones/release'
 
+Bones.booted = true
+
 def directories(base)
   Dir.chdir(base) do
     Dir.entries(base).map do |e|
       next if e =~ /^\.+$/ 
       File.directory?(base / e) ? '/' + e : nil
     end.compact
-  end  
+  end
 end
 
 def page_directories
-  directories(ROOT / 'pages')
+  directories(Bones.root / 'pages')
 end
 
 def versioned_directories
@@ -35,5 +36,5 @@ def versioned_directories
 end
 
 def public_directories
-  directories(ROOT / 'public') - page_directories - versioned_directories
+  directories(Bones.root / 'public') - page_directories - versioned_directories
 end
\ No newline at end of file</diff>
      <filename>lib/boot.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,10 +21,13 @@ class Bones
           method = &quot;#{k}=&quot;.to_sym
           send(method, v) if respond_to?(method)
         end
+        
+        self
       end
   
       # Process arguments
       def self.process(args)
+        args = [] if args.blank?
         options = new
     
         OptionParser.new do |o|
@@ -72,7 +75,7 @@ class Bones
       end
       
       def default_destination
-        File.expand_path(ROOT / 'public')
+        File.expand_path(Bones.root / 'public')
       end
   
       # Returns true if the versions enabled
@@ -94,7 +97,14 @@ class Bones
     attr_accessor :options
     
     def initialize(options=nil)
-      self.options = Options === options ? options : Options.process(options)
+      self.options = case options
+      when Hash
+        Options.new.merge(options)
+      when Options
+        options
+      else  
+        Options.process(options)
+      end  
     end
     
     def self.run(options=nil)
@@ -105,7 +115,7 @@ class Bones
       version = options.versioned? ? options.release.versioned_directory_name : nil
       
       # Process each page
-      Dir.chdir(ROOT) do
+      Dir.chdir(Bones.root) do
         puts &quot;** Note: No files/directories will be modified (noop flag)&quot; if options.noop        
         puts &quot;** Writing to: #{options.destination}&quot;
         puts &quot;** Using base: #{options.base}&quot; unless options.base.blank?
@@ -115,14 +125,9 @@ class Bones
         pages.each_with_index do |page, index|
           print  &quot;\r     %-70s (%4d/%4d)&quot; % [[version, page].compact.join('/') + '.html', index + 1, total]
           $stdout.flush
-          template = Bones::Template.new(page)
-          template.request = generate_mock_request(:path_info =&gt; page)
-          result = template.compile
-          result.gsub!(/(href|src|action|url)(=&quot;|\()([-A-Za-z0-9_\.\/]+)([^:]*?)(&quot;|\))/) do |match|
-            property, url, params = $1, normalize_url(original_url = $3, options.base), $4
-            property =~ /url/ ? 'url(%s%s)' % [url, params] : '%s=&quot;%s%s&quot;' % [property, url, params]
-          end
-          path = options.destination / page + '.html'
+          
+          result = process_page(page)
+          path   = options.destination / page + '.html'
           
           unless options.noop
             FileUtils.mkdir_p(File.dirname(path))
@@ -136,15 +141,24 @@ class Bones
           puts &quot;** Copying public files&quot;
           options.release.copy_public_directories unless options.noop
         end
-  
-        # puts &quot;** Cached to: #{options.destination}&quot; 
-        # puts &quot;** Using base: #{options.base}&quot; unless options.base.blank?
-        # puts &quot;** Note: No files/directories were modified (noop flag)&quot; if options.noop
       end
 
       puts &quot;** Done.&quot;      
     end
     
+    def process_page(page)
+      template = Bones::Template.new(page)
+      template.request = generate_mock_request(:path_info =&gt; page)
+      process_template(template.compile)
+    end
+    
+    def process_template(result)
+      result.gsub(/(href|src|action|url)(=&quot;|\()([-A-Za-z0-9_\.\/]+)([^:]*?)(&quot;|\))/) do |match|
+        property, url, params = $1, normalize_url(original_url = $3), $4
+        property =~ /url/ ? 'url(%s%s)' % [url, params] : '%s=&quot;%s%s&quot;' % [property, url, params]
+      end      
+    end
+    
     # Fixes the given URL path to begin at given base.
     # In addition, the .html extension will be added if
     # the path is a page.
@@ -152,7 +166,7 @@ class Bones
     # For example, if the base is /some_folder,
     #   normalize_url('/page_path', '/some_folder')
     #   # =&gt; /some_folder/page_path.html
-    def normalize_url(path, base='')
+    def normalize_url(path)
       @known_pairs ||= {}
       @public_directories_regex ||= Regexp.new(public_directories.join('|'))
   
@@ -160,19 +174,19 @@ class Bones
         return v
       else
         value = case
-        when path =~ /\..+/ # any path with an extension should be ignored
-          path  
         when path =~ /^(\w{3,}:\/\/|mailto)/
+          # don't do anything to this type of URL
           return path
         when path =~ @public_directories_regex
           path
         when File.directory?('pages' / path)
           path
         else
-          path + '.html'
+          # don't add .html if there's already an extension
+          path =~ /\..+/ ? path : path + '.html'
         end
-    
-        @known_pairs[path] = base / value
+        
+        @known_pairs[path] = options.base / value
       end    
     end    
 </diff>
      <filename>lib/cache.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,19 +18,19 @@ class BonesInitializer
   def self.run
     puts &quot;** Initializing&quot;
 
-    ensure_directory(ROOT / 'public' / 'javascripts')
-    ensure_directory(ROOT / 'public' / 'stylesheets')
-    pages_new = ensure_directory(ROOT / 'pages')
-    ensure_directory(ROOT / 'layouts')
-    ensure_directory(ROOT / 'helpers')
+    ensure_directory(Bones.root / 'public' / 'javascripts')
+    ensure_directory(Bones.root / 'public' / 'stylesheets')
+    pages_new = ensure_directory(Bones.root / 'pages')
+    ensure_directory(Bones.root / 'layouts')
+    ensure_directory(Bones.root / 'helpers')
 
     if pages_new
-      ensure_file(ROOT / 'pages' / 'index.html.erb') do |f|
-        f.write File.read(SYSTEM / 'pages' / 'intro.html.erb')
+      ensure_file(Bones.root / 'pages' / 'index.html.erb') do |f|
+        f.write File.read(Bones.system_path / 'pages' / 'intro.html.erb')
       end
     end  
 
-    ensure_file(ROOT / 'layouts' / 'application.html.erb') do |f|
+    ensure_file(Bones.root / 'layouts' / 'application.html.erb') do |f|
       f.write &lt;&lt;-HTML
     &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;
       &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
@@ -49,11 +49,11 @@ class BonesInitializer
       HTML
     end
 
-    ensure_file(ROOT / 'public' / 'stylesheets' / 'styles.css')
+    ensure_file(Bones.root / 'public' / 'stylesheets' / 'styles.css')
 
-    ensure_file(ROOT / 'Rakefile') do |f|
+    ensure_file(Bones.root / 'Rakefile') do |f|
       puts &quot;** Adding Rakefile to parent directory&quot;
-      f.write File.read(SYSTEM / 'Rakefile')
+      f.write File.read(Bones.system_path / 'Rakefile')
     end
 
     puts &lt;&lt;-HELP if __FILE__ == $0</diff>
      <filename>lib/init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -28,7 +28,7 @@ class BonesServer
        use Rack::CommonLogger
        use Rack::ShowExceptions
        use Rack::Reloader
-       use Rack::Static, :urls =&gt; statics, :root =&gt; ROOT / 'public'
+       use Rack::Static, :urls =&gt; statics, :root =&gt; Bones.root / 'public'
        run BonesProxy.new
     end
 </diff>
      <filename>lib/server.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>7ba791b60dbb5e8bb0a17ea6f879779efd091bf2</id>
    </parent>
  </parents>
  <author>
    <name>Chris Scharf</name>
    <email>scharfie@gmail.com</email>
  </author>
  <url>http://github.com/rpheath/bones/commit/28dcdf93ce15e33f231d4f5169d966b217ccbed4</url>
  <id>28dcdf93ce15e33f231d4f5169d966b217ccbed4</id>
  <committed-date>2009-02-05T11:52:15-08:00</committed-date>
  <authored-date>2009-02-05T11:52:15-08:00</authored-date>
  <message>Added tests</message>
  <tree>e1334f52dbc5c33df07541c51b7bdf89cdd37a3f</tree>
  <committer>
    <name>Chris Scharf</name>
    <email>scharfie@gmail.com</email>
  </committer>
</commit>
