jekyll 0.8.0 → 0.9.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.
Potentially problematic release.
This version of jekyll might be problematic. Click here for more details.
- data/History.txt +8 -0
- data/bin/jekyll +10 -18
- data/jekyll.gemspec +4 -2
- data/lib/jekyll.rb +1 -1
- data/lib/jekyll/convertible.rb +18 -3
- data/lib/jekyll/migrators/drupal.rb +86 -0
- data/lib/jekyll/migrators/marley.rb +53 -0
- data/lib/jekyll/page.rb +15 -14
- data/lib/jekyll/post.rb +13 -10
- data/lib/jekyll/site.rb +31 -0
- data/lib/jekyll/static_file.rb +1 -2
- data/test/test_site.rb +33 -0
- metadata +6 -4
    
        data/History.txt
    CHANGED
    
    | @@ -1,3 +1,11 @@ | |
| 1 | 
            +
            == 0.9.0 / 2010-12-15
         | 
| 2 | 
            +
              * Minor Enhancements
         | 
| 3 | 
            +
                * Use OptionParser's [no-] functionality for better boolean parsing.
         | 
| 4 | 
            +
                * Add Drupal migrator (#245)
         | 
| 5 | 
            +
                * Complain about YAML and Liquid errors (#249)
         | 
| 6 | 
            +
                * Remove orphaned files during regeneration (#247)
         | 
| 7 | 
            +
                * Add Marley migrator (#28)
         | 
| 8 | 
            +
             | 
| 1 9 | 
             
            == 0.8.0 / 2010-11-22
         | 
| 2 10 | 
             
              * Minor Enhancements
         | 
| 3 11 | 
             
                * Add wordpress.com importer (#207)
         | 
    
        data/bin/jekyll
    CHANGED
    
    | @@ -23,16 +23,12 @@ options = {} | |
| 23 23 | 
             
            opts = OptionParser.new do |opts|
         | 
| 24 24 | 
             
              opts.banner = help
         | 
| 25 25 |  | 
| 26 | 
            -
              opts.on("--safe", "Safe mode (default unsafe)") do
         | 
| 27 | 
            -
                options['safe'] =  | 
| 26 | 
            +
              opts.on("--[no-]safe", "Safe mode (default unsafe)") do |safe|
         | 
| 27 | 
            +
                options['safe'] = safe
         | 
| 28 28 | 
             
              end
         | 
| 29 29 |  | 
| 30 | 
            -
              opts.on("--auto", "Auto-regenerate") do
         | 
| 31 | 
            -
                options['auto'] =  | 
| 32 | 
            -
              end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
              opts.on("--no-auto", "No auto-regenerate") do
         | 
| 35 | 
            -
                options['auto'] = false
         | 
| 30 | 
            +
              opts.on("--[no-]auto", "Auto-regenerate") do |auto|
         | 
| 31 | 
            +
                options['auto'] = auto
         | 
| 36 32 | 
             
              end
         | 
| 37 33 |  | 
| 38 34 | 
             
              opts.on("--server [PORT]", "Start web server (default port 4000)") do |port|
         | 
| @@ -44,12 +40,12 @@ opts = OptionParser.new do |opts| | |
| 44 40 | 
             
                  options['baseurl'] = baseurl
         | 
| 45 41 | 
             
              end
         | 
| 46 42 |  | 
| 47 | 
            -
              opts.on("--lsi", "Use LSI for better related posts") do
         | 
| 48 | 
            -
                options['lsi'] =  | 
| 43 | 
            +
              opts.on("--[no-]lsi", "Use LSI for better related posts") do |lsi|
         | 
| 44 | 
            +
                options['lsi'] = lsi
         | 
| 49 45 | 
             
              end
         | 
| 50 46 |  | 
| 51 | 
            -
              opts.on("--pygments", "Use pygments to highlight code") do
         | 
| 52 | 
            -
                options['pygments'] =  | 
| 47 | 
            +
              opts.on("--[no-]pygments", "Use pygments to highlight code") do |pygments|
         | 
| 48 | 
            +
                options['pygments'] = pygments
         | 
| 53 49 | 
             
              end
         | 
| 54 50 |  | 
| 55 51 | 
             
              opts.on("--rdiscount", "Use rdiscount gem for Markdown") do
         | 
| @@ -64,12 +60,8 @@ opts = OptionParser.new do |opts| | |
| 64 60 | 
             
                options['time'] = Time.parse(time)
         | 
| 65 61 | 
             
              end
         | 
| 66 62 |  | 
| 67 | 
            -
              opts.on("--future", "Render future dated posts") do
         | 
| 68 | 
            -
                options['future'] =  | 
| 69 | 
            -
              end
         | 
| 70 | 
            -
             | 
| 71 | 
            -
              opts.on("--no-future", "Do not render future dated posts") do
         | 
| 72 | 
            -
                options['future'] = false
         | 
| 63 | 
            +
              opts.on("--[no-]future", "Render future dated posts") do |future|
         | 
| 64 | 
            +
                options['future'] = future
         | 
| 73 65 | 
             
              end
         | 
| 74 66 |  | 
| 75 67 | 
             
              opts.on("--permalink [TYPE]", "Use 'date' (default) for YYYY/MM/DD") do |style|
         | 
    
        data/jekyll.gemspec
    CHANGED
    
    | @@ -4,8 +4,8 @@ Gem::Specification.new do |s| | |
| 4 4 | 
             
              s.rubygems_version = '1.3.5'
         | 
| 5 5 |  | 
| 6 6 | 
             
              s.name              = 'jekyll'
         | 
| 7 | 
            -
              s.version           = '0. | 
| 8 | 
            -
              s.date              = '2010- | 
| 7 | 
            +
              s.version           = '0.9.0'
         | 
| 8 | 
            +
              s.date              = '2010-12-15'
         | 
| 9 9 | 
             
              s.rubyforge_project = 'jekyll'
         | 
| 10 10 |  | 
| 11 11 | 
             
              s.summary     = "A simple, blog aware, static site generator."
         | 
| @@ -68,6 +68,8 @@ Gem::Specification.new do |s| | |
| 68 68 | 
             
                lib/jekyll/generators/pagination.rb
         | 
| 69 69 | 
             
                lib/jekyll/layout.rb
         | 
| 70 70 | 
             
                lib/jekyll/migrators/csv.rb
         | 
| 71 | 
            +
                lib/jekyll/migrators/drupal.rb
         | 
| 72 | 
            +
                lib/jekyll/migrators/marley.rb
         | 
| 71 73 | 
             
                lib/jekyll/migrators/mephisto.rb
         | 
| 72 74 | 
             
                lib/jekyll/migrators/mt.rb
         | 
| 73 75 | 
             
                lib/jekyll/migrators/textpattern.rb
         | 
    
        data/lib/jekyll.rb
    CHANGED
    
    | @@ -45,7 +45,7 @@ require_all 'jekyll/generators' | |
| 45 45 | 
             
            require_all 'jekyll/tags'
         | 
| 46 46 |  | 
| 47 47 | 
             
            module Jekyll
         | 
| 48 | 
            -
              VERSION = '0. | 
| 48 | 
            +
              VERSION = '0.9.0'
         | 
| 49 49 |  | 
| 50 50 | 
             
              # Default options. Overriden by values in _config.yml or command-line opts.
         | 
| 51 51 | 
             
              # (Strings rather symbols used for compatability with YAML).
         | 
    
        data/lib/jekyll/convertible.rb
    CHANGED
    
    | @@ -26,7 +26,11 @@ module Jekyll | |
| 26 26 | 
             
                  if self.content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
         | 
| 27 27 | 
             
                    self.content = self.content[($1.size + $2.size)..-1]
         | 
| 28 28 |  | 
| 29 | 
            -
                     | 
| 29 | 
            +
                    begin
         | 
| 30 | 
            +
                      self.data = YAML.load($1)
         | 
| 31 | 
            +
                    rescue => e
         | 
| 32 | 
            +
                      puts "YAML Exception: #{e.message}"
         | 
| 33 | 
            +
                    end
         | 
| 30 34 | 
             
                  end
         | 
| 31 35 |  | 
| 32 36 | 
             
                  self.data ||= {}
         | 
| @@ -63,7 +67,13 @@ module Jekyll | |
| 63 67 | 
             
                  # render and transform content (this becomes the final content of the object)
         | 
| 64 68 | 
             
                  payload["pygments_prefix"] = converter.pygments_prefix
         | 
| 65 69 | 
             
                  payload["pygments_suffix"] = converter.pygments_suffix
         | 
| 66 | 
            -
                   | 
| 70 | 
            +
                  
         | 
| 71 | 
            +
                  begin
         | 
| 72 | 
            +
                    self.content = Liquid::Template.parse(self.content).render(payload, info)
         | 
| 73 | 
            +
                  rescue => e
         | 
| 74 | 
            +
                    puts "Liquid Exception: #{e.message} in #{self.data["layout"]}"
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
                  
         | 
| 67 77 | 
             
                  self.transform
         | 
| 68 78 |  | 
| 69 79 | 
             
                  # output keeps track of what will finally be written
         | 
| @@ -73,7 +83,12 @@ module Jekyll | |
| 73 83 | 
             
                  layout = layouts[self.data["layout"]]
         | 
| 74 84 | 
             
                  while layout
         | 
| 75 85 | 
             
                    payload = payload.deep_merge({"content" => self.output, "page" => layout.data})
         | 
| 76 | 
            -
             | 
| 86 | 
            +
             | 
| 87 | 
            +
                    begin
         | 
| 88 | 
            +
                      self.output = Liquid::Template.parse(layout.content).render(payload, info)
         | 
| 89 | 
            +
                    rescue => e
         | 
| 90 | 
            +
                      puts "Liquid Exception: #{e.message} in #{self.data["layout"]}"
         | 
| 91 | 
            +
                    end
         | 
| 77 92 |  | 
| 78 93 | 
             
                    layout = layouts[layout.data["layout"]]
         | 
| 79 94 | 
             
                  end
         | 
| @@ -0,0 +1,86 @@ | |
| 1 | 
            +
            require 'rubygems'
         | 
| 2 | 
            +
            require 'sequel'
         | 
| 3 | 
            +
            require 'fileutils'
         | 
| 4 | 
            +
            require 'yaml'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # NOTE: This converter requires Sequel and the MySQL gems.
         | 
| 7 | 
            +
            # The MySQL gem can be difficult to install on OS X. Once you have MySQL
         | 
| 8 | 
            +
            # installed, running the following commands should work:
         | 
| 9 | 
            +
            # $ sudo gem install sequel
         | 
| 10 | 
            +
            # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            module Jekyll
         | 
| 13 | 
            +
              module Drupal
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                # Reads a MySQL database via Sequel and creates a post file for each
         | 
| 16 | 
            +
                # post in wp_posts that has post_status = 'publish'.
         | 
| 17 | 
            +
                # This restriction is made because 'draft' posts are not guaranteed to
         | 
| 18 | 
            +
                # have valid dates.
         | 
| 19 | 
            +
                QUERY = "SELECT node.nid, node.title, node_revisions.body, node.created, node.status FROM node, node_revisions WHERE (node.type = 'blog' OR node.type = 'story') AND node.vid = node_revisions.vid"
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def self.process(dbname, user, pass, host = 'localhost')
         | 
| 22 | 
            +
                  db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  FileUtils.mkdir_p "_posts"
         | 
| 25 | 
            +
                  FileUtils.mkdir_p "_drafts"
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  # Create the refresh layout
         | 
| 28 | 
            +
                  # Change the refresh url if you customized your permalink config
         | 
| 29 | 
            +
                  File.open("_layouts/refresh.html", "w") do |f|
         | 
| 30 | 
            +
                    f.puts <<EOF
         | 
| 31 | 
            +
            <!DOCTYPE html>
         | 
| 32 | 
            +
            <html>
         | 
| 33 | 
            +
            <head>
         | 
| 34 | 
            +
            <meta http-equiv="content-type" content="text/html; charset=utf-8" />
         | 
| 35 | 
            +
            <meta http-equiv="refresh" content="0;url={{ page.refresh_to_post_id }}.html" />
         | 
| 36 | 
            +
            </head>
         | 
| 37 | 
            +
            </html>
         | 
| 38 | 
            +
            EOF
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  db[QUERY].each do |post|
         | 
| 42 | 
            +
                    # Get required fields and construct Jekyll compatible name
         | 
| 43 | 
            +
                    node_id = post[:nid]
         | 
| 44 | 
            +
                    title = post[:title]
         | 
| 45 | 
            +
                    content = post[:body]
         | 
| 46 | 
            +
                    created = post[:created]
         | 
| 47 | 
            +
                    time = Time.at(created)
         | 
| 48 | 
            +
                    is_published = post[:status] == 1
         | 
| 49 | 
            +
                    dir = is_published ? "_posts" : "_drafts"
         | 
| 50 | 
            +
                    slug = title.strip.downcase.gsub(/(&|&)/, ' and ').gsub(/[\s\.\/\\]/, '-').gsub(/[^\w-]/, '').gsub(/[-_]{2,}/, '-').gsub(/^[-_]/, '').gsub(/[-_]$/, '')
         | 
| 51 | 
            +
                    name = time.strftime("%Y-%m-%d-") + slug + '.md'
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    # Get the relevant fields as a hash, delete empty fields and convert
         | 
| 54 | 
            +
                    # to YAML for the header
         | 
| 55 | 
            +
                    data = {
         | 
| 56 | 
            +
                       'layout' => 'post',
         | 
| 57 | 
            +
                       'title' => title.to_s,
         | 
| 58 | 
            +
                       'created' => created,
         | 
| 59 | 
            +
                     }.delete_if { |k,v| v.nil? || v == ''}.to_yaml
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    # Write out the data and content to file
         | 
| 62 | 
            +
                    File.open("#{dir}/#{name}", "w") do |f|
         | 
| 63 | 
            +
                      f.puts data
         | 
| 64 | 
            +
                      f.puts "---"
         | 
| 65 | 
            +
                      f.puts content
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                    # Make a file to redirect from the old Drupal URL
         | 
| 69 | 
            +
                    if is_published
         | 
| 70 | 
            +
                      FileUtils.mkdir_p "node/#{node_id}"
         | 
| 71 | 
            +
                      File.open("node/#{node_id}/index.md", "w") do |f|
         | 
| 72 | 
            +
                        f.puts "---"
         | 
| 73 | 
            +
                        f.puts "layout: refresh"
         | 
| 74 | 
            +
                        f.puts "refresh_to_post_id: /#{time.strftime("%Y/%m/%d/") + slug}"
         | 
| 75 | 
            +
                        f.puts "---"
         | 
| 76 | 
            +
                      end
         | 
| 77 | 
            +
                    end
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  # TODO: Make dirs & files for nodes of type 'page'
         | 
| 81 | 
            +
                    # Make refresh pages for these as well
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  # TODO: Make refresh dirs & files according to entries in url_alias table
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
              end
         | 
| 86 | 
            +
            end
         | 
| @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            require 'yaml'
         | 
| 2 | 
            +
            require 'fileutils'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Jekyll
         | 
| 5 | 
            +
              module Marley
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def self.regexp
         | 
| 8 | 
            +
                  { :id    => /^\d{0,4}-{0,1}(.*)$/,
         | 
| 9 | 
            +
                    :title => /^#\s*(.*)\s+$/,
         | 
| 10 | 
            +
                    :title_with_date => /^#\s*(.*)\s+\(([0-9\/]+)\)$/,
         | 
| 11 | 
            +
                    :published_on => /.*\s+\(([0-9\/]+)\)$/,
         | 
| 12 | 
            +
                    :perex => /^([^\#\n]+\n)$/,
         | 
| 13 | 
            +
                    :meta  => /^\{\{\n(.*)\}\}\n$/mi # Multiline Regexp 
         | 
| 14 | 
            +
                  }
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def self.process(marley_data_dir)
         | 
| 18 | 
            +
                  raise ArgumentError, "marley dir #{marley_data_dir} not found" unless File.directory?(marley_data_dir)
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  FileUtils.mkdir_p "_posts"
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  posts = 0
         | 
| 23 | 
            +
                  Dir["#{marley_data_dir}/**/*.txt"].each do |f|
         | 
| 24 | 
            +
                    next unless File.exists?(f)
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    #copied over from marley's app/lib/post.rb
         | 
| 27 | 
            +
                    file_content  = File.read(f)
         | 
| 28 | 
            +
                    meta_content  = file_content.slice!( self.regexp[:meta] )
         | 
| 29 | 
            +
                    body          = file_content.sub( self.regexp[:title], '').sub( self.regexp[:perex], '').strip
         | 
| 30 | 
            +
               
         | 
| 31 | 
            +
                    title = file_content.scan( self.regexp[:title] ).first.to_s.strip
         | 
| 32 | 
            +
                    prerex = file_content.scan( self.regexp[:perex] ).first.to_s.strip
         | 
| 33 | 
            +
                    published_on = DateTime.parse( post[:published_on] ) rescue File.mtime( File.dirname(f) )
         | 
| 34 | 
            +
                    meta          = ( meta_content ) ? YAML::load( meta_content.scan( self.regexp[:meta]).to_s ) : {}
         | 
| 35 | 
            +
                    meta['title'] = title
         | 
| 36 | 
            +
                    meta['layout'] = 'post'
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    formatted_date = published_on.strftime('%Y-%m-%d')
         | 
| 39 | 
            +
                    post_name =  File.dirname(f).split(%r{/}).last.gsub(/\A\d+-/, '')
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    name = "#{formatted_date}-#{post_name}" 
         | 
| 42 | 
            +
                    File.open("_posts/#{name}.markdown", "w") do |f|
         | 
| 43 | 
            +
                      f.puts meta.to_yaml
         | 
| 44 | 
            +
                      f.puts "---\n"
         | 
| 45 | 
            +
                      f.puts "\n#{prerex}\n\n" if prerex
         | 
| 46 | 
            +
                      f.puts body
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                    posts += 1
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                  "Created #{posts} posts!"
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
            end
         | 
    
        data/lib/jekyll/page.rb
    CHANGED
    
    | @@ -93,24 +93,25 @@ module Jekyll | |
| 93 93 | 
             
                    "url"        => File.join(@dir, self.url),
         | 
| 94 94 | 
             
                    "content"    => self.content })
         | 
| 95 95 | 
             
                end
         | 
| 96 | 
            +
                
         | 
| 97 | 
            +
                # Obtain destination path.
         | 
| 98 | 
            +
                #   +dest+ is the String path to the destination dir
         | 
| 99 | 
            +
                #
         | 
| 100 | 
            +
                # Returns destination file path.
         | 
| 101 | 
            +
                def destination(dest)
         | 
| 102 | 
            +
                  # The url needs to be unescaped in order to preserve the correct filename
         | 
| 103 | 
            +
                  path = File.join(dest, @dir, CGI.unescape(self.url))
         | 
| 104 | 
            +
                  path = File.join(path, "index.html") if self.url =~ /\/$/
         | 
| 105 | 
            +
                  path
         | 
| 106 | 
            +
                end
         | 
| 96 107 |  | 
| 97 108 | 
             
                # Write the generated page file to the destination directory.
         | 
| 98 | 
            -
                #   + | 
| 99 | 
            -
                #   +dest_suffix+ is a suffix path to the destination dir
         | 
| 109 | 
            +
                #   +dest+ is the String path to the destination dir
         | 
| 100 110 | 
             
                #
         | 
| 101 111 | 
             
                # Returns nothing
         | 
| 102 | 
            -
                def write( | 
| 103 | 
            -
                   | 
| 104 | 
            -
                   | 
| 105 | 
            -
                  FileUtils.mkdir_p(dest)
         | 
| 106 | 
            -
             | 
| 107 | 
            -
                  # The url needs to be unescaped in order to preserve the correct filename
         | 
| 108 | 
            -
                  path = File.join(dest, CGI.unescape(self.url))
         | 
| 109 | 
            -
                  if self.url =~ /\/$/
         | 
| 110 | 
            -
                    FileUtils.mkdir_p(path)
         | 
| 111 | 
            -
                    path = File.join(path, "index.html")
         | 
| 112 | 
            -
                  end
         | 
| 113 | 
            -
             | 
| 112 | 
            +
                def write(dest)
         | 
| 113 | 
            +
                  path = destination(dest)
         | 
| 114 | 
            +
                  FileUtils.mkdir_p(File.dirname(path))
         | 
| 114 115 | 
             
                  File.open(path, 'w') do |f|
         | 
| 115 116 | 
             
                    f.write(self.output)
         | 
| 116 117 | 
             
                  end
         | 
    
        data/lib/jekyll/post.rb
    CHANGED
    
    | @@ -177,22 +177,25 @@ module Jekyll | |
| 177 177 |  | 
| 178 178 | 
             
                  do_layout(payload, layouts)
         | 
| 179 179 | 
             
                end
         | 
| 180 | 
            +
                
         | 
| 181 | 
            +
                # Obtain destination path.
         | 
| 182 | 
            +
                #   +dest+ is the String path to the destination dir
         | 
| 183 | 
            +
                #
         | 
| 184 | 
            +
                # Returns destination file path.
         | 
| 185 | 
            +
                def destination(dest)
         | 
| 186 | 
            +
                  # The url needs to be unescaped in order to preserve the correct filename
         | 
| 187 | 
            +
                  path = File.join(dest, CGI.unescape(self.url))
         | 
| 188 | 
            +
                  path = File.join(path, "index.html") if template[/\.html$/].nil?
         | 
| 189 | 
            +
                  path
         | 
| 190 | 
            +
                end
         | 
| 180 191 |  | 
| 181 192 | 
             
                # Write the generated post file to the destination directory.
         | 
| 182 193 | 
             
                #   +dest+ is the String path to the destination dir
         | 
| 183 194 | 
             
                #
         | 
| 184 195 | 
             
                # Returns nothing
         | 
| 185 196 | 
             
                def write(dest)
         | 
| 186 | 
            -
                   | 
| 187 | 
            -
             | 
| 188 | 
            -
                  # The url needs to be unescaped in order to preserve the correct filename
         | 
| 189 | 
            -
                  path = File.join(dest, CGI.unescape(self.url))
         | 
| 190 | 
            -
             | 
| 191 | 
            -
                  if template[/\.html$/].nil?
         | 
| 192 | 
            -
                    FileUtils.mkdir_p(path)
         | 
| 193 | 
            -
                    path = File.join(path, "index.html")
         | 
| 194 | 
            -
                  end
         | 
| 195 | 
            -
             | 
| 197 | 
            +
                  path = destination(dest)
         | 
| 198 | 
            +
                  FileUtils.mkdir_p(File.dirname(path))
         | 
| 196 199 | 
             
                  File.open(path, 'w') do |f|
         | 
| 197 200 | 
             
                    f.write(self.output)
         | 
| 198 201 | 
             
                  end
         | 
    
        data/lib/jekyll/site.rb
    CHANGED
    
    | @@ -79,6 +79,7 @@ module Jekyll | |
| 79 79 | 
             
                  self.read
         | 
| 80 80 | 
             
                  self.generate
         | 
| 81 81 | 
             
                  self.render
         | 
| 82 | 
            +
                  self.cleanup
         | 
| 82 83 | 
             
                  self.write
         | 
| 83 84 | 
             
                end
         | 
| 84 85 |  | 
| @@ -151,6 +152,36 @@ module Jekyll | |
| 151 152 | 
             
                rescue Errno::ENOENT => e
         | 
| 152 153 | 
             
                  # ignore missing layout dir
         | 
| 153 154 | 
             
                end
         | 
| 155 | 
            +
                
         | 
| 156 | 
            +
                # Remove orphaned files and empty directories in destination
         | 
| 157 | 
            +
                #
         | 
| 158 | 
            +
                # Returns nothing
         | 
| 159 | 
            +
                def cleanup
         | 
| 160 | 
            +
                  # all files and directories in destination, including hidden ones
         | 
| 161 | 
            +
                  dest_files = []
         | 
| 162 | 
            +
                  Dir.glob(File.join(self.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
         | 
| 163 | 
            +
                    dest_files << file unless file =~ /\/\.{1,2}$/
         | 
| 164 | 
            +
                  end
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                  # files to be written
         | 
| 167 | 
            +
                  files = []
         | 
| 168 | 
            +
                  self.posts.each do |post|
         | 
| 169 | 
            +
                    files << post.destination(self.dest)
         | 
| 170 | 
            +
                  end
         | 
| 171 | 
            +
                  self.pages.each do |page|
         | 
| 172 | 
            +
                    files << page.destination(self.dest)
         | 
| 173 | 
            +
                  end
         | 
| 174 | 
            +
                  self.static_files.each do |sf|
         | 
| 175 | 
            +
                    files << sf.destination(self.dest)
         | 
| 176 | 
            +
                  end
         | 
| 177 | 
            +
                  
         | 
| 178 | 
            +
                  # adding files' parent directories
         | 
| 179 | 
            +
                  files.each { |file| files << File.dirname(file) unless files.include? File.dirname(file) }
         | 
| 180 | 
            +
                  
         | 
| 181 | 
            +
                  obsolete_files = dest_files - files
         | 
| 182 | 
            +
                  
         | 
| 183 | 
            +
                  FileUtils.rm_rf(obsolete_files)
         | 
| 184 | 
            +
                end
         | 
| 154 185 |  | 
| 155 186 | 
             
                # Write static files, pages and posts
         | 
| 156 187 | 
             
                #
         | 
    
        data/lib/jekyll/static_file.rb
    CHANGED
    
    | @@ -52,12 +52,11 @@ module Jekyll | |
| 52 52 | 
             
                # Returns false if the file was not modified since last time (no-op).
         | 
| 53 53 | 
             
                def write(dest)
         | 
| 54 54 | 
             
                  dest_path = destination(dest)
         | 
| 55 | 
            -
                  dest_dir = File.join(dest, @dir)
         | 
| 56 55 |  | 
| 57 56 | 
             
                  return false if File.exist? dest_path and !modified?
         | 
| 58 57 | 
             
                  @@mtimes[path] = mtime
         | 
| 59 58 |  | 
| 60 | 
            -
                  FileUtils.mkdir_p( | 
| 59 | 
            +
                  FileUtils.mkdir_p(File.dirname(dest_path))
         | 
| 61 60 | 
             
                  FileUtils.cp(path, dest_path)
         | 
| 62 61 |  | 
| 63 62 | 
             
                  true
         | 
    
        data/test/test_site.rb
    CHANGED
    
    | @@ -132,6 +132,39 @@ class TestSite < Test::Unit::TestCase | |
| 132 132 | 
             
                  assert_equal includes, @site.filter_entries(excludes + includes)
         | 
| 133 133 | 
             
                end
         | 
| 134 134 |  | 
| 135 | 
            +
                context 'with orphaned files in destination' do
         | 
| 136 | 
            +
                  setup do
         | 
| 137 | 
            +
                    clear_dest
         | 
| 138 | 
            +
                    @site.process
         | 
| 139 | 
            +
                    # generate some orphaned files:
         | 
| 140 | 
            +
                    # hidden file
         | 
| 141 | 
            +
                    File.open(dest_dir('.htpasswd'), 'w')
         | 
| 142 | 
            +
                    # single file
         | 
| 143 | 
            +
                    File.open(dest_dir('obsolete.html'), 'w')
         | 
| 144 | 
            +
                    # single file in sub directory
         | 
| 145 | 
            +
                    FileUtils.mkdir(dest_dir('qux'))
         | 
| 146 | 
            +
                    File.open(dest_dir('qux/obsolete.html'), 'w')
         | 
| 147 | 
            +
                    # empty directory
         | 
| 148 | 
            +
                    FileUtils.mkdir(dest_dir('quux'))
         | 
| 149 | 
            +
                  end
         | 
| 150 | 
            +
                  
         | 
| 151 | 
            +
                  teardown do
         | 
| 152 | 
            +
                    FileUtils.rm_f(dest_dir('.htpasswd'))
         | 
| 153 | 
            +
                    FileUtils.rm_f(dest_dir('obsolete.html'))
         | 
| 154 | 
            +
                    FileUtils.rm_rf(dest_dir('qux'))
         | 
| 155 | 
            +
                    FileUtils.rm_f(dest_dir('quux'))
         | 
| 156 | 
            +
                  end
         | 
| 157 | 
            +
                  
         | 
| 158 | 
            +
                  should 'remove orphaned files in destination' do
         | 
| 159 | 
            +
                    @site.process
         | 
| 160 | 
            +
                    assert !File.exist?(dest_dir('.htpasswd'))
         | 
| 161 | 
            +
                    assert !File.exist?(dest_dir('obsolete.html'))
         | 
| 162 | 
            +
                    assert !File.exist?(dest_dir('qux'))
         | 
| 163 | 
            +
                    assert !File.exist?(dest_dir('quux'))
         | 
| 164 | 
            +
                  end
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                end
         | 
| 167 | 
            +
                
         | 
| 135 168 | 
             
                context 'with an invalid markdown processor in the configuration' do
         | 
| 136 169 | 
             
                  should 'not throw an error at initialization time' do
         | 
| 137 170 | 
             
                    bad_processor = 'not a processor name'
         | 
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: jekyll
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 4 | 
            +
              hash: 59
         | 
| 5 5 | 
             
              prerelease: false
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 0
         | 
| 8 | 
            -
              -  | 
| 8 | 
            +
              - 9
         | 
| 9 9 | 
             
              - 0
         | 
| 10 | 
            -
              version: 0. | 
| 10 | 
            +
              version: 0.9.0
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - Tom Preston-Werner
         | 
| @@ -15,7 +15,7 @@ autorequire: | |
| 15 15 | 
             
            bindir: bin
         | 
| 16 16 | 
             
            cert_chain: []
         | 
| 17 17 |  | 
| 18 | 
            -
            date: 2010- | 
| 18 | 
            +
            date: 2010-12-15 00:00:00 -08:00
         | 
| 19 19 | 
             
            default_executable: jekyll
         | 
| 20 20 | 
             
            dependencies: 
         | 
| 21 21 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -219,6 +219,8 @@ files: | |
| 219 219 | 
             
            - lib/jekyll/generators/pagination.rb
         | 
| 220 220 | 
             
            - lib/jekyll/layout.rb
         | 
| 221 221 | 
             
            - lib/jekyll/migrators/csv.rb
         | 
| 222 | 
            +
            - lib/jekyll/migrators/drupal.rb
         | 
| 223 | 
            +
            - lib/jekyll/migrators/marley.rb
         | 
| 222 224 | 
             
            - lib/jekyll/migrators/mephisto.rb
         | 
| 223 225 | 
             
            - lib/jekyll/migrators/mt.rb
         | 
| 224 226 | 
             
            - lib/jekyll/migrators/textpattern.rb
         |