jekyll 0.2.1 → 0.3.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 +14 -0
- data/Manifest.txt +5 -1
- data/README.textile +70 -5
- data/Rakefile +3 -0
- data/bin/jekyll +27 -1
- data/jekyll.gemspec +4 -4
- data/lib/jekyll.rb +3 -1
- data/lib/jekyll/converters/mt.rb +59 -0
- data/lib/jekyll/converters/wordpress.rb +54 -0
- data/lib/jekyll/convertible.rb +5 -7
- data/lib/jekyll/core_ext.rb +22 -0
- data/lib/jekyll/filters.rb +6 -3
- data/lib/jekyll/layout.rb +0 -15
- data/lib/jekyll/page.rb +3 -3
- data/lib/jekyll/post.rb +36 -19
- data/lib/jekyll/site.rb +52 -20
- data/lib/jekyll/tags/include.rb +12 -1
- data/test/source/{posts → _posts}/2008-12-03-permalinked-post.textile +0 -0
- data/test/source/index.html +11 -1
- data/test/test_generated_site.rb +21 -0
- data/test/test_post.rb +15 -11
- data/test/test_site.rb +4 -4
- metadata +8 -3
    
        data/History.txt
    CHANGED
    
    | @@ -1,3 +1,17 @@ | |
| 1 | 
            +
            == 0.3.0 / 2008-12-24
         | 
| 2 | 
            +
              * Major Enhancements
         | 
| 3 | 
            +
                * Added --server option to start a simple WEBrick server on destination directory [github.com/johnreilly and github.com/mchung]
         | 
| 4 | 
            +
              * Minor Enhancements
         | 
| 5 | 
            +
                * Added post categories based on directories containing _posts [github.com/mreid]
         | 
| 6 | 
            +
                * Added post topics based on directories underneath _posts
         | 
| 7 | 
            +
                * Added new date filter that shows the full month name [github.com/mreid]
         | 
| 8 | 
            +
                * Merge Post's YAML front matter into its to_liquid payload [github.com/remi]
         | 
| 9 | 
            +
                * Restrict includes to regular files underneath _includes
         | 
| 10 | 
            +
              * Bug Fixes
         | 
| 11 | 
            +
                * Change YAML delimiter matcher so as to not chew up 2nd level markdown headers [github.com/mreid]
         | 
| 12 | 
            +
                * Fix bug that meant page data (such as the date) was not available in templates [github.com/mreid]
         | 
| 13 | 
            +
                * Properly reject directories in _layouts
         | 
| 14 | 
            +
             | 
| 1 15 | 
             
            == 0.2.1 / 2008-12-15
         | 
| 2 16 | 
             
              * Major Changes
         | 
| 3 17 | 
             
                * Use Maruku (pure Ruby) for Markdown by default [github.com/mreid]
         | 
    
        data/Manifest.txt
    CHANGED
    
    | @@ -8,7 +8,10 @@ lib/jekyll.rb | |
| 8 8 | 
             
            lib/jekyll/albino.rb
         | 
| 9 9 | 
             
            lib/jekyll/converters/csv.rb
         | 
| 10 10 | 
             
            lib/jekyll/converters/mephisto.rb
         | 
| 11 | 
            +
            lib/jekyll/converters/mt.rb
         | 
| 12 | 
            +
            lib/jekyll/converters/wordpress.rb
         | 
| 11 13 | 
             
            lib/jekyll/convertible.rb
         | 
| 14 | 
            +
            lib/jekyll/core_ext.rb
         | 
| 12 15 | 
             
            lib/jekyll/filters.rb
         | 
| 13 16 | 
             
            lib/jekyll/layout.rb
         | 
| 14 17 | 
             
            lib/jekyll/page.rb
         | 
| @@ -22,11 +25,12 @@ test/source/_layouts/default.html | |
| 22 25 | 
             
            test/source/_layouts/simple.html
         | 
| 23 26 | 
             
            test/source/_posts/2008-10-18-foo-bar.textile
         | 
| 24 27 | 
             
            test/source/_posts/2008-11-21-complex.textile
         | 
| 28 | 
            +
            test/source/_posts/2008-12-03-permalinked-post.textile
         | 
| 25 29 | 
             
            test/source/_posts/2008-12-13-include.markdown
         | 
| 26 30 | 
             
            test/source/css/screen.css
         | 
| 27 31 | 
             
            test/source/index.html
         | 
| 28 | 
            -
            test/source/posts/2008-12-03-permalinked-post.textile
         | 
| 29 32 | 
             
            test/suite.rb
         | 
| 33 | 
            +
            test/test_generated_site.rb
         | 
| 30 34 | 
             
            test/test_jekyll.rb
         | 
| 31 35 | 
             
            test/test_post.rb
         | 
| 32 36 | 
             
            test/test_site.rb
         | 
    
        data/README.textile
    CHANGED
    
    | @@ -31,9 +31,10 @@ various data about my site. A reverse chronological list of all my blog posts | |
| 31 31 | 
             
            can be found in <code>site.posts</code>. Each post, in turn, contains various
         | 
| 32 32 | 
             
            fields such as <code>title</code> and <code>date</code>.
         | 
| 33 33 |  | 
| 34 | 
            -
            Jekyll gets the list of blog posts by parsing the files in  | 
| 35 | 
            -
            "_posts":http://github.com/mojombo/tpw/tree/master/_posts directory | 
| 36 | 
            -
             | 
| 34 | 
            +
            Jekyll gets the list of blog posts by parsing the files in any
         | 
| 35 | 
            +
            "_posts":http://github.com/mojombo/tpw/tree/master/_posts directory found in
         | 
| 36 | 
            +
            subdirectories below the root. 
         | 
| 37 | 
            +
            Each post's filename contains the publishing date and slug (what shows up in the
         | 
| 37 38 | 
             
            URL) that the final HTML file should have. Open up the file corresponding to a
         | 
| 38 39 | 
             
            blog post:
         | 
| 39 40 | 
             
            "2008-11-17-blogging-like-a-hacker.textile":http://github.com/mojombo/tpw/tree/master/_posts/2008-11-17-blogging-like-a-hacker.textile.
         | 
| @@ -52,6 +53,12 @@ filename is used to construct the URL in the generated site. The example post, | |
| 52 53 | 
             
            for instance, ends up at
         | 
| 53 54 | 
             
            <code>http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html</code>.
         | 
| 54 55 |  | 
| 56 | 
            +
            Categories for posts are derived from the directory structure the posts were
         | 
| 57 | 
            +
            found within. A post that appears in the directory foo/bar/_posts is placed in
         | 
| 58 | 
            +
            the categories 'foo' and 'bar'. By selecting posts from particular categories
         | 
| 59 | 
            +
            in your Liquid templates, you will be able to host multiple blogs within a
         | 
| 60 | 
            +
            site.
         | 
| 61 | 
            +
             | 
| 55 62 | 
             
            Files that do not reside in directories prefixed with an underscore are
         | 
| 56 63 | 
             
            mirrored into a corresponding directory structure in the generated site. If a
         | 
| 57 64 | 
             
            file does not have a YAML preface, it is not run through the Liquid
         | 
| @@ -129,6 +136,14 @@ compilation), you must install it (gem install rdiscount) and then you can | |
| 129 136 | 
             
            have it used instead:
         | 
| 130 137 |  | 
| 131 138 | 
             
              $ jekyll --rdiscount
         | 
| 139 | 
            +
              
         | 
| 140 | 
            +
            When previewing complex sites locally, simply opening the site in a web 
         | 
| 141 | 
            +
            browser (using file://) can cause problems with links that are relative to
         | 
| 142 | 
            +
            the site root (e.g., "/stylesheets/style.css"). To get around this, Jekyll
         | 
| 143 | 
            +
            can launch a simple WEBrick server (works well in conjunction with --auto).
         | 
| 144 | 
            +
            Default port is 4000:
         | 
| 145 | 
            +
             | 
| 146 | 
            +
              $ jekyll --server [PORT]
         | 
| 132 147 |  | 
| 133 148 | 
             
            h2. Data
         | 
| 134 149 |  | 
| @@ -149,7 +164,7 @@ h3. Global | |
| 149 164 |  | 
| 150 165 | 
             
              content
         | 
| 151 166 | 
             
                In layout files, this contains the content of the subview(s). In Posts or
         | 
| 152 | 
            -
                 | 
| 167 | 
            +
                Pages, this is undefined.
         | 
| 153 168 |  | 
| 154 169 | 
             
            h3. Site
         | 
| 155 170 |  | 
| @@ -165,6 +180,9 @@ h3. Site | |
| 165 180 | 
             
                high quality but slow to compute results, run the jekyll command with the 
         | 
| 166 181 | 
             
                --lsi (latent semantic indexing) option.
         | 
| 167 182 |  | 
| 183 | 
            +
              site.categories.CATEGORY
         | 
| 184 | 
            +
                The list of all Posts in category CATEGORY.
         | 
| 185 | 
            +
             | 
| 168 186 | 
             
            h3. Post
         | 
| 169 187 |  | 
| 170 188 | 
             
              post.title
         | 
| @@ -181,6 +199,18 @@ h3. Post | |
| 181 199 | 
             
                An identifier unique to the Post (useful in RSS feeds).
         | 
| 182 200 | 
             
                e.g. /2008/12/14/my-post
         | 
| 183 201 |  | 
| 202 | 
            +
              post.categories
         | 
| 203 | 
            +
                The list of categories to which this post belongs. Categories are
         | 
| 204 | 
            +
                derived from the directory structure above the _posts directory. For
         | 
| 205 | 
            +
                example, a post at /work/code/_posts/2008-12-24-closures.textile
         | 
| 206 | 
            +
                would have this field set to ['work', 'code'].
         | 
| 207 | 
            +
             | 
| 208 | 
            +
              post.topics
         | 
| 209 | 
            +
                The list of topics for this Post. Topics are derived from the directory
         | 
| 210 | 
            +
                structure beneath the _posts directory. For example, a post at
         | 
| 211 | 
            +
                /_posts/music/metal/2008-12-24-metalocalypse.textile would have this field
         | 
| 212 | 
            +
                set to ['music', 'metal'].
         | 
| 213 | 
            +
             | 
| 184 214 | 
             
              post.content
         | 
| 185 215 | 
             
                The content of the Post.
         | 
| 186 216 |  | 
| @@ -258,7 +288,8 @@ becomes | |
| 258 288 |  | 
| 259 289 | 
             
            h3. Include (Tag)
         | 
| 260 290 |  | 
| 261 | 
            -
            If you have small page fragments that you wish to include in multiple places | 
| 291 | 
            +
            If you have small page fragments that you wish to include in multiple places
         | 
| 292 | 
            +
            on your site, you can use the <code>include</code> tag.
         | 
| 262 293 |  | 
| 263 294 | 
             
            <pre>{% include sig.textile %}</pre>
         | 
| 264 295 |  | 
| @@ -296,6 +327,22 @@ highlighting stylesheet. For an example stylesheet you can look at | |
| 296 327 | 
             
            are the same styles as used by GitHub and you are free to use them for your
         | 
| 297 328 | 
             
            own site.
         | 
| 298 329 |  | 
| 330 | 
            +
            h2. Categories
         | 
| 331 | 
            +
             | 
| 332 | 
            +
            Posts are placed into categories based on the directory structure they are found
         | 
| 333 | 
            +
            within (see above for an example). The categories can be accessed from within
         | 
| 334 | 
            +
            a Liquid template as follows:
         | 
| 335 | 
            +
             | 
| 336 | 
            +
            <pre>
         | 
| 337 | 
            +
            {% for post in site.categories.foo %}
         | 
| 338 | 
            +
            	<li><span>{{ post.date | date_to_string }}</span> - {{ post.title }}</li>
         | 
| 339 | 
            +
            {% endfor %}
         | 
| 340 | 
            +
            </pre>
         | 
| 341 | 
            +
             | 
| 342 | 
            +
            This would list all the posts in the category 'foo' by date and title.
         | 
| 343 | 
            +
             | 
| 344 | 
            +
            The posts within each category are sorted in reverse chronological order.
         | 
| 345 | 
            +
             | 
| 299 346 | 
             
            h2. Contribute
         | 
| 300 347 |  | 
| 301 348 | 
             
            If you'd like to hack on Jekyll, grab the source from GitHub. To get
         | 
| @@ -314,6 +361,24 @@ The best way to get your changes merged back into core is as follows: | |
| 314 361 | 
             
            # Push the branch up to GitHub
         | 
| 315 362 | 
             
            # Send me (mojombo) a pull request for your branch
         | 
| 316 363 |  | 
| 364 | 
            +
            h2. Blog migrations
         | 
| 365 | 
            +
             | 
| 366 | 
            +
            h3. Movable Type
         | 
| 367 | 
            +
             | 
| 368 | 
            +
            To migrate your MT blog into Jekyll, you'll need read access to the database.
         | 
| 369 | 
            +
            The lib/jekyll/converters/mt.rb module provides a simple convert to create
         | 
| 370 | 
            +
            .markdown files in a _posts directory based on the entries contained therein.
         | 
| 371 | 
            +
             | 
| 372 | 
            +
              $ export DB=my_mtdb
         | 
| 373 | 
            +
              $ export USER=dbuser
         | 
| 374 | 
            +
              $ export PASS=dbpass
         | 
| 375 | 
            +
              $ ruby -r './lib/jekyll/converters/mt' -e 'Jekyll::MT.process( \
         | 
| 376 | 
            +
                "#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")'
         | 
| 377 | 
            +
             | 
| 378 | 
            +
            You may need to adjust the SQL query used to retrieve MT entries. Left alone,
         | 
| 379 | 
            +
            it will attempt to pull all entries across all blogs regardless of status.
         | 
| 380 | 
            +
            Please check the results and verify the posts before publishing.
         | 
| 381 | 
            +
             | 
| 317 382 | 
             
            h2. License
         | 
| 318 383 |  | 
| 319 384 | 
             
            (The MIT License)
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -18,4 +18,7 @@ namespace :convert do | |
| 18 18 | 
             
              task :mephisto do
         | 
| 19 19 | 
             
                sh %q(ruby -r './lib/jekyll/converters/mephisto' -e 'Jekyll::Mephisto.postgres(:database => "#{ENV["DB"]}")')
         | 
| 20 20 | 
             
              end
         | 
| 21 | 
            +
              task :mt do
         | 
| 22 | 
            +
                sh %q(ruby -r './lib/jekyll/converters/mt' -e 'Jekyll::MT.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")')
         | 
| 23 | 
            +
              end
         | 
| 21 24 | 
             
            end
         | 
    
        data/bin/jekyll
    CHANGED
    
    | @@ -25,6 +25,11 @@ opts = OptionParser.new do |opts| | |
| 25 25 | 
             
                options[:auto] = true
         | 
| 26 26 | 
             
              end
         | 
| 27 27 |  | 
| 28 | 
            +
              opts.on("--server [PORT]", "Start web server (default port 4000)") do |port|
         | 
| 29 | 
            +
                options[:server] = true
         | 
| 30 | 
            +
                options[:server_port] = port || 4000
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
              
         | 
| 28 33 | 
             
              opts.on("--lsi", "Use LSI for better related posts") do
         | 
| 29 34 | 
             
                Jekyll.lsi = true
         | 
| 30 35 | 
             
              end
         | 
| @@ -95,7 +100,28 @@ if options[:auto] | |
| 95 100 |  | 
| 96 101 | 
             
              dw.start
         | 
| 97 102 |  | 
| 98 | 
            -
               | 
| 103 | 
            +
              unless options[:server]
         | 
| 104 | 
            +
                loop { sleep 1000 }
         | 
| 105 | 
            +
              end
         | 
| 99 106 | 
             
            else
         | 
| 100 107 | 
             
              Jekyll.process(source, destination)
         | 
| 108 | 
            +
              puts "Successfully generated site in #{destination}"
         | 
| 109 | 
            +
            end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
            if options[:server]
         | 
| 112 | 
            +
              require 'webrick'
         | 
| 113 | 
            +
              include WEBrick
         | 
| 114 | 
            +
              
         | 
| 115 | 
            +
              FileUtils.mkdir_p(destination)
         | 
| 116 | 
            +
             | 
| 117 | 
            +
              s = HTTPServer.new(
         | 
| 118 | 
            +
                :Port            => options[:server_port],
         | 
| 119 | 
            +
                :DocumentRoot    => destination
         | 
| 120 | 
            +
              )
         | 
| 121 | 
            +
              t = Thread.new {
         | 
| 122 | 
            +
                s.start
         | 
| 123 | 
            +
              }
         | 
| 124 | 
            +
              
         | 
| 125 | 
            +
              trap("INT") { s.shutdown }
         | 
| 126 | 
            +
              t.join()
         | 
| 101 127 | 
             
            end
         | 
    
        data/jekyll.gemspec
    CHANGED
    
    | @@ -1,22 +1,22 @@ | |
| 1 1 | 
             
            Gem::Specification.new do |s|
         | 
| 2 2 | 
             
              s.name = %q{jekyll}
         | 
| 3 | 
            -
              s.version = "0. | 
| 3 | 
            +
              s.version = "0.3.0"
         | 
| 4 4 |  | 
| 5 5 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         | 
| 6 6 | 
             
              s.authors = ["Tom Preston-Werner"]
         | 
| 7 | 
            -
              s.date = %q{2008-12- | 
| 7 | 
            +
              s.date = %q{2008-12-24}
         | 
| 8 8 | 
             
              s.default_executable = %q{jekyll}
         | 
| 9 9 | 
             
              s.email = ["tom@mojombo.com"]
         | 
| 10 10 | 
             
              s.executables = ["jekyll"]
         | 
| 11 11 | 
             
              s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
         | 
| 12 | 
            -
              s.files = ["History.txt", "Manifest.txt", "README.textile", "Rakefile", "bin/jekyll", "jekyll.gemspec", "lib/jekyll.rb", "lib/jekyll/albino.rb", "lib/jekyll/converters/csv.rb", "lib/jekyll/converters/mephisto.rb", "lib/jekyll/convertible.rb", "lib/jekyll/filters.rb", "lib/jekyll/layout.rb", "lib/jekyll/page.rb", "lib/jekyll/post.rb", "lib/jekyll/site.rb", "lib/jekyll/tags/highlight.rb", "lib/jekyll/tags/include.rb", "test/helper.rb", "test/source/_includes/sig.markdown", "test/source/_layouts/default.html", "test/source/_layouts/simple.html", "test/source/_posts/2008-10-18-foo-bar.textile", "test/source/_posts/2008-11-21-complex.textile", "test/source/_posts/2008-12-13-include.markdown", "test/source/css/screen.css", "test/source/index.html", "test/ | 
| 12 | 
            +
              s.files = ["History.txt", "Manifest.txt", "README.textile", "Rakefile", "bin/jekyll", "jekyll.gemspec", "lib/jekyll.rb", "lib/jekyll/albino.rb", "lib/jekyll/converters/csv.rb", "lib/jekyll/converters/mephisto.rb", "lib/jekyll/converters/mt.rb", "lib/jekyll/converters/wordpress.rb", "lib/jekyll/convertible.rb", "lib/jekyll/core_ext.rb", "lib/jekyll/filters.rb", "lib/jekyll/layout.rb", "lib/jekyll/page.rb", "lib/jekyll/post.rb", "lib/jekyll/site.rb", "lib/jekyll/tags/highlight.rb", "lib/jekyll/tags/include.rb", "test/helper.rb", "test/source/_includes/sig.markdown", "test/source/_layouts/default.html", "test/source/_layouts/simple.html", "test/source/_posts/2008-10-18-foo-bar.textile", "test/source/_posts/2008-11-21-complex.textile", "test/source/_posts/2008-12-03-permalinked-post.textile", "test/source/_posts/2008-12-13-include.markdown", "test/source/css/screen.css", "test/source/index.html", "test/suite.rb", "test/test_generated_site.rb", "test/test_jekyll.rb", "test/test_post.rb", "test/test_site.rb"]
         | 
| 13 13 | 
             
              s.has_rdoc = true
         | 
| 14 14 | 
             
              s.rdoc_options = ["--main", "README.txt"]
         | 
| 15 15 | 
             
              s.require_paths = ["lib"]
         | 
| 16 16 | 
             
              s.rubyforge_project = %q{jekyll}
         | 
| 17 17 | 
             
              s.rubygems_version = %q{1.3.0}
         | 
| 18 18 | 
             
              s.summary = %q{Jekyll is a simple, blog aware, static site generator.}
         | 
| 19 | 
            -
              s.test_files = ["test/test_jekyll.rb", "test/test_post.rb", "test/test_site.rb"]
         | 
| 19 | 
            +
              s.test_files = ["test/test_generated_site.rb", "test/test_jekyll.rb", "test/test_post.rb", "test/test_site.rb"]
         | 
| 20 20 |  | 
| 21 21 | 
             
              if s.respond_to? :specification_version then
         | 
| 22 22 | 
             
                current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
         | 
    
        data/lib/jekyll.rb
    CHANGED
    
    | @@ -6,6 +6,7 @@ require 'rubygems' | |
| 6 6 | 
             
            # core
         | 
| 7 7 | 
             
            require 'fileutils'
         | 
| 8 8 | 
             
            require 'time'
         | 
| 9 | 
            +
            require 'yaml'
         | 
| 9 10 |  | 
| 10 11 | 
             
            # stdlib
         | 
| 11 12 |  | 
| @@ -30,6 +31,7 @@ rescue LoadError | |
| 30 31 | 
             
            end
         | 
| 31 32 |  | 
| 32 33 | 
             
            # internal requires
         | 
| 34 | 
            +
            require 'jekyll/core_ext'
         | 
| 33 35 | 
             
            require 'jekyll/site'
         | 
| 34 36 | 
             
            require 'jekyll/convertible'
         | 
| 35 37 | 
             
            require 'jekyll/layout'
         | 
| @@ -41,7 +43,7 @@ require 'jekyll/tags/include' | |
| 41 43 | 
             
            require 'jekyll/albino'
         | 
| 42 44 |  | 
| 43 45 | 
             
            module Jekyll
         | 
| 44 | 
            -
              VERSION = '0. | 
| 46 | 
            +
              VERSION = '0.3.0'
         | 
| 45 47 |  | 
| 46 48 | 
             
              class << self
         | 
| 47 49 | 
             
                attr_accessor :source, :dest, :lsi, :pygments, :markdown_proc
         | 
| @@ -0,0 +1,59 @@ | |
| 1 | 
            +
            # Created by Nick Gerakines, open source and publically available under the
         | 
| 2 | 
            +
            # MIT license. Use this module at your own risk.
         | 
| 3 | 
            +
            # I'm an Erlang/Perl/C++ guy so please forgive my dirty ruby.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require 'rubygems'
         | 
| 6 | 
            +
            require 'sequel'
         | 
| 7 | 
            +
            require 'fileutils'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # NOTE: This converter requires Sequel and the MySQL gems.
         | 
| 10 | 
            +
            # The MySQL gem can be difficult to install on OS X. Once you have MySQL
         | 
| 11 | 
            +
            # installed, running the following commands should work:
         | 
| 12 | 
            +
            # $ sudo gem install sequel
         | 
| 13 | 
            +
            # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
         | 
| 14 | 
            +
             
         | 
| 15 | 
            +
            module Jekyll
         | 
| 16 | 
            +
              module MT
         | 
| 17 | 
            +
                # This query will pull blog posts from all entries across all blogs. If
         | 
| 18 | 
            +
                # you've got unpublished, deleted or otherwise hidden posts please sift
         | 
| 19 | 
            +
                # through the created posts to make sure nothing is accidently published.
         | 
| 20 | 
            +
                QUERY = "SELECT entry_id, entry_basename, entry_text, entry_text_more, entry_created_on, entry_title FROM mt_entry"
         | 
| 21 | 
            +
             
         | 
| 22 | 
            +
                def self.process(dbname, user, pass, host = 'localhost')
         | 
| 23 | 
            +
                  db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host)
         | 
| 24 | 
            +
                  
         | 
| 25 | 
            +
                  FileUtils.mkdir_p "_posts"
         | 
| 26 | 
            +
                        
         | 
| 27 | 
            +
                  db[QUERY].each do |post|
         | 
| 28 | 
            +
                    title = post[:entry_title]
         | 
| 29 | 
            +
                    slug = post[:entry_basename]
         | 
| 30 | 
            +
                    date = post[:entry_created_on]
         | 
| 31 | 
            +
                    content = post[:entry_text]
         | 
| 32 | 
            +
                    more_content = post[:entry_text_more]
         | 
| 33 | 
            +
                    
         | 
| 34 | 
            +
                    # Be sure to include the body and extended body.
         | 
| 35 | 
            +
                    if more_content != nil
         | 
| 36 | 
            +
                      conent = content + " \n" + more_content
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                    
         | 
| 39 | 
            +
                    # Ideally, this script would determine the post format (markdown, html
         | 
| 40 | 
            +
                    # , etc) and create files with proper extensions. At this point it
         | 
| 41 | 
            +
                    # just assumes that markdown will be acceptable.
         | 
| 42 | 
            +
                    name = [date.year, date.month, date.day, slug].join('-') + ".markdown"
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    data = {
         | 
| 45 | 
            +
                       'layout' => 'post',
         | 
| 46 | 
            +
                       'title' => title.to_s,
         | 
| 47 | 
            +
                       'mt_id' => post[:entry_id],
         | 
| 48 | 
            +
                     }.delete_if { |k,v| v.nil? || v == ''}.to_yaml
         | 
| 49 | 
            +
             
         | 
| 50 | 
            +
                    File.open("_posts/#{name}", "w") do |f|
         | 
| 51 | 
            +
                      f.puts data
         | 
| 52 | 
            +
                      f.puts "---"
         | 
| 53 | 
            +
                      f.puts content
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
            end
         | 
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            require 'rubygems'
         | 
| 2 | 
            +
            require 'sequel'
         | 
| 3 | 
            +
            require 'fileutils'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # NOTE: This converter requires Sequel and the MySQL gems.
         | 
| 6 | 
            +
            # The MySQL gem can be difficult to install on OS X. Once you have MySQL
         | 
| 7 | 
            +
            # installed, running the following commands should work:
         | 
| 8 | 
            +
            # $ sudo gem install sequel
         | 
| 9 | 
            +
            # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            module Jekyll
         | 
| 12 | 
            +
              module WordPress
         | 
| 13 | 
            +
                
         | 
| 14 | 
            +
                # Reads a MySQL database via Sequel and creates a post file for each 
         | 
| 15 | 
            +
                # post in wp_posts that has post_status = 'publish'.
         | 
| 16 | 
            +
                # This restriction is made because 'draft' posts are not guaranteed to
         | 
| 17 | 
            +
                # have valid dates.
         | 
| 18 | 
            +
                QUERY = "select * from wp_posts where post_status = 'publish' and post_type = 'post'"
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def self.process(dbname, user, pass, host = 'localhost')
         | 
| 21 | 
            +
                  db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host)
         | 
| 22 | 
            +
                  
         | 
| 23 | 
            +
                  FileUtils.mkdir_p "_posts"
         | 
| 24 | 
            +
                        
         | 
| 25 | 
            +
                  db[QUERY].each do |post|
         | 
| 26 | 
            +
                    # Get required fields and construct Jekyll compatible name
         | 
| 27 | 
            +
                    title = post[:post_title]
         | 
| 28 | 
            +
                    slug = post[:post_name]
         | 
| 29 | 
            +
                    date = post[:post_date]
         | 
| 30 | 
            +
                    content = post[:post_content]
         | 
| 31 | 
            +
                    
         | 
| 32 | 
            +
                    name = [date.year, date.month, date.day, slug].join('-') + ".markdown"
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    # Get the relevant fields as a hash, delete empty fields and convert
         | 
| 35 | 
            +
                    # to YAML for the header        
         | 
| 36 | 
            +
                    data = {
         | 
| 37 | 
            +
                       'layout' => 'post',
         | 
| 38 | 
            +
                       'title' => title.to_s,
         | 
| 39 | 
            +
                       'excerpt' => post[:post_excerpt].to_s,
         | 
| 40 | 
            +
                       'wordpress_id' => post[:ID],
         | 
| 41 | 
            +
                       'wordpress_url' => post[:guid]
         | 
| 42 | 
            +
                     }.delete_if { |k,v| v.nil? || v == ''}.to_yaml
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    # Write out the data and content to file
         | 
| 45 | 
            +
                    File.open("_posts/#{name}", "w") do |f|
         | 
| 46 | 
            +
                      f.puts data
         | 
| 47 | 
            +
                      f.puts "---"
         | 
| 48 | 
            +
                      f.puts content
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         | 
    
        data/lib/jekyll/convertible.rb
    CHANGED
    
    | @@ -13,13 +13,13 @@ module Jekyll | |
| 13 13 | 
             
                def read_yaml(base, name)
         | 
| 14 14 | 
             
                  self.content = File.read(File.join(base, name))
         | 
| 15 15 |  | 
| 16 | 
            -
                  if self.content =~ /^( | 
| 16 | 
            +
                  if self.content =~ /^(---\s*\n.*?)\n---\s*\n/m
         | 
| 17 17 | 
             
                    self.content = self.content[($1.size + 5)..-1]
         | 
| 18 18 |  | 
| 19 19 | 
             
                    self.data = YAML.load($1)
         | 
| 20 20 | 
             
                  end
         | 
| 21 21 | 
             
                end
         | 
| 22 | 
            -
             | 
| 22 | 
            +
                
         | 
| 23 23 | 
             
                # Transform the contents based on the file extension.
         | 
| 24 24 | 
             
                #
         | 
| 25 25 | 
             
                # Returns nothing
         | 
| @@ -39,10 +39,8 @@ module Jekyll | |
| 39 39 | 
             
                #   +site_payload+ is the site payload hash
         | 
| 40 40 | 
             
                #
         | 
| 41 41 | 
             
                # Returns nothing
         | 
| 42 | 
            -
                def do_layout(payload, layouts | 
| 43 | 
            -
                  #  | 
| 44 | 
            -
                  payload = payload.merge(site_payload)
         | 
| 45 | 
            -
                  # render content
         | 
| 42 | 
            +
                def do_layout(payload, layouts)
         | 
| 43 | 
            +
                  # render and transform content (this becomes the final content of the object)
         | 
| 46 44 | 
             
                  self.content = Liquid::Template.parse(self.content).render(payload, [Jekyll::Filters])
         | 
| 47 45 | 
             
                  self.transform
         | 
| 48 46 |  | 
| @@ -52,7 +50,7 @@ module Jekyll | |
| 52 50 | 
             
                  # recursively render layouts
         | 
| 53 51 | 
             
                  layout = layouts[self.data["layout"]]
         | 
| 54 52 | 
             
                  while layout
         | 
| 55 | 
            -
                    payload = payload. | 
| 53 | 
            +
                    payload = payload.deep_merge({"content" => self.output, "page" => layout.data})
         | 
| 56 54 | 
             
                    self.output = Liquid::Template.parse(layout.content).render(payload, [Jekyll::Filters])
         | 
| 57 55 |  | 
| 58 56 | 
             
                    layout = layouts[layout.data["layout"]]
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            class Hash
         | 
| 2 | 
            +
              # Merges self with another hash, recursively.
         | 
| 3 | 
            +
              # 
         | 
| 4 | 
            +
              # This code was lovingly stolen from some random gem:
         | 
| 5 | 
            +
              # http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
         | 
| 6 | 
            +
              # 
         | 
| 7 | 
            +
              # Thanks to whoever made it.
         | 
| 8 | 
            +
              def deep_merge(hash)
         | 
| 9 | 
            +
                target = dup
         | 
| 10 | 
            +
                
         | 
| 11 | 
            +
                hash.keys.each do |key|
         | 
| 12 | 
            +
                  if hash[key].is_a? Hash and self[key].is_a? Hash
         | 
| 13 | 
            +
                    target[key] = target[key].deep_merge(hash[key])
         | 
| 14 | 
            +
                    next
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                  
         | 
| 17 | 
            +
                  target[key] = hash[key]
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
                
         | 
| 20 | 
            +
                target
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
    
        data/lib/jekyll/filters.rb
    CHANGED
    
    | @@ -4,6 +4,10 @@ module Jekyll | |
| 4 4 | 
             
                def date_to_string(date)
         | 
| 5 5 | 
             
                  date.strftime("%d %b %Y")
         | 
| 6 6 | 
             
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def date_to_long_string(date)
         | 
| 9 | 
            +
                  date.strftime("%d %B %Y")
         | 
| 10 | 
            +
                end
         | 
| 7 11 |  | 
| 8 12 | 
             
                def date_to_xmlschema(date)
         | 
| 9 13 | 
             
                  date.xmlschema
         | 
| @@ -15,7 +19,6 @@ module Jekyll | |
| 15 19 |  | 
| 16 20 | 
             
                def number_of_words(input)
         | 
| 17 21 | 
             
                  input.split.length
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
              
         | 
| 22 | 
            +
                end    
         | 
| 23 | 
            +
              end  
         | 
| 21 24 | 
             
            end
         | 
    
        data/lib/jekyll/layout.rb
    CHANGED
    
    | @@ -28,21 +28,6 @@ module Jekyll | |
| 28 28 | 
             
                def process(name)
         | 
| 29 29 | 
             
                  self.ext = File.extname(name)
         | 
| 30 30 | 
             
                end
         | 
| 31 | 
            -
                
         | 
| 32 | 
            -
                # Add any necessary layouts to this post
         | 
| 33 | 
            -
                #   +layouts+ is a Hash of {"name" => "layout"}
         | 
| 34 | 
            -
                #   +site_payload+ is the site payload hash
         | 
| 35 | 
            -
                #
         | 
| 36 | 
            -
                # Returns nothing
         | 
| 37 | 
            -
                def add_layout(layouts, site_payload)
         | 
| 38 | 
            -
                  payload = {"page" => self.data}.merge(site_payload)
         | 
| 39 | 
            -
                  self.content = Liquid::Template.parse(self.content).render(payload, [Jekyll::Filters])
         | 
| 40 | 
            -
                  
         | 
| 41 | 
            -
                  layout = layouts[self.data["layout"]] || self.content
         | 
| 42 | 
            -
                  payload = {"content" => self.content, "page" => self.data}
         | 
| 43 | 
            -
                  
         | 
| 44 | 
            -
                  self.content = Liquid::Template.parse(layout).render(payload, [Jekyll::Filters])
         | 
| 45 | 
            -
                end
         | 
| 46 31 | 
             
              end
         | 
| 47 32 |  | 
| 48 33 | 
             
            end
         | 
    
        data/lib/jekyll/page.rb
    CHANGED
    
    | @@ -37,9 +37,9 @@ module Jekyll | |
| 37 37 | 
             
                #   +site_payload+ is the site payload hash
         | 
| 38 38 | 
             
                #
         | 
| 39 39 | 
             
                # Returns nothing
         | 
| 40 | 
            -
                def  | 
| 41 | 
            -
                  payload = {"page" => self.data}
         | 
| 42 | 
            -
                  do_layout(payload, layouts | 
| 40 | 
            +
                def render(layouts, site_payload)
         | 
| 41 | 
            +
                  payload = {"page" => self.data}.deep_merge(site_payload)
         | 
| 42 | 
            +
                  do_layout(payload, layouts)
         | 
| 43 43 | 
             
                end
         | 
| 44 44 |  | 
| 45 45 | 
             
                # Write the generated page file to the destination directory.
         | 
    
        data/lib/jekyll/post.rb
    CHANGED
    
    | @@ -3,12 +3,12 @@ module Jekyll | |
| 3 3 | 
             
              class Post
         | 
| 4 4 | 
             
                include Comparable
         | 
| 5 5 | 
             
                include Convertible
         | 
| 6 | 
            -
             | 
| 6 | 
            +
                    
         | 
| 7 7 | 
             
                class << self
         | 
| 8 8 | 
             
                  attr_accessor :lsi
         | 
| 9 9 | 
             
                end
         | 
| 10 10 |  | 
| 11 | 
            -
                MATCHER = /^(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
         | 
| 11 | 
            +
                MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
         | 
| 12 12 |  | 
| 13 13 | 
             
                # Post name validator. Post filenames must be like:
         | 
| 14 14 | 
             
                #   2008-11-05-my-awesome-post.textile
         | 
| @@ -18,22 +18,26 @@ module Jekyll | |
| 18 18 | 
             
                  name =~ MATCHER
         | 
| 19 19 | 
             
                end
         | 
| 20 20 |  | 
| 21 | 
            -
                attr_accessor :date, :slug, :ext
         | 
| 21 | 
            +
                attr_accessor :date, :slug, :ext, :categories, :topics
         | 
| 22 22 | 
             
                attr_accessor :data, :content, :output
         | 
| 23 23 |  | 
| 24 24 | 
             
                # Initialize this Post instance.
         | 
| 25 25 | 
             
                #   +base+ is the String path to the dir containing the post file
         | 
| 26 26 | 
             
                #   +name+ is the String filename of the post file
         | 
| 27 | 
            +
                #   +categories+ is an Array of Strings for the categories for this post
         | 
| 27 28 | 
             
                #
         | 
| 28 29 | 
             
                # Returns <Post>
         | 
| 29 | 
            -
                def initialize( | 
| 30 | 
            -
                  @base =  | 
| 30 | 
            +
                def initialize(source, dir, name)
         | 
| 31 | 
            +
                  @base = File.join(source, dir, '_posts')
         | 
| 31 32 | 
             
                  @name = name
         | 
| 32 33 |  | 
| 34 | 
            +
                  self.categories = dir.split('/').reject { |x| x.empty? }
         | 
| 35 | 
            +
                  
         | 
| 36 | 
            +
                  parts = name.split('/')
         | 
| 37 | 
            +
                  self.topics = parts.size > 1 ? parts[0..-2] : []
         | 
| 38 | 
            +
                  
         | 
| 33 39 | 
             
                  self.process(name)
         | 
| 34 | 
            -
                  self.read_yaml(base, name)
         | 
| 35 | 
            -
                  #Removed to avoid munging of liquid tags, replaced in convertible.rb#48
         | 
| 36 | 
            -
                  #self.transform
         | 
| 40 | 
            +
                  self.read_yaml(@base, name)
         | 
| 37 41 | 
             
                end
         | 
| 38 42 |  | 
| 39 43 | 
             
                # Spaceship is based on Post#date
         | 
| @@ -48,7 +52,7 @@ module Jekyll | |
| 48 52 | 
             
                #
         | 
| 49 53 | 
             
                # Returns nothing
         | 
| 50 54 | 
             
                def process(name)
         | 
| 51 | 
            -
                  m, date, slug, ext = *name.match(MATCHER)
         | 
| 55 | 
            +
                  m, cats, date, slug, ext = *name.match(MATCHER)
         | 
| 52 56 | 
             
                  self.date = Time.parse(date)
         | 
| 53 57 | 
             
                  self.slug = slug
         | 
| 54 58 | 
             
                  self.ext = ext
         | 
| @@ -61,9 +65,12 @@ module Jekyll | |
| 61 65 | 
             
                #
         | 
| 62 66 | 
             
                # Returns <String>
         | 
| 63 67 | 
             
                def dir
         | 
| 64 | 
            -
                  permalink | 
| 65 | 
            -
                    permalink.to_s.split("/")[0..-2].join("/") | 
| 66 | 
            -
             | 
| 68 | 
            +
                  if permalink
         | 
| 69 | 
            +
                    permalink.to_s.split("/")[0..-2].join("/")
         | 
| 70 | 
            +
                  else
         | 
| 71 | 
            +
                    prefix = self.categories.empty? ? '' : '/' + self.categories.join('/')
         | 
| 72 | 
            +
                    prefix + date.strftime("/%Y/%m/%d/")
         | 
| 73 | 
            +
                  end
         | 
| 67 74 | 
             
                end
         | 
| 68 75 |  | 
| 69 76 | 
             
                # The full path and filename of the post.
         | 
| @@ -90,7 +97,7 @@ module Jekyll | |
| 90 97 | 
             
                def id
         | 
| 91 98 | 
             
                  self.dir + self.slug
         | 
| 92 99 | 
             
                end
         | 
| 93 | 
            -
             | 
| 100 | 
            +
                    
         | 
| 94 101 | 
             
                # Calculate related posts.
         | 
| 95 102 | 
             
                #
         | 
| 96 103 | 
             
                # Returns [<Post>]
         | 
| @@ -118,11 +125,16 @@ module Jekyll | |
| 118 125 | 
             
                #   +site_payload+ is the site payload hash
         | 
| 119 126 | 
             
                #
         | 
| 120 127 | 
             
                # Returns nothing
         | 
| 121 | 
            -
                def  | 
| 122 | 
            -
                  # construct  | 
| 123 | 
            -
                   | 
| 124 | 
            -
                   | 
| 125 | 
            -
             | 
| 128 | 
            +
                def render(layouts, site_payload)
         | 
| 129 | 
            +
                  # construct payload
         | 
| 130 | 
            +
                  payload =
         | 
| 131 | 
            +
                  {
         | 
| 132 | 
            +
                    "site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
         | 
| 133 | 
            +
                    "page" => self.to_liquid
         | 
| 134 | 
            +
                  }
         | 
| 135 | 
            +
                  payload = payload.deep_merge(site_payload)
         | 
| 136 | 
            +
                  
         | 
| 137 | 
            +
                  do_layout(payload, layouts)
         | 
| 126 138 | 
             
                end
         | 
| 127 139 |  | 
| 128 140 | 
             
                # Write the generated post file to the destination directory.
         | 
| @@ -146,7 +158,12 @@ module Jekyll | |
| 146 158 | 
             
                    "url" => self.url,
         | 
| 147 159 | 
             
                    "date" => self.date,
         | 
| 148 160 | 
             
                    "id" => self.id,
         | 
| 149 | 
            -
                    " | 
| 161 | 
            +
                    "topics" => self.topics,
         | 
| 162 | 
            +
                    "content" => self.content }.deep_merge(self.data)
         | 
| 163 | 
            +
                end
         | 
| 164 | 
            +
                
         | 
| 165 | 
            +
                def inspect
         | 
| 166 | 
            +
                  "<Post: #{self.id}>"
         | 
| 150 167 | 
             
                end
         | 
| 151 168 | 
             
              end
         | 
| 152 169 |  | 
    
        data/lib/jekyll/site.rb
    CHANGED
    
    | @@ -24,19 +24,19 @@ module Jekyll | |
| 24 24 | 
             
                # Returns nothing
         | 
| 25 25 | 
             
                def process
         | 
| 26 26 | 
             
                  self.read_layouts
         | 
| 27 | 
            -
                  self.read_posts
         | 
| 28 | 
            -
                  self.write_posts
         | 
| 29 27 | 
             
                  self.transform_pages
         | 
| 28 | 
            +
                  self.write_posts
         | 
| 30 29 | 
             
                end
         | 
| 31 30 |  | 
| 32 | 
            -
                # Read all the files in <source>/_layouts  | 
| 33 | 
            -
                # later use.
         | 
| 31 | 
            +
                # Read all the files in <source>/_layouts except backup files
         | 
| 32 | 
            +
                # (end with "~") into memory for later use.
         | 
| 34 33 | 
             
                #
         | 
| 35 34 | 
             
                # Returns nothing
         | 
| 36 35 | 
             
                def read_layouts
         | 
| 37 36 | 
             
                  base = File.join(self.source, "_layouts")
         | 
| 38 37 | 
             
                  entries = Dir.entries(base)
         | 
| 39 | 
            -
                  entries = entries.reject { |e|  | 
| 38 | 
            +
                  entries = entries.reject { |e| e[-1..-1] == '~' }
         | 
| 39 | 
            +
                  entries = entries.reject { |e| File.directory?(File.join(base, e)) }
         | 
| 40 40 |  | 
| 41 41 | 
             
                  entries.each do |f|
         | 
| 42 42 | 
             
                    name = f.split(".")[0..-2].join(".")
         | 
| @@ -46,17 +46,29 @@ module Jekyll | |
| 46 46 | 
             
                  # ignore missing layout dir
         | 
| 47 47 | 
             
                end
         | 
| 48 48 |  | 
| 49 | 
            -
                # Read all the files in < | 
| 50 | 
            -
                # object with each one.
         | 
| 49 | 
            +
                # Read all the files in <base>/_posts except backup files (end with "~")
         | 
| 50 | 
            +
                # and create a new Post object with each one.
         | 
| 51 51 | 
             
                #
         | 
| 52 52 | 
             
                # Returns nothing
         | 
| 53 | 
            -
                def read_posts
         | 
| 54 | 
            -
                  base = File.join(self.source,  | 
| 55 | 
            -
                   | 
| 56 | 
            -
                  entries =  | 
| 53 | 
            +
                def read_posts(dir)
         | 
| 54 | 
            +
                  base = File.join(self.source, dir, '_posts')
         | 
| 55 | 
            +
                  
         | 
| 56 | 
            +
                  entries = []
         | 
| 57 | 
            +
                  Dir.chdir(base) { entries = Dir['**/*'] }
         | 
| 58 | 
            +
                  entries = entries.reject { |e| e[-1..-1] == '~' }
         | 
| 59 | 
            +
                  entries = entries.reject { |e| File.directory?(File.join(base, e)) }
         | 
| 57 60 |  | 
| 61 | 
            +
                  # first pass processes, but does not yet render post content
         | 
| 58 62 | 
             
                  entries.each do |f|
         | 
| 59 | 
            -
                     | 
| 63 | 
            +
                    if Post.valid?(f)
         | 
| 64 | 
            +
                      post = Post.new(self.source, dir, f)
         | 
| 65 | 
            +
                      self.posts << post
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                  
         | 
| 69 | 
            +
                  # second pass renders each post now that full site payload is available
         | 
| 70 | 
            +
                  self.posts.each do |post|
         | 
| 71 | 
            +
                    post.render(self.layouts, site_payload)
         | 
| 60 72 | 
             
                  end
         | 
| 61 73 |  | 
| 62 74 | 
             
                  self.posts.sort!
         | 
| @@ -69,14 +81,14 @@ module Jekyll | |
| 69 81 | 
             
                # Returns nothing
         | 
| 70 82 | 
             
                def write_posts
         | 
| 71 83 | 
             
                  self.posts.each do |post|
         | 
| 72 | 
            -
                    post.add_layout(self.layouts, site_payload)
         | 
| 73 84 | 
             
                    post.write(self.dest)
         | 
| 74 85 | 
             
                  end
         | 
| 75 86 | 
             
                end
         | 
| 76 87 |  | 
| 77 88 | 
             
                # Copy all regular files from <source> to <dest>/ ignoring
         | 
| 78 | 
            -
                # any files/directories that are hidden  | 
| 79 | 
            -
                # site content (start with "_")
         | 
| 89 | 
            +
                # any files/directories that are hidden or backup files (start
         | 
| 90 | 
            +
                # with "." or end with "~") or contain site content (start with "_")
         | 
| 91 | 
            +
                # unless they are "_posts" directories
         | 
| 80 92 | 
             
                #   The +dir+ String is a relative path used to call this method
         | 
| 81 93 | 
             
                #            recursively as it descends through directories
         | 
| 82 94 | 
             
                #
         | 
| @@ -84,7 +96,17 @@ module Jekyll | |
| 84 96 | 
             
                def transform_pages(dir = '')
         | 
| 85 97 | 
             
                  base = File.join(self.source, dir)
         | 
| 86 98 | 
             
                  entries = Dir.entries(base)
         | 
| 87 | 
            -
                  entries = entries.reject { |e| [ | 
| 99 | 
            +
                  entries = entries.reject { |e| e[-1..-1] == '~' }
         | 
| 100 | 
            +
                  entries = entries.reject do |e|
         | 
| 101 | 
            +
                    (e != '_posts') and ['.', '_'].include?(e[0..0])
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  # we need to make sure to process _posts *first* otherwise they 
         | 
| 105 | 
            +
                  # might not be available yet to other templates as {{ site.posts }}
         | 
| 106 | 
            +
                  if entries.include?('_posts')
         | 
| 107 | 
            +
                    entries.delete('_posts')
         | 
| 108 | 
            +
                    read_posts(dir)
         | 
| 109 | 
            +
                  end
         | 
| 88 110 |  | 
| 89 111 | 
             
                  entries.each do |f|
         | 
| 90 112 | 
             
                    if File.directory?(File.join(base, f))
         | 
| @@ -93,13 +115,13 @@ module Jekyll | |
| 93 115 | 
             
                    else
         | 
| 94 116 | 
             
                      first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
         | 
| 95 117 |  | 
| 96 | 
            -
                      # if the file appears to have a YAML header then process it as a page
         | 
| 97 118 | 
             
                      if first3 == "---"
         | 
| 119 | 
            +
                        # file appears to have a YAML header so process it as a page
         | 
| 98 120 | 
             
                        page = Page.new(self.source, dir, f)
         | 
| 99 | 
            -
                        page. | 
| 121 | 
            +
                        page.render(self.layouts, site_payload)
         | 
| 100 122 | 
             
                        page.write(self.dest)
         | 
| 101 | 
            -
                      # otherwise copy the file without transforming it
         | 
| 102 123 | 
             
                      else
         | 
| 124 | 
            +
                        # otherwise copy the file without transforming it
         | 
| 103 125 | 
             
                        FileUtils.mkdir_p(File.join(self.dest, dir))
         | 
| 104 126 | 
             
                        FileUtils.cp(File.join(self.source, dir, f), File.join(self.dest, dir, f))
         | 
| 105 127 | 
             
                      end
         | 
| @@ -111,7 +133,17 @@ module Jekyll | |
| 111 133 | 
             
                #
         | 
| 112 134 | 
             
                # Returns {"site" => {"time" => <Time>, "posts" => [<Post>]}}
         | 
| 113 135 | 
             
                def site_payload
         | 
| 114 | 
            -
                   | 
| 136 | 
            +
                  # Build the category hash map of category ( names => arrays of posts )
         | 
| 137 | 
            +
                  # then sort each array in reverse order
         | 
| 138 | 
            +
                  categories = Hash.new { |hash, key| hash[key] = Array.new }
         | 
| 139 | 
            +
                  self.posts.each { |p| p.categories.each { |c| categories[c] << p } }
         | 
| 140 | 
            +
                  categories.values.map { |cats| cats.sort! { |a, b| b <=> a} }
         | 
| 141 | 
            +
                  
         | 
| 142 | 
            +
                  {"site" => {
         | 
| 143 | 
            +
                    "time" => Time.now, 
         | 
| 144 | 
            +
                    "posts" => self.posts.sort { |a,b| b <=> a },
         | 
| 145 | 
            +
                    "categories" => categories
         | 
| 146 | 
            +
                  }}
         | 
| 115 147 | 
             
                end
         | 
| 116 148 | 
             
              end
         | 
| 117 149 |  | 
    
        data/lib/jekyll/tags/include.rb
    CHANGED
    
    | @@ -7,7 +7,18 @@ module Jekyll | |
| 7 7 | 
             
                end
         | 
| 8 8 |  | 
| 9 9 | 
             
                def render(context)
         | 
| 10 | 
            -
                   | 
| 10 | 
            +
                  if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
         | 
| 11 | 
            +
                    return "Include file '#{@file}' contains invalid characters or sequences"
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                  
         | 
| 14 | 
            +
                  Dir.chdir(File.join(Jekyll.source, '_includes')) do
         | 
| 15 | 
            +
                    choices = Dir['**/*'].reject { |x| File.symlink?(x) }
         | 
| 16 | 
            +
                    if choices.include?(@file)
         | 
| 17 | 
            +
                      File.read(@file)
         | 
| 18 | 
            +
                    else
         | 
| 19 | 
            +
                      "Included file '#{@file}' not found in _includes directory"
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 11 22 | 
             
                end
         | 
| 12 23 | 
             
              end
         | 
| 13 24 |  | 
| 
            File without changes
         | 
    
        data/test/source/index.html
    CHANGED
    
    | @@ -5,8 +5,18 @@ title: Tom Preston-Werner | |
| 5 5 |  | 
| 6 6 | 
             
            h1. Welcome to my site
         | 
| 7 7 |  | 
| 8 | 
            +
            h2. Please read our {{ site.posts | size }} Posts
         | 
| 9 | 
            +
             | 
| 8 10 | 
             
            <ul>
         | 
| 9 11 | 
             
              {% for post in site.posts %}
         | 
| 10 12 | 
             
                <li>{{ post.date }} <a href="{{ post.url }}">{{ post.title }}</a></li>
         | 
| 11 13 | 
             
              {% endfor %}
         | 
| 12 | 
            -
            </ul>
         | 
| 14 | 
            +
            </ul>
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            {% assign first_post = site.posts.first %}
         | 
| 17 | 
            +
            <div id="first_post">
         | 
| 18 | 
            +
              <h1>{{ first_post.title }}</h1>
         | 
| 19 | 
            +
              <div>
         | 
| 20 | 
            +
                {{ first_post.content }}
         | 
| 21 | 
            +
              </div>
         | 
| 22 | 
            +
            </div>
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            require File.dirname(__FILE__) + '/helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestGeneratedSite < Test::Unit::TestCase
         | 
| 4 | 
            +
              def setup
         | 
| 5 | 
            +
                clear_dest
         | 
| 6 | 
            +
                source = File.join(File.dirname(__FILE__), *%w[source])
         | 
| 7 | 
            +
                @s = Site.new(source, dest_dir)
         | 
| 8 | 
            +
                @s.process
         | 
| 9 | 
            +
                @index = File.read(File.join(dest_dir, 'index.html'))
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              def test_site_posts_in_index
         | 
| 13 | 
            +
                # confirm that {{ site.posts }} is working
         | 
| 14 | 
            +
                assert @index.include?("#{@s.posts.size} Posts")
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def test_post_content_in_index
         | 
| 18 | 
            +
                # confirm that the {{ post.content }} is rendered OK
         | 
| 19 | 
            +
                assert @index.include?('<p>This <em>is</em> cool</p>')
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
    
        data/test/test_post.rb
    CHANGED
    
    | @@ -7,6 +7,9 @@ class TestPost < Test::Unit::TestCase | |
| 7 7 |  | 
| 8 8 | 
             
              def test_valid
         | 
| 9 9 | 
             
                assert Post.valid?("2008-10-19-foo-bar.textile")
         | 
| 10 | 
            +
                assert Post.valid?("foo/bar/2008-10-19-foo-bar.textile")
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
                assert !Post.valid?("lol2008-10-19-foo-bar.textile")
         | 
| 10 13 | 
             
                assert !Post.valid?("blah")
         | 
| 11 14 | 
             
              end
         | 
| 12 15 |  | 
| @@ -21,6 +24,7 @@ class TestPost < Test::Unit::TestCase | |
| 21 24 |  | 
| 22 25 | 
             
              def test_url
         | 
| 23 26 | 
             
                p = Post.allocate
         | 
| 27 | 
            +
                p.categories = []
         | 
| 24 28 | 
             
                p.process("2008-10-19-foo-bar.textile")
         | 
| 25 29 |  | 
| 26 30 | 
             
                assert_equal "/2008/10/19/foo-bar.html", p.url
         | 
| @@ -29,7 +33,7 @@ class TestPost < Test::Unit::TestCase | |
| 29 33 | 
             
              def test_permalink
         | 
| 30 34 | 
             
                p = Post.allocate
         | 
| 31 35 | 
             
                p.process("2008-12-03-permalinked-post.textile")
         | 
| 32 | 
            -
                p.read_yaml(File.join(File.dirname(__FILE__), *%w[source  | 
| 36 | 
            +
                p.read_yaml(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-12-03-permalinked-post.textile")
         | 
| 33 37 |  | 
| 34 38 | 
             
                assert_equal "my_category/permalinked-post", p.permalink
         | 
| 35 39 | 
             
              end
         | 
| @@ -37,7 +41,7 @@ class TestPost < Test::Unit::TestCase | |
| 37 41 | 
             
              def test_dir_respects_permalink
         | 
| 38 42 | 
             
                p = Post.allocate
         | 
| 39 43 | 
             
                p.process("2008-12-03-permalinked-post.textile")
         | 
| 40 | 
            -
                p.read_yaml(File.join(File.dirname(__FILE__), *%w[source  | 
| 44 | 
            +
                p.read_yaml(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-12-03-permalinked-post.textile")
         | 
| 41 45 |  | 
| 42 46 | 
             
                assert_equal "my_category", p.dir
         | 
| 43 47 | 
             
              end
         | 
| @@ -59,10 +63,10 @@ class TestPost < Test::Unit::TestCase | |
| 59 63 | 
             
                assert_equal "<h1>{{ page.title }}</h1>\n<p>Best <strong>post</strong> ever</p>", p.content
         | 
| 60 64 | 
             
              end
         | 
| 61 65 |  | 
| 62 | 
            -
              def  | 
| 63 | 
            -
                p = Post.new(File.join(File.dirname(__FILE__), *%w[source | 
| 66 | 
            +
              def test_render
         | 
| 67 | 
            +
                p = Post.new(File.join(File.dirname(__FILE__), *%w[source]), '',  "2008-10-18-foo-bar.textile")
         | 
| 64 68 | 
             
                layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
         | 
| 65 | 
            -
                p. | 
| 69 | 
            +
                p.render(layouts, {"site" => {"posts" => []}})
         | 
| 66 70 |  | 
| 67 71 | 
             
                assert_equal "<<< <h1>Foo Bar</h1>\n<p>Best <strong>post</strong> ever</p> >>>", p.output
         | 
| 68 72 | 
             
              end
         | 
| @@ -70,25 +74,25 @@ class TestPost < Test::Unit::TestCase | |
| 70 74 | 
             
              def test_write
         | 
| 71 75 | 
             
                clear_dest
         | 
| 72 76 |  | 
| 73 | 
            -
                p = Post.new(File.join(File.dirname(__FILE__), *%w[source | 
| 77 | 
            +
                p = Post.new(File.join(File.dirname(__FILE__), *%w[source]), '', "2008-10-18-foo-bar.textile")
         | 
| 74 78 | 
             
                layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
         | 
| 75 | 
            -
                p. | 
| 79 | 
            +
                p.render(layouts, {"site" => {"posts" => []}})
         | 
| 76 80 | 
             
                p.write(dest_dir)
         | 
| 77 81 | 
             
              end
         | 
| 78 82 |  | 
| 79 83 | 
             
              def test_data
         | 
| 80 | 
            -
                p = Post.new(File.join(File.dirname(__FILE__), *%w[source | 
| 84 | 
            +
                p = Post.new(File.join(File.dirname(__FILE__), *%w[source]), '', "2008-11-21-complex.textile")
         | 
| 81 85 | 
             
                layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
         | 
| 82 | 
            -
                p. | 
| 86 | 
            +
                p.render(layouts, {"site" => {"posts" => []}})
         | 
| 83 87 |  | 
| 84 88 | 
             
                assert_equal "<<< <p>url: /2008/11/21/complex.html<br />\ndate: #{Time.parse("2008-11-21")}<br />\nid: /2008/11/21/complex</p> >>>", p.output
         | 
| 85 89 | 
             
              end
         | 
| 86 90 |  | 
| 87 91 | 
             
              def test_include
         | 
| 88 92 | 
             
                Jekyll.source = File.join(File.dirname(__FILE__), *%w[source])
         | 
| 89 | 
            -
                p = Post.new(File.join(File.dirname(__FILE__), *%w[source | 
| 93 | 
            +
                p = Post.new(File.join(File.dirname(__FILE__), *%w[source]), '', "2008-12-13-include.markdown")
         | 
| 90 94 | 
             
                layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
         | 
| 91 | 
            -
                p. | 
| 95 | 
            +
                p.render(layouts, {"site" => {"posts" => []}})
         | 
| 92 96 |  | 
| 93 97 | 
             
                assert_equal "<<< <hr />\n<p>Tom Preston-Werner github.com/mojombo</p>\n\n<p>This <em>is</em> cool</p> >>>", p.output
         | 
| 94 98 | 
             
              end
         | 
    
        data/test/test_site.rb
    CHANGED
    
    | @@ -15,11 +15,11 @@ class TestSite < Test::Unit::TestCase | |
| 15 15 |  | 
| 16 16 | 
             
                assert_equal ["default", "simple"].sort, @s.layouts.keys.sort
         | 
| 17 17 | 
             
              end
         | 
| 18 | 
            -
             | 
| 18 | 
            +
             
         | 
| 19 19 | 
             
              def test_read_posts
         | 
| 20 | 
            -
                @s.read_posts
         | 
| 20 | 
            +
                @s.read_posts('')
         | 
| 21 21 |  | 
| 22 | 
            -
                assert_equal  | 
| 22 | 
            +
                assert_equal 4, @s.posts.size
         | 
| 23 23 | 
             
              end
         | 
| 24 24 |  | 
| 25 25 | 
             
              def test_write_posts
         | 
| @@ -27,4 +27,4 @@ class TestSite < Test::Unit::TestCase | |
| 27 27 |  | 
| 28 28 | 
             
                @s.process
         | 
| 29 29 | 
             
              end
         | 
| 30 | 
            -
            end
         | 
| 30 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: jekyll
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors: 
         | 
| 7 7 | 
             
            - Tom Preston-Werner
         | 
| @@ -9,7 +9,7 @@ autorequire: | |
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 11 |  | 
| 12 | 
            -
            date: 2008-12- | 
| 12 | 
            +
            date: 2008-12-24 00:00:00 -08:00
         | 
| 13 13 | 
             
            default_executable: 
         | 
| 14 14 | 
             
            dependencies: 
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -103,7 +103,10 @@ files: | |
| 103 103 | 
             
            - lib/jekyll/albino.rb
         | 
| 104 104 | 
             
            - lib/jekyll/converters/csv.rb
         | 
| 105 105 | 
             
            - lib/jekyll/converters/mephisto.rb
         | 
| 106 | 
            +
            - lib/jekyll/converters/mt.rb
         | 
| 107 | 
            +
            - lib/jekyll/converters/wordpress.rb
         | 
| 106 108 | 
             
            - lib/jekyll/convertible.rb
         | 
| 109 | 
            +
            - lib/jekyll/core_ext.rb
         | 
| 107 110 | 
             
            - lib/jekyll/filters.rb
         | 
| 108 111 | 
             
            - lib/jekyll/layout.rb
         | 
| 109 112 | 
             
            - lib/jekyll/page.rb
         | 
| @@ -117,11 +120,12 @@ files: | |
| 117 120 | 
             
            - test/source/_layouts/simple.html
         | 
| 118 121 | 
             
            - test/source/_posts/2008-10-18-foo-bar.textile
         | 
| 119 122 | 
             
            - test/source/_posts/2008-11-21-complex.textile
         | 
| 123 | 
            +
            - test/source/_posts/2008-12-03-permalinked-post.textile
         | 
| 120 124 | 
             
            - test/source/_posts/2008-12-13-include.markdown
         | 
| 121 125 | 
             
            - test/source/css/screen.css
         | 
| 122 126 | 
             
            - test/source/index.html
         | 
| 123 | 
            -
            - test/source/posts/2008-12-03-permalinked-post.textile
         | 
| 124 127 | 
             
            - test/suite.rb
         | 
| 128 | 
            +
            - test/test_generated_site.rb
         | 
| 125 129 | 
             
            - test/test_jekyll.rb
         | 
| 126 130 | 
             
            - test/test_post.rb
         | 
| 127 131 | 
             
            - test/test_site.rb
         | 
| @@ -153,6 +157,7 @@ signing_key: | |
| 153 157 | 
             
            specification_version: 2
         | 
| 154 158 | 
             
            summary: Jekyll is a simple, blog aware, static site generator.
         | 
| 155 159 | 
             
            test_files: 
         | 
| 160 | 
            +
            - test/test_generated_site.rb
         | 
| 156 161 | 
             
            - test/test_jekyll.rb
         | 
| 157 162 | 
             
            - test/test_post.rb
         | 
| 158 163 | 
             
            - test/test_site.rb
         |