jekyll-0.11.2/0000775000175000017500000000000011752165402012726 5ustar uwabamiuwabamijekyll-0.11.2/metadata.yml0000664000175000017500000002343511752165402015240 0ustar uwabamiuwabami--- !ruby/object:Gem::Specification name: jekyll version: !ruby/object:Gem::Version hash: 55 prerelease: segments: - 0 - 11 - 2 version: 0.11.2 platform: ruby authors: - Tom Preston-Werner autorequire: bindir: bin cert_chain: [] date: 2011-12-27 00:00:00 -07:00 default_executable: dependencies: - !ruby/object:Gem::Dependency prerelease: false requirement: &id001 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 5 segments: - 2 - 3 version: "2.3" type: :runtime name: liquid version_requirements: *id001 - !ruby/object:Gem::Dependency prerelease: false requirement: &id002 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 9 segments: - 1 - 3 version: "1.3" type: :runtime name: classifier version_requirements: *id002 - !ruby/object:Gem::Dependency prerelease: false requirement: &id003 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 13 segments: - 1 - 1 version: "1.1" type: :runtime name: directory_watcher version_requirements: *id003 - !ruby/object:Gem::Dependency prerelease: false requirement: &id004 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 1 segments: - 0 - 5 version: "0.5" type: :runtime name: maruku version_requirements: *id004 - !ruby/object:Gem::Dependency prerelease: false requirement: &id005 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 17 segments: - 0 - 13 version: "0.13" type: :runtime name: kramdown version_requirements: *id005 - !ruby/object:Gem::Dependency prerelease: false requirement: &id006 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 9 segments: - 1 - 3 version: "1.3" type: :runtime name: albino version_requirements: *id006 - !ruby/object:Gem::Dependency prerelease: false requirement: &id007 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 25 segments: - 0 - 9 version: "0.9" type: :development name: rake version_requirements: *id007 - !ruby/object:Gem::Dependency prerelease: false requirement: &id008 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 17 segments: - 3 - 11 version: "3.11" type: :development name: rdoc version_requirements: *id008 - !ruby/object:Gem::Dependency prerelease: false requirement: &id009 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 11 segments: - 1 - 2 version: "1.2" type: :development name: redgreen version_requirements: *id009 - !ruby/object:Gem::Dependency prerelease: false requirement: &id010 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 21 segments: - 2 - 11 version: "2.11" type: :development name: shoulda version_requirements: *id010 - !ruby/object:Gem::Dependency prerelease: false requirement: &id011 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 15 segments: - 1 - 0 version: "1.0" type: :development name: rr version_requirements: *id011 - !ruby/object:Gem::Dependency prerelease: false requirement: &id012 !ruby/object:Gem::Requirement none: false requirements: - - "=" - !ruby/object:Gem::Version hash: 13 segments: - 1 - 1 version: "1.1" type: :development name: cucumber version_requirements: *id012 - !ruby/object:Gem::Dependency prerelease: false requirement: &id013 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 31 segments: - 4 - 2 version: "4.2" type: :development name: RedCloth version_requirements: *id013 - !ruby/object:Gem::Dependency prerelease: false requirement: &id014 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 3 segments: - 1 - 6 version: "1.6" type: :development name: rdiscount version_requirements: *id014 - !ruby/object:Gem::Dependency prerelease: false requirement: &id015 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 29 segments: - 1 - 9 version: "1.9" type: :development name: redcarpet version_requirements: *id015 description: Jekyll is a simple, blog aware, static site generator. email: tom@mojombo.com executables: - jekyll extensions: [] extra_rdoc_files: - README.textile - LICENSE files: - Gemfile - History.txt - LICENSE - README.textile - Rakefile - bin/jekyll - cucumber.yml - features/create_sites.feature - features/embed_filters.feature - features/markdown.feature - features/pagination.feature - features/permalinks.feature - features/post_data.feature - features/site_configuration.feature - features/site_data.feature - features/step_definitions/jekyll_steps.rb - features/support/env.rb - jekyll.gemspec - lib/jekyll.rb - lib/jekyll/converter.rb - lib/jekyll/converters/identity.rb - lib/jekyll/converters/markdown.rb - lib/jekyll/converters/textile.rb - lib/jekyll/convertible.rb - lib/jekyll/core_ext.rb - lib/jekyll/errors.rb - lib/jekyll/filters.rb - lib/jekyll/generator.rb - lib/jekyll/generators/pagination.rb - lib/jekyll/layout.rb - lib/jekyll/migrators/csv.rb - lib/jekyll/migrators/drupal.rb - lib/jekyll/migrators/enki.rb - lib/jekyll/migrators/marley.rb - lib/jekyll/migrators/mephisto.rb - lib/jekyll/migrators/mt.rb - lib/jekyll/migrators/posterous.rb - lib/jekyll/migrators/textpattern.rb - lib/jekyll/migrators/tumblr.rb - lib/jekyll/migrators/typo.rb - lib/jekyll/migrators/wordpress.rb - lib/jekyll/migrators/wordpressdotcom.rb - lib/jekyll/page.rb - lib/jekyll/plugin.rb - lib/jekyll/post.rb - lib/jekyll/site.rb - lib/jekyll/static_file.rb - lib/jekyll/tags/highlight.rb - lib/jekyll/tags/include.rb - test/helper.rb - test/source/.htaccess - test/source/_includes/sig.markdown - test/source/_layouts/default.html - test/source/_layouts/simple.html - test/source/_posts/2008-02-02-not-published.textile - test/source/_posts/2008-02-02-published.textile - 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/_posts/2009-01-27-array-categories.textile - test/source/_posts/2009-01-27-categories.textile - test/source/_posts/2009-01-27-category.textile - test/source/_posts/2009-01-27-empty-categories.textile - test/source/_posts/2009-01-27-empty-category.textile - test/source/_posts/2009-03-12-hash-#1.markdown - test/source/_posts/2009-05-18-empty-tag.textile - test/source/_posts/2009-05-18-empty-tags.textile - test/source/_posts/2009-05-18-tag.textile - test/source/_posts/2009-05-18-tags.textile - test/source/_posts/2009-06-22-empty-yaml.textile - test/source/_posts/2009-06-22-no-yaml.textile - test/source/_posts/2010-01-08-triple-dash.markdown - test/source/_posts/2010-01-09-date-override.textile - test/source/_posts/2010-01-09-time-override.textile - test/source/_posts/2010-01-09-timezone-override.textile - test/source/_posts/2010-01-16-override-data.textile - test/source/_posts/2011-04-12-md-extension.md - test/source/_posts/2011-04-12-text-extension.text - test/source/about.html - test/source/category/_posts/2008-9-23-categories.textile - test/source/contacts.html - test/source/css/screen.css - test/source/deal.with.dots.html - test/source/foo/_posts/bar/2008-12-12-topical-post.textile - test/source/index.html - test/source/sitemap.xml - test/source/win/_posts/2009-05-24-yaml-linebreak.markdown - test/source/z_category/_posts/2008-9-23-categories.textile - test/suite.rb - test/test_configuration.rb - test/test_core_ext.rb - test/test_filters.rb - test/test_generated_site.rb - test/test_kramdown.rb - test/test_page.rb - test/test_pager.rb - test/test_post.rb - test/test_rdiscount.rb - test/test_redcarpet.rb - test/test_site.rb - test/test_tags.rb has_rdoc: true homepage: http://github.com/mojombo/jekyll licenses: [] post_install_message: rdoc_options: - --charset=UTF-8 require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" requirements: [] rubyforge_project: jekyll rubygems_version: 1.6.2 signing_key: specification_version: 2 summary: A simple, blog aware, static site generator. test_files: - test/test_configuration.rb - test/test_core_ext.rb - test/test_filters.rb - test/test_generated_site.rb - test/test_kramdown.rb - test/test_page.rb - test/test_pager.rb - test/test_post.rb - test/test_rdiscount.rb - test/test_redcarpet.rb - test/test_site.rb - test/test_tags.rb jekyll-0.11.2/test/0000775000175000017500000000000011752165402013705 5ustar uwabamiuwabamijekyll-0.11.2/test/test_tags.rb0000644000175000017500000000652111752165402016231 0ustar uwabamiuwabami# coding: utf-8 require 'helper' class TestTags < Test::Unit::TestCase def create_post(content, override = {}, converter_class = Jekyll::MarkdownConverter) stub(Jekyll).configuration do Jekyll::DEFAULTS.merge({'pygments' => true}).merge(override) end site = Site.new(Jekyll.configuration) info = { :filters => [Jekyll::Filters], :registers => { :site => site } } @converter = site.converters.find { |c| c.class == converter_class } payload = { "pygments_prefix" => @converter.pygments_prefix, "pygments_suffix" => @converter.pygments_suffix } @result = Liquid::Template.parse(content).render(payload, info) @result = @converter.convert(@result) end def fill_post(code, override = {}) content = <test\n}, @result end end context "post content has highlight with file reference" do setup do fill_post("./jekyll.gemspec") end should "not embed the file" do assert_match %{
./jekyll.gemspec\n
}, @result end end context "post content has highlight tag with UTF character" do setup do fill_post("Æ") end should "render markdown with pygments line handling" do assert_match %{
Æ\n
}, @result end end context "simple post with markdown and pre tags" do setup do @content = <
}, @result end end context "using Maruku" do setup do create_post(@content) end should "parse correctly" do assert_match %r{FIGHT!}, @result assert_match %r{FINISH HIM}, @result end end context "using RDiscount" do setup do create_post(@content, 'markdown' => 'rdiscount') end should "parse correctly" do assert_match %r{FIGHT!}, @result assert_match %r{FINISH HIM}, @result end end context "using Kramdown" do setup do create_post(@content, 'markdown' => 'kramdown') end should "parse correctly" do assert_match %r{FIGHT!}, @result assert_match %r{FINISH HIM}, @result end end context "using Redcarpet" do setup do create_post(@content, 'markdown' => 'redcarpet') end should "parse correctly" do assert_match %r{FIGHT!}, @result assert_match %r{FINISH HIM}, @result end end end end jekyll-0.11.2/test/test_site.rb0000644000175000017500000001337311752165402016242 0ustar uwabamiuwabamirequire 'helper' class TestSite < Test::Unit::TestCase context "creating sites" do setup do stub(Jekyll).configuration do Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) end @site = Site.new(Jekyll.configuration) end should "have an empty tag hash by default" do assert_equal Hash.new, @site.tags end should "reset data before processing" do clear_dest @site.process before_posts = @site.posts.length before_layouts = @site.layouts.length before_categories = @site.categories.length before_tags = @site.tags.length before_pages = @site.pages.length before_static_files = @site.static_files.length before_time = @site.time @site.process assert_equal before_posts, @site.posts.length assert_equal before_layouts, @site.layouts.length assert_equal before_categories, @site.categories.length assert_equal before_tags, @site.tags.length assert_equal before_pages, @site.pages.length assert_equal before_static_files, @site.static_files.length assert before_time <= @site.time end should "write only modified static files" do clear_dest StaticFile.reset_cache @site.process some_static_file = @site.static_files[0].path dest = File.expand_path(@site.static_files[0].destination(@site.dest)) mtime1 = File.stat(dest).mtime.to_i # first run must generate dest file # need to sleep because filesystem timestamps have best resolution in seconds sleep 1 @site.process mtime2 = File.stat(dest).mtime.to_i assert_equal mtime1, mtime2 # simulate file modification by user FileUtils.touch some_static_file sleep 1 @site.process mtime3 = File.stat(dest).mtime.to_i assert_not_equal mtime2, mtime3 # must be regenerated! sleep 1 @site.process mtime4 = File.stat(dest).mtime.to_i assert_equal mtime3, mtime4 # no modifications, so must be the same end should "write static files if not modified but missing in destination" do clear_dest StaticFile.reset_cache @site.process some_static_file = @site.static_files[0].path dest = File.expand_path(@site.static_files[0].destination(@site.dest)) mtime1 = File.stat(dest).mtime.to_i # first run must generate dest file # need to sleep because filesystem timestamps have best resolution in seconds sleep 1 @site.process mtime2 = File.stat(dest).mtime.to_i assert_equal mtime1, mtime2 # simulate destination file deletion File.unlink dest sleep 1 @site.process mtime3 = File.stat(dest).mtime.to_i assert_not_equal mtime2, mtime3 # must be regenerated and differ! sleep 1 @site.process mtime4 = File.stat(dest).mtime.to_i assert_equal mtime3, mtime4 # no modifications, so must be the same end should "read layouts" do @site.read_layouts assert_equal ["default", "simple"].sort, @site.layouts.keys.sort end should "read posts" do @site.read_posts('') posts = Dir[source_dir('_posts', '*')] assert_equal posts.size - 1, @site.posts.size end should "deploy payload" do clear_dest @site.process posts = Dir[source_dir("**", "_posts", "*")] categories = %w(bar baz category foo z_category publish_test win).sort assert_equal posts.size - 1, @site.posts.size assert_equal categories, @site.categories.keys.sort assert_equal 4, @site.categories['foo'].size end should "filter entries" do ent1 = %w[foo.markdown bar.markdown baz.markdown #baz.markdown# .baz.markdow foo.markdown~] ent2 = %w[.htaccess _posts _pages bla.bla] assert_equal %w[foo.markdown bar.markdown baz.markdown], @site.filter_entries(ent1) assert_equal %w[.htaccess bla.bla], @site.filter_entries(ent2) end should "filter entries with exclude" do excludes = %w[README TODO] includes = %w[index.html site.css] @site.exclude = excludes assert_equal includes, @site.filter_entries(excludes + includes) end context 'with orphaned files in destination' do setup do clear_dest @site.process # generate some orphaned files: # hidden file File.open(dest_dir('.htpasswd'), 'w') # single file File.open(dest_dir('obsolete.html'), 'w') # single file in sub directory FileUtils.mkdir(dest_dir('qux')) File.open(dest_dir('qux/obsolete.html'), 'w') # empty directory FileUtils.mkdir(dest_dir('quux')) end teardown do FileUtils.rm_f(dest_dir('.htpasswd')) FileUtils.rm_f(dest_dir('obsolete.html')) FileUtils.rm_rf(dest_dir('qux')) FileUtils.rm_f(dest_dir('quux')) end should 'remove orphaned files in destination' do @site.process assert !File.exist?(dest_dir('.htpasswd')) assert !File.exist?(dest_dir('obsolete.html')) assert !File.exist?(dest_dir('qux')) assert !File.exist?(dest_dir('quux')) end end context 'with an invalid markdown processor in the configuration' do should 'not throw an error at initialization time' do bad_processor = 'not a processor name' assert_nothing_raised do Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor })) end end should 'throw FatalException at process time' do bad_processor = 'not a processor name' s = Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor })) assert_raise Jekyll::FatalException do s.process end end end end end jekyll-0.11.2/test/test_redcarpet.rb0000644000175000017500000000110011752165402017230 0ustar uwabamiuwabamirequire File.dirname(__FILE__) + '/helper' class TestRedcarpet < Test::Unit::TestCase context "redcarpet" do setup do config = { 'redcarpet' => { 'extensions' => ['smart'] }, 'markdown' => 'redcarpet' } @markdown = MarkdownConverter.new config end should "pass redcarpet options" do assert_equal "

Some Header

", @markdown.convert('# Some Header #').strip end should "pass redcarpet extensions" do assert_equal "

“smart”

", @markdown.convert('"smart"').strip end end end jekyll-0.11.2/test/test_rdiscount.rb0000644000175000017500000000063511752165402017305 0ustar uwabamiuwabamirequire 'helper' class TestRdiscount < Test::Unit::TestCase context "rdiscount" do setup do config = { 'rdiscount' => { 'extensions' => ['smart'] }, 'markdown' => 'rdiscount' } @markdown = MarkdownConverter.new config end should "pass rdiscount extensions" do assert_equal "

“smart”

", @markdown.convert('"smart"').strip end end end jekyll-0.11.2/test/test_post.rb0000644000175000017500000003460111752165402016260 0ustar uwabamiuwabamirequire 'helper' class TestPost < Test::Unit::TestCase def setup_post(file) Post.new(@site, source_dir, '', file) end def do_render(post) layouts = { "default" => Layout.new(@site, source_dir('_layouts'), "simple.html")} post.render(layouts, {"site" => {"posts" => []}}) end context "A Post" do setup do clear_dest stub(Jekyll).configuration { Jekyll::DEFAULTS } @site = Site.new(Jekyll.configuration) end should "ensure valid posts are valid" do assert Post.valid?("2008-09-09-foo-bar.textile") assert Post.valid?("foo/bar/2008-09-09-foo-bar.textile") assert !Post.valid?("lol2008-09-09-foo-bar.textile") assert !Post.valid?("blah") end context "processing posts" do setup do @post = Post.allocate @post.site = @site @real_file = "2008-10-18-foo-bar.textile" @fake_file = "2008-09-09-foo-bar.textile" @source = source_dir('_posts') end should "keep date, title, and markup type" do @post.categories = [] @post.process(@fake_file) assert_equal Time.parse("2008-09-09"), @post.date assert_equal "foo-bar", @post.slug assert_equal ".textile", @post.ext assert_equal "/2008/09/09", @post.dir assert_equal "/2008/09/09/foo-bar", @post.id end should "create url based on date and title" do @post.categories = [] @post.process(@fake_file) assert_equal "/2008/09/09/foo-bar.html", @post.url end should "raise a good error on invalid post date" do assert_raise Jekyll::FatalException do @post.process("2009-27-03-foo-bar.textile") end end should "CGI escape urls" do @post.categories = [] @post.process("2009-03-12-hash-#1.markdown") assert_equal "/2009/03/12/hash-%231.html", @post.url assert_equal "/2009/03/12/hash-#1", @post.id end should "respect permalink in yaml front matter" do file = "2008-12-03-permalinked-post.textile" @post.process(file) @post.read_yaml(@source, file) assert_equal "my_category/permalinked-post", @post.permalink assert_equal "my_category", @post.dir assert_equal "my_category/permalinked-post", @post.url end context "with CRLF linebreaks" do setup do @real_file = "2009-05-24-yaml-linebreak.markdown" @source = source_dir('win/_posts') end should "read yaml front-matter" do @post.read_yaml(@source, @real_file) assert_equal({"title" => "Test title", "layout" => "post", "tag" => "Ruby"}, @post.data) assert_equal "This is the content", @post.content end end context "with embedded triple dash" do setup do @real_file = "2010-01-08-triple-dash.markdown" end should "consume the embedded dashes" do @post.read_yaml(@source, @real_file) assert_equal({"title" => "Foo --- Bar"}, @post.data) assert_equal "Triple the fun!", @post.content end end context "with site wide permalink" do setup do @post.categories = [] end context "with unspecified (date) style" do setup do @post.process(@fake_file) end should "process the url correctly" do assert_equal "/:categories/:year/:month/:day/:title.html", @post.template assert_equal "/2008/09/09/foo-bar.html", @post.url end end context "with unspecified (date) style and a category" do setup do @post.categories << "beer" @post.process(@fake_file) end should "process the url correctly" do assert_equal "/:categories/:year/:month/:day/:title.html", @post.template assert_equal "/beer/2008/09/09/foo-bar.html", @post.url end end context "with unspecified (date) style and categories" do setup do @post.categories << "food" @post.categories << "beer" @post.process(@fake_file) end should "process the url correctly" do assert_equal "/:categories/:year/:month/:day/:title.html", @post.template assert_equal "/food/beer/2008/09/09/foo-bar.html", @post.url end end context "with none style" do setup do @post.site.permalink_style = :none @post.process(@fake_file) end should "process the url correctly" do assert_equal "/:categories/:title.html", @post.template assert_equal "/foo-bar.html", @post.url end end context "with pretty style" do setup do @post.site.permalink_style = :pretty @post.process(@fake_file) end should "process the url correctly" do assert_equal "/:categories/:year/:month/:day/:title/", @post.template assert_equal "/2008/09/09/foo-bar/", @post.url end end context "with custom date permalink" do setup do @post.site.permalink_style = '/:categories/:year/:i_month/:i_day/:title/' @post.process(@fake_file) end should "process the url correctly" do assert_equal "/2008/9/9/foo-bar/", @post.url end end context "with prefix style and no extension" do setup do @post.site.permalink_style = "/prefix/:title" @post.process(@fake_file) end should "process the url correctly" do assert_equal "/prefix/:title", @post.template assert_equal "/prefix/foo-bar", @post.url end end end should "read yaml front-matter" do @post.read_yaml(@source, @real_file) assert_equal({"title" => "Foo Bar", "layout" => "default"}, @post.data) assert_equal "h1. {{ page.title }}\n\nBest *post* ever", @post.content end should "transform textile" do @post.process(@real_file) @post.read_yaml(@source, @real_file) @post.transform assert_equal "

{{ page.title }}

\n

Best post ever

", @post.content end end context "when in a site" do setup do clear_dest stub(Jekyll).configuration { Jekyll::DEFAULTS } @site = Site.new(Jekyll.configuration) @site.posts = [setup_post('2008-02-02-published.textile'), setup_post('2009-01-27-categories.textile')] end should "have next post" do assert_equal(@site.posts.last, @site.posts.first.next) end should "have previous post" do assert_equal(@site.posts.first, @site.posts.last.previous) end should "not have previous post if first" do assert_equal(nil, @site.posts.first.previous) end should "not have next post if last" do assert_equal(nil, @site.posts.last.next) end end context "initializing posts" do should "publish when published yaml is no specified" do post = setup_post("2008-02-02-published.textile") assert_equal true, post.published end should "not published when published yaml is false" do post = setup_post("2008-02-02-not-published.textile") assert_equal false, post.published end should "recognize date in yaml" do post = setup_post("2010-01-09-date-override.textile") do_render(post) assert_equal Time, post.date.class assert_equal Time, post.to_liquid["date"].class assert_equal "/2010/01/10/date-override.html", post.url assert_equal "

Post with a front matter date

\n

10 Jan 2010

", post.output end should "recognize time in yaml" do post = setup_post("2010-01-09-time-override.textile") do_render(post) assert_equal Time, post.date.class assert_equal Time, post.to_liquid["date"].class assert_equal "/2010/01/10/time-override.html", post.url assert_equal "

Post with a front matter time

\n

10 Jan 2010

", post.output end should "recognize time with timezone in yaml" do post = setup_post("2010-01-09-timezone-override.textile") do_render(post) assert_equal Time, post.date.class assert_equal Time, post.to_liquid["date"].class assert_equal "/2010/01/10/timezone-override.html", post.url assert_equal "

Post with a front matter time with timezone

\n

10 Jan 2010

", post.output end should "to_liquid prioritizes post attributes over data" do post = setup_post("2010-01-16-override-data.textile") assert_equal Array, post.tags.class assert_equal Array, post.to_liquid["tags"].class assert_equal Time, post.date.class assert_equal Time, post.to_liquid["date"].class end should "recognize category in yaml" do post = setup_post("2009-01-27-category.textile") assert post.categories.include?('foo') end should "recognize several categories in yaml" do post = setup_post("2009-01-27-categories.textile") assert post.categories.include?('foo') assert post.categories.include?('bar') assert post.categories.include?('baz') end should "recognize empty category in yaml" do post = setup_post("2009-01-27-empty-category.textile") assert_equal [], post.categories end should "recognize empty categories in yaml" do post = setup_post("2009-01-27-empty-categories.textile") assert_equal [], post.categories end should "recognize tag in yaml" do post = setup_post("2009-05-18-tag.textile") assert post.tags.include?('code') end should "recognize tags in yaml" do post = setup_post("2009-05-18-tags.textile") assert post.tags.include?('food') assert post.tags.include?('cooking') assert post.tags.include?('pizza') end should "recognize empty tag in yaml" do post = setup_post("2009-05-18-empty-tag.textile") assert_equal [], post.tags end should "recognize empty tags in yaml" do post = setup_post("2009-05-18-empty-tags.textile") assert_equal [], post.tags end should "allow no yaml" do post = setup_post("2009-06-22-no-yaml.textile") assert_equal "No YAML.", post.content end should "allow empty yaml" do post = setup_post("2009-06-22-empty-yaml.textile") assert_equal "Empty YAML.", post.content end context "rendering" do setup do clear_dest end should "render properly" do post = setup_post("2008-10-18-foo-bar.textile") do_render(post) assert_equal "<<<

Foo Bar

\n

Best post ever

>>>", post.output end should "write properly" do post = setup_post("2008-10-18-foo-bar.textile") do_render(post) post.write(dest_dir) assert File.directory?(dest_dir) assert File.exists?(File.join(dest_dir, '2008', '10', '18', 'foo-bar.html')) end should "write properly without html extension" do post = setup_post("2008-10-18-foo-bar.textile") post.site.permalink_style = ":title" do_render(post) post.write(dest_dir) assert File.directory?(dest_dir) assert File.exists?(File.join(dest_dir, 'foo-bar', 'index.html')) end should "insert data" do post = setup_post("2008-11-21-complex.textile") do_render(post) assert_equal "<<<

url: /2008/11/21/complex.html
\ndate: #{Time.parse("2008-11-21")}
\nid: /2008/11/21/complex

>>>", post.output end should "include templates" do post = setup_post("2008-12-13-include.markdown") post.site.source = File.join(File.dirname(__FILE__), 'source') do_render(post) assert_equal "<<<
\n

Tom Preston-Werner github.com/mojombo

\n\n

This is cool

>>>", post.output end should "render date specified in front matter properly" do post = setup_post("2010-01-09-date-override.textile") do_render(post) assert_equal "

Post with a front matter date

\n

10 Jan 2010

", post.output end should "render time specified in front matter properly" do post = setup_post("2010-01-09-time-override.textile") do_render(post) assert_equal "

Post with a front matter time

\n

10 Jan 2010

", post.output end end end should "generate categories and topics" do post = Post.new(@site, File.join(File.dirname(__FILE__), *%w[source]), 'foo', 'bar/2008-12-12-topical-post.textile') assert_equal ['foo'], post.categories end end context "converter file extension settings" do setup do stub(Jekyll).configuration { Jekyll::DEFAULTS } @site = Site.new(Jekyll.configuration) end should "process .md as markdown under default configuration" do post = setup_post '2011-04-12-md-extension.md' conv = post.converter assert conv.kind_of? Jekyll::MarkdownConverter end should "process .text as indentity under default configuration" do post = setup_post '2011-04-12-text-extension.text' conv = post.converter assert conv.kind_of? Jekyll::IdentityConverter end should "process .text as markdown under alternate configuration" do @site.config['markdown_ext'] = 'markdown,mdw,mdwn,md,text' post = setup_post '2011-04-12-text-extension.text' conv = post.converter assert conv.kind_of? Jekyll::MarkdownConverter end should "process .md as markdown under alternate configuration" do @site.config['markdown_ext'] = 'markdown,mkd,mkdn,md,text' post = setup_post '2011-04-12-text-extension.text' conv = post.converter assert conv.kind_of? Jekyll::MarkdownConverter end should "process .text as textile under alternate configuration" do @site.config['textile_ext'] = 'textile,text' post = setup_post '2011-04-12-text-extension.text' conv = post.converter assert conv.kind_of? Jekyll::TextileConverter end end end jekyll-0.11.2/test/test_pager.rb0000644000175000017500000000604711752165402016374 0ustar uwabamiuwabamirequire 'helper' class TestPager < Test::Unit::TestCase should "calculate number of pages" do assert_equal(0, Pager.calculate_pages([], '2')) assert_equal(1, Pager.calculate_pages([1], '2')) assert_equal(1, Pager.calculate_pages([1,2], '2')) assert_equal(2, Pager.calculate_pages([1,2,3], '2')) assert_equal(2, Pager.calculate_pages([1,2,3,4], '2')) assert_equal(3, Pager.calculate_pages([1,2,3,4,5], '2')) end context "pagination disabled" do setup do stub(Jekyll).configuration do Jekyll::DEFAULTS.merge({ 'source' => source_dir, 'destination' => dest_dir }) end @config = Jekyll.configuration end should "report that pagination is disabled" do assert !Pager.pagination_enabled?(@config, 'index.html') end end context "pagination enabled for 2" do setup do stub(Jekyll).configuration do Jekyll::DEFAULTS.merge({ 'source' => source_dir, 'destination' => dest_dir, 'paginate' => 2 }) end @config = Jekyll.configuration @site = Site.new(@config) @site.process @posts = @site.posts end should "report that pagination is enabled" do assert Pager.pagination_enabled?(@config, 'index.html') end context "with 4 posts" do setup do @posts = @site.posts[1..4] # limit to 4 end should "create first pager" do pager = Pager.new(@config, 1, @posts) assert_equal(2, pager.posts.size) assert_equal(2, pager.total_pages) assert_nil(pager.previous_page) assert_equal(2, pager.next_page) end should "create second pager" do pager = Pager.new(@config, 2, @posts) assert_equal(2, pager.posts.size) assert_equal(2, pager.total_pages) assert_equal(1, pager.previous_page) assert_nil(pager.next_page) end should "not create third pager" do assert_raise(RuntimeError) { Pager.new(@config, 3, @posts) } end end context "with 5 posts" do setup do @posts = @site.posts[1..5] # limit to 5 end should "create first pager" do pager = Pager.new(@config, 1, @posts) assert_equal(2, pager.posts.size) assert_equal(3, pager.total_pages) assert_nil(pager.previous_page) assert_equal(2, pager.next_page) end should "create second pager" do pager = Pager.new(@config, 2, @posts) assert_equal(2, pager.posts.size) assert_equal(3, pager.total_pages) assert_equal(1, pager.previous_page) assert_equal(3, pager.next_page) end should "create third pager" do pager = Pager.new(@config, 3, @posts) assert_equal(1, pager.posts.size) assert_equal(3, pager.total_pages) assert_equal(2, pager.previous_page) assert_nil(pager.next_page) end should "not create fourth pager" do assert_raise(RuntimeError) { Pager.new(@config, 4, @posts) } end end end end jekyll-0.11.2/test/test_page.rb0000644000175000017500000000620311752165402016204 0ustar uwabamiuwabamirequire 'helper' class TestPage < Test::Unit::TestCase def setup_page(file) @page = Page.new(@site, source_dir, '', file) end def do_render(page) layouts = { "default" => Layout.new(@site, source_dir('_layouts'), "simple.html")} page.render(layouts, {"site" => {"posts" => []}}) end context "A Page" do setup do clear_dest stub(Jekyll).configuration { Jekyll::DEFAULTS } @site = Site.new(Jekyll.configuration) end context "processing pages" do should "create url based on filename" do @page = setup_page('contacts.html') assert_equal "/contacts.html", @page.url end should "deal properly with extensions" do @page = setup_page('deal.with.dots.html') assert_equal ".html", @page.ext end should "deal properly with dots" do @page = setup_page('deal.with.dots.html') assert_equal "deal.with.dots", @page.basename end context "with pretty url style" do setup do @site.permalink_style = :pretty end should "return dir correctly" do @page = setup_page('contacts.html') assert_equal '/contacts/', @page.dir end should "return dir correctly for index page" do @page = setup_page('index.html') assert_equal '/', @page.dir end end context "with any other url style" do should "return dir correctly" do @site.permalink_style = nil @page = setup_page('contacts.html') assert_equal '/', @page.dir end end should "respect permalink in yaml front matter" do file = "about.html" @page = setup_page(file) assert_equal "/about/", @page.permalink assert_equal @page.permalink, @page.url assert_equal "/about/", @page.dir end end context "rendering" do setup do clear_dest end should "write properly" do page = setup_page('contacts.html') do_render(page) page.write(dest_dir) assert File.directory?(dest_dir) assert File.exists?(File.join(dest_dir, 'contacts.html')) end should "write properly without html extension" do page = setup_page('contacts.html') page.site.permalink_style = :pretty do_render(page) page.write(dest_dir) assert File.directory?(dest_dir) assert File.exists?(File.join(dest_dir, 'contacts', 'index.html')) end should "write properly with extension different from html" do page = setup_page("sitemap.xml") page.site.permalink_style = :pretty do_render(page) page.write(dest_dir) assert_equal("/sitemap.xml", page.url) assert_nil(page.url[/\.html$/]) assert File.directory?(dest_dir) assert File.exists?(File.join(dest_dir,'sitemap.xml')) end should "write dotfiles properly" do page = setup_page('.htaccess') do_render(page) page.write(dest_dir) assert File.directory?(dest_dir) assert File.exists?(File.join(dest_dir, '.htaccess')) end end end end jekyll-0.11.2/test/test_kramdown.rb0000644000175000017500000000112411752165402017107 0ustar uwabamiuwabamirequire 'helper' class TestKramdown < Test::Unit::TestCase context "kramdown" do setup do config = { 'markdown' => 'kramdown', 'kramdown' => { 'auto_ids' => false, 'footnote_nr' => 1, 'entity_output' => 'as_char', 'toc_levels' => '1..6' } } @markdown = MarkdownConverter.new config end # http://kramdown.rubyforge.org/converter/html.html#options should "pass kramdown options" do assert_equal "

Some Header

", @markdown.convert('# Some Header #').strip end end end jekyll-0.11.2/test/test_generated_site.rb0000644000175000017500000000374411752165402020261 0ustar uwabamiuwabamirequire 'helper' class TestGeneratedSite < Test::Unit::TestCase context "generated sites" do setup do clear_dest stub(Jekyll).configuration do Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) end @site = Site.new(Jekyll.configuration) @site.process @index = File.read(dest_dir('index.html')) end should "ensure post count is as expected" do assert_equal 28, @site.posts.size end should "insert site.posts into the index" do assert @index.include?("#{@site.posts.size} Posts") end should "render latest post's content" do assert @index.include?(@site.posts.last.content) end should "hide unpublished posts" do published = Dir[dest_dir('publish_test/2008/02/02/*.html')].map {|f| File.basename(f)} assert_equal 1, published.size assert_equal "published.html", published.first end should "not copy _posts directory" do assert !File.exist?(dest_dir('_posts')) end should "process other static files and generate correct permalinks" do assert File.exists?(dest_dir('/about/index.html')) assert File.exists?(dest_dir('/contacts.html')) end end context "generating limited posts" do setup do clear_dest stub(Jekyll).configuration do Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'limit_posts' => 5}) end @site = Site.new(Jekyll.configuration) @site.process @index = File.read(dest_dir('index.html')) end should "generate only the specified number of posts" do assert_equal 5, @site.posts.size end should "ensure limit posts is 1 or more" do assert_raise ArgumentError do clear_dest stub(Jekyll).configuration do Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'limit_posts' => 0}) end @site = Site.new(Jekyll.configuration) end end end end jekyll-0.11.2/test/test_filters.rb0000644000175000017500000000413111752165402016736 0ustar uwabamiuwabamirequire 'helper' class TestFilters < Test::Unit::TestCase class JekyllFilter include Jekyll::Filters def initialize site = Jekyll::Site.new(Jekyll.configuration({})) @context = Liquid::Context.new({}, {}, { :site => site }) end end context "filters" do setup do @filter = JekyllFilter.new end should "textilize with simple string" do assert_equal "

something really simple

", @filter.textilize("something *really* simple") end should "markdownify with simple string" do assert_equal "

something really simple

", @filter.markdownify("something **really** simple") end should "convert array to sentence string with no args" do assert_equal "", @filter.array_to_sentence_string([]) end should "convert array to sentence string with one arg" do assert_equal "1", @filter.array_to_sentence_string([1]) assert_equal "chunky", @filter.array_to_sentence_string(["chunky"]) end should "convert array to sentence string with two args" do assert_equal "1 and 2", @filter.array_to_sentence_string([1, 2]) assert_equal "chunky and bacon", @filter.array_to_sentence_string(["chunky", "bacon"]) end should "convert array to sentence string with multiple args" do assert_equal "1, 2, 3, and 4", @filter.array_to_sentence_string([1, 2, 3, 4]) assert_equal "chunky, bacon, bits, and pieces", @filter.array_to_sentence_string(["chunky", "bacon", "bits", "pieces"]) end should "escape xml with ampersands" do assert_equal "AT&T", @filter.xml_escape("AT&T") assert_equal "<code>command &lt;filename&gt;</code>", @filter.xml_escape("command <filename>") end should "escape space as plus" do assert_equal "my+things", @filter.cgi_escape("my things") end should "escape special characters" do assert_equal "hey%21", @filter.cgi_escape("hey!") end should "escape space as %20" do assert_equal "my%20things", @filter.uri_escape("my things") end end end jekyll-0.11.2/test/test_core_ext.rb0000644000175000017500000000454711752165402017111 0ustar uwabamiuwabamirequire 'helper' class TestCoreExt < Test::Unit::TestCase context "hash" do context "pluralized_array" do should "return empty array with no values" do data = {} assert_equal [], data.pluralized_array('tag', 'tags') end should "return empty array with no matching values" do data = { 'foo' => 'bar' } assert_equal [], data.pluralized_array('tag', 'tags') end should "return empty array with matching nil singular" do data = { 'foo' => 'bar', 'tag' => nil, 'tags' => ['dog', 'cat'] } assert_equal [], data.pluralized_array('tag', 'tags') end should "return single value array with matching singular" do data = { 'foo' => 'bar', 'tag' => 'dog', 'tags' => ['dog', 'cat'] } assert_equal ['dog'], data.pluralized_array('tag', 'tags') end should "return single value array with matching singular with spaces" do data = { 'foo' => 'bar', 'tag' => 'dog cat', 'tags' => ['dog', 'cat'] } assert_equal ['dog cat'], data.pluralized_array('tag', 'tags') end should "return empty array with matching nil plural" do data = { 'foo' => 'bar', 'tags' => nil } assert_equal [], data.pluralized_array('tag', 'tags') end should "return empty array with matching empty array" do data = { 'foo' => 'bar', 'tags' => [] } assert_equal [], data.pluralized_array('tag', 'tags') end should "return single value array with matching plural with single string value" do data = { 'foo' => 'bar', 'tags' => 'dog' } assert_equal ['dog'], data.pluralized_array('tag', 'tags') end should "return multiple value array with matching plural with single string value with spaces" do data = { 'foo' => 'bar', 'tags' => 'dog cat' } assert_equal ['dog', 'cat'], data.pluralized_array('tag', 'tags') end should "return single value array with matching plural with single value array" do data = { 'foo' => 'bar', 'tags' => ['dog'] } assert_equal ['dog'], data.pluralized_array('tag', 'tags') end should "return multiple value array with matching plural with multiple value array" do data = { 'foo' => 'bar', 'tags' => ['dog', 'cat'] } assert_equal ['dog', 'cat'], data.pluralized_array('tag', 'tags') end end end end jekyll-0.11.2/test/test_configuration.rb0000644000175000017500000000210111752165402020130 0ustar uwabamiuwabamirequire 'helper' class TestConfiguration < Test::Unit::TestCase context "loading configuration" do setup do @path = File.join(Dir.pwd, '_config.yml') end should "fire warning with no _config.yml" do mock(YAML).load_file(@path) { raise "No such file or directory - #{@path}" } mock($stderr).puts("WARNING: Could not read configuration. Using defaults (and options).") mock($stderr).puts("\tNo such file or directory - #{@path}") assert_equal Jekyll::DEFAULTS, Jekyll.configuration({}) end should "load configuration as hash" do mock(YAML).load_file(@path) { Hash.new } mock($stdout).puts("Configuration from #{@path}") assert_equal Jekyll::DEFAULTS, Jekyll.configuration({}) end should "fire warning with bad config" do mock(YAML).load_file(@path) { Array.new } mock($stderr).puts("WARNING: Could not read configuration. Using defaults (and options).") mock($stderr).puts("\tInvalid configuration - #{@path}") assert_equal Jekyll::DEFAULTS, Jekyll.configuration({}) end end end jekyll-0.11.2/test/suite.rb0000644000175000017500000000041211752165402015356 0ustar uwabamiuwabamirequire 'rubygems' gem 'test-unit' require 'test/unit' # for some reason these tests fail when run via TextMate # but succeed when run on the command line. tests = Dir[File.expand_path("#{File.dirname(__FILE__)}/test_*.rb")] tests.each do |file| require file endjekyll-0.11.2/test/source/0000775000175000017500000000000011752165402015205 5ustar uwabamiuwabamijekyll-0.11.2/test/source/z_category/0000775000175000017500000000000011752165402017353 5ustar uwabamiuwabamijekyll-0.11.2/test/source/z_category/_posts/0000775000175000017500000000000011752165402020662 5ustar uwabamiuwabamijekyll-0.11.2/test/source/z_category/_posts/2008-9-23-categories.textile0000644000175000017500000000014111752165402025360 0ustar uwabamiuwabami--- layout: default title: Categories --- Categories _should_ work. Even if ordered after index.jekyll-0.11.2/test/source/win/0000775000175000017500000000000011752165402016002 5ustar uwabamiuwabamijekyll-0.11.2/test/source/win/_posts/0000775000175000017500000000000011752165402017311 5ustar uwabamiuwabamijekyll-0.11.2/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown0000644000175000017500000000011711752165402025003 0ustar uwabamiuwabami--- layout: post title: "Test title" tag: "Ruby" --- This is the contentjekyll-0.11.2/test/source/sitemap.xml0000644000175000017500000000204111752165402017364 0ustar uwabamiuwabami--- layout: nil --- http://example.com {{ site.time | date: "%Y-%m-%d" }} daily 1.0 {% for post in site.posts %} http://example.com{{ post.url }}/ {{ post.date | date: "%Y-%m-%d" }} monthly 0.2 {% endfor %} {% for page in site.html_pages %} http://example.com{{ page.url }} {{ site.time | date: "%Y-%m-%d" }} {% if page.changefreq %}{{ page.changefreq }}{% endif %} {% if page.priority %}{{ page.priority }}{% endif %} {% endfor %} jekyll-0.11.2/test/source/index.html0000644000175000017500000000063311752165402017202 0ustar uwabamiuwabami--- layout: default title: Tom Preston-Werner --- h1. Welcome to my site h2. Please read our {{ site.posts | size }} Posts {% assign first_post = site.posts.first %}

{{ first_post.title }}

{{ first_post.content }}
jekyll-0.11.2/test/source/foo/0000775000175000017500000000000011752165402015770 5ustar uwabamiuwabamijekyll-0.11.2/test/source/foo/_posts/0000775000175000017500000000000011752165402017277 5ustar uwabamiuwabamijekyll-0.11.2/test/source/foo/_posts/bar/0000775000175000017500000000000011752165402020043 5ustar uwabamiuwabamijekyll-0.11.2/test/source/foo/_posts/bar/2008-12-12-topical-post.textile0000644000175000017500000000013211752165402025102 0ustar uwabamiuwabami--- layout: default title: Topical Post --- h1. {{ page.title }} This post has a topic. jekyll-0.11.2/test/source/deal.with.dots.html0000644000175000017500000000015311752165402020717 0ustar uwabamiuwabami--- title: Deal with dots permalink: /deal.with.dots/ --- Let's test if jekyll deals properly with dots. jekyll-0.11.2/test/source/css/0000775000175000017500000000000011752165402015775 5ustar uwabamiuwabamijekyll-0.11.2/test/source/css/screen.css0000644000175000017500000000177311752165402017774 0ustar uwabamiuwabami/*****************************************************************************/ /* /* Common /* /*****************************************************************************/ /* Global Reset */ * { margin: 0; padding: 0; } html, body { height: 100%; } body { background-color: white; font: 13.34px helvetica, arial, clean, sans-serif; *font-size: small; text-align: center; } h1, h2, h3, h4, h5, h6 { font-size: 100%; } h1 { margin-bottom: 1em; } p { margin: 1em 0; } a { color: #00a; } a:hover { color: black; } a:visited { color: #a0a; } table { font-size: inherit; font: 100%; } /*****************************************************************************/ /* /* Site /* /*****************************************************************************/ .site { font-size: 110%; text-align: justify; width: 40em; margin: 3em auto 2em auto; line-height: 1.5em; } .title { color: #a00; font-weight: bold; margin-bottom: 2em; } .site .meta { color: #aaa; }jekyll-0.11.2/test/source/contacts.html0000644000175000017500000000007011752165402017704 0ustar uwabamiuwabami--- title: Contact Information --- Contact Information jekyll-0.11.2/test/source/category/0000775000175000017500000000000011752165402017022 5ustar uwabamiuwabamijekyll-0.11.2/test/source/category/_posts/0000775000175000017500000000000011752165402020331 5ustar uwabamiuwabamijekyll-0.11.2/test/source/category/_posts/2008-9-23-categories.textile0000644000175000017500000000010311752165402025025 0ustar uwabamiuwabami--- layout: default title: Categories --- Categories _should_ workjekyll-0.11.2/test/source/about.html0000644000175000017500000000007011752165402017200 0ustar uwabamiuwabami--- title: About permalink: /about/ --- About the site jekyll-0.11.2/test/source/_posts/0000775000175000017500000000000011752165402016514 5ustar uwabamiuwabamijekyll-0.11.2/test/source/_posts/2011-04-12-text-extension.text0000644000175000017500000000000011752165402023426 0ustar uwabamiuwabamijekyll-0.11.2/test/source/_posts/2011-04-12-md-extension.md0000644000175000017500000000041311752165402022466 0ustar uwabamiuwabami--- date: 2011-04-12 13:07:09 --- under default configuration, this post should get processed by the identity converter. By changing textile extension or markdown extension configuration parameters, you should be able to associate it with either of those convertersjekyll-0.11.2/test/source/_posts/2010-01-16-override-data.textile0000644000175000017500000000006111752165402023657 0ustar uwabamiuwabami--- date: 2010-01-10 13:07:09 tags: A string --- jekyll-0.11.2/test/source/_posts/2010-01-09-timezone-override.textile0000644000175000017500000000017011752165402024603 0ustar uwabamiuwabami--- date: 2010-01-10 13:07:09 +00:00 --- Post with a front matter time with timezone {{ page.date | date_to_string }} jekyll-0.11.2/test/source/_posts/2010-01-09-time-override.textile0000644000175000017500000000014311752165402023707 0ustar uwabamiuwabami--- date: 2010-01-10 13:07:09 --- Post with a front matter time {{ page.date | date_to_string }} jekyll-0.11.2/test/source/_posts/2010-01-09-date-override.textile0000644000175000017500000000013211752165402023664 0ustar uwabamiuwabami--- date: 2010-01-10 --- Post with a front matter date {{ page.date | date_to_string }} jekyll-0.11.2/test/source/_posts/2010-01-08-triple-dash.markdown0000644000175000017500000000005311752165402023513 0ustar uwabamiuwabami--- title: Foo --- Bar --- Triple the fun!jekyll-0.11.2/test/source/_posts/2009-06-22-no-yaml.textile0000644000175000017500000000001011752165402022511 0ustar uwabamiuwabamiNo YAML.jekyll-0.11.2/test/source/_posts/2009-06-22-empty-yaml.textile0000644000175000017500000000002311752165402023237 0ustar uwabamiuwabami--- --- Empty YAML.jekyll-0.11.2/test/source/_posts/2009-05-18-tags.textile0000644000175000017500000000010211752165402022101 0ustar uwabamiuwabami--- title: Some Tags tags: - food - cooking - pizza --- Awesome! jekyll-0.11.2/test/source/_posts/2009-05-18-tag.textile0000644000175000017500000000004611752165402021725 0ustar uwabamiuwabami--- title: A Tag tag: code --- Whoa. jekyll-0.11.2/test/source/_posts/2009-05-18-empty-tags.textile0000644000175000017500000000005111752165402023240 0ustar uwabamiuwabami--- title: Some Tags tags: --- Awesome! jekyll-0.11.2/test/source/_posts/2009-05-18-empty-tag.textile0000644000175000017500000000004111752165402023054 0ustar uwabamiuwabami--- title: A Tag tag: --- Whoa. jekyll-0.11.2/test/source/_posts/2009-03-12-hash-#1.markdown0000644000175000017500000000007011752165402022427 0ustar uwabamiuwabami--- layout: default title: Hash #1 --- Hashes are nice jekyll-0.11.2/test/source/_posts/2009-01-27-empty-category.textile0000644000175000017500000000011411752165402024113 0ustar uwabamiuwabami--- layout: default title: Category in YAML category: --- Best *post* ever jekyll-0.11.2/test/source/_posts/2009-01-27-empty-categories.textile0000644000175000017500000000011611752165402024425 0ustar uwabamiuwabami--- layout: default title: Category in YAML categories: --- Best *post* ever jekyll-0.11.2/test/source/_posts/2009-01-27-category.textile0000644000175000017500000000012011752165402022754 0ustar uwabamiuwabami--- layout: default title: Category in YAML category: foo --- Best *post* ever jekyll-0.11.2/test/source/_posts/2009-01-27-categories.textile0000644000175000017500000000013411752165402023271 0ustar uwabamiuwabami--- layout: default title: Categories in YAML categories: foo bar baz --- Best *post* ever jekyll-0.11.2/test/source/_posts/2009-01-27-array-categories.textile0000644000175000017500000000015011752165402024403 0ustar uwabamiuwabami--- layout: default title: Array categories in YAML categories: - foo - bar - baz --- Best *post* ever jekyll-0.11.2/test/source/_posts/2008-12-13-include.markdown0000644000175000017500000000012211752165402022724 0ustar uwabamiuwabami--- layout: default title: Include --- {% include sig.markdown %} This _is_ cooljekyll-0.11.2/test/source/_posts/2008-12-03-permalinked-post.textile0000644000175000017500000000021111752165402024411 0ustar uwabamiuwabami--- title: Post with Permalink permalink: my_category/permalinked-post --- h1. {{ page.title }}

Best post ever

jekyll-0.11.2/test/source/_posts/2008-11-21-complex.textile0000644000175000017500000000014311752165402022605 0ustar uwabamiuwabami--- layout: default title: Complex --- url: {{ page.url }} date: {{ page.date }} id: {{ page.id }}jekyll-0.11.2/test/source/_posts/2008-10-18-foo-bar.textile0000644000175000017500000000011611752165402022470 0ustar uwabamiuwabami--- layout: default title: Foo Bar --- h1. {{ page.title }} Best *post* everjekyll-0.11.2/test/source/_posts/2008-02-02-published.textile0000644000175000017500000000013211752165402023112 0ustar uwabamiuwabami--- layout: default title: Publish category: publish_test --- This should be published. jekyll-0.11.2/test/source/_posts/2008-02-02-not-published.textile0000644000175000017500000000016711752165402023720 0ustar uwabamiuwabami--- layout: default title: Not published! published: false category: publish_test --- This should *not* be published! jekyll-0.11.2/test/source/_layouts/0000775000175000017500000000000011752165402017044 5ustar uwabamiuwabamijekyll-0.11.2/test/source/_layouts/simple.html0000644000175000017500000000002511752165402021216 0ustar uwabamiuwabami<<< {{ content }} >>>jekyll-0.11.2/test/source/_layouts/default.html0000644000175000017500000000132411752165402021354 0ustar uwabamiuwabami {{ page.title }}
Tom Preston-Werner
{{ content }}
jekyll-0.11.2/test/source/_includes/0000775000175000017500000000000011752165402017152 5ustar uwabamiuwabamijekyll-0.11.2/test/source/_includes/sig.markdown0000644000175000017500000000005011752165402021471 0ustar uwabamiuwabami-- Tom Preston-Werner github.com/mojombojekyll-0.11.2/test/source/.htaccess0000644000175000017500000000021011752165402016772 0ustar uwabamiuwabami--- layout: nil --- ErrorDocument 404 /404.html ErrorDocument 500 /500.html {% for post in site.posts %} # {{ post.url }} {% endfor %}jekyll-0.11.2/test/helper.rb0000644000175000017500000000122211752165402015504 0ustar uwabamiuwabamirequire 'rubygems' gem 'RedCloth', '>= 4.2.1' require 'jekyll' require 'RedCloth' require 'rdiscount' require 'kramdown' require 'redcarpet' require 'redgreen' if RUBY_VERSION < '1.9' require 'shoulda' require 'rr' include Jekyll # Send STDERR into the void to suppress program output messages STDERR.reopen(test(?e, '/dev/null') ? '/dev/null' : 'NUL:') class Test::Unit::TestCase include RR::Adapters::TestUnit def dest_dir(*subdirs) File.join(File.dirname(__FILE__), 'dest', *subdirs) end def source_dir(*subdirs) File.join(File.dirname(__FILE__), 'source', *subdirs) end def clear_dest FileUtils.rm_rf(dest_dir) end end jekyll-0.11.2/lib/0000775000175000017500000000000011752165402013474 5ustar uwabamiuwabamijekyll-0.11.2/lib/jekyll/0000775000175000017500000000000011752165402014766 5ustar uwabamiuwabamijekyll-0.11.2/lib/jekyll/tags/0000775000175000017500000000000011752165402015724 5ustar uwabamiuwabamijekyll-0.11.2/lib/jekyll/tags/include.rb0000644000175000017500000000176511752165402017703 0ustar uwabamiuwabamimodule Jekyll class IncludeTag < Liquid::Tag def initialize(tag_name, file, tokens) super @file = file.strip end def render(context) includes_dir = File.join(context.registers[:site].source, '_includes') if File.symlink?(includes_dir) return "Includes directory '#{includes_dir}' cannot be a symlink" end if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./ return "Include file '#{@file}' contains invalid characters or sequences" end Dir.chdir(includes_dir) do choices = Dir['**/*'].reject { |x| File.symlink?(x) } if choices.include?(@file) source = File.read(@file) partial = Liquid::Template.parse(source) context.stack do partial.render(context) end else "Included file '#{@file}' not found in _includes directory" end end end end end Liquid::Template.register_tag('include', Jekyll::IncludeTag) jekyll-0.11.2/lib/jekyll/tags/highlight.rb0000644000175000017500000000366711752165402020232 0ustar uwabamiuwabamimodule Jekyll class HighlightBlock < Liquid::Block include Liquid::StandardFilters # We need a language, but the linenos argument is optional. SYNTAX = /(\w+)\s?([\w\s=]+)*/ def initialize(tag_name, markup, tokens) super if markup =~ SYNTAX @lang = $1 if defined? $2 tmp_options = {} $2.split.each do |opt| key, value = opt.split('=') if value.nil? if key == 'linenos' value = 'inline' else value = true end end tmp_options[key] = value end tmp_options = tmp_options.to_a.collect { |opt| opt.join('=') } # additional options to pass to Albino @options = { 'O' => tmp_options.join(',') } else @options = {} end else raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight [linenos]") end end def render(context) if context.registers[:site].pygments render_pygments(context, super) else render_codehighlighter(context, super) end end def render_pygments(context, code) output = add_code_tags(Albino.new(code, @lang).to_s(@options), @lang) output = context["pygments_prefix"] + output if context["pygments_prefix"] output = output + context["pygments_suffix"] if context["pygments_suffix"] output end def render_codehighlighter(context, code) #The div is required because RDiscount blows ass <<-HTML
#{h(code).strip}
HTML end def add_code_tags(code, lang) # Add nested tags to code blocks code = code.sub(/
/,'
')
      code = code.sub(/<\/pre>/,"
") end end end Liquid::Template.register_tag('highlight', Jekyll::HighlightBlock) jekyll-0.11.2/lib/jekyll/static_file.rb0000644000175000017500000000313711752165402017603 0ustar uwabamiuwabamimodule Jekyll class StaticFile # The cache of last modification times [path] -> mtime. @@mtimes = Hash.new # Initialize a new StaticFile. # # site - The Site. # base - The String path to the . # dir - The String path between and the file. # name - The String filename of the file. def initialize(site, base, dir, name) @site = site @base = base @dir = dir @name = name end # Returns source file path. def path File.join(@base, @dir, @name) end # Obtain destination path. # # dest - The String path to the destination dir. # # Returns destination file path. def destination(dest) File.join(dest, @dir, @name) end # Returns last modification time for this file. def mtime File.stat(path).mtime.to_i end # Is source path modified? # # Returns true if modified since last write. def modified? @@mtimes[path] != mtime end # Write the static file to the destination directory (if modified). # # dest - The String path to the destination dir. # # Returns false if the file was not modified since last time (no-op). def write(dest) dest_path = destination(dest) return false if File.exist?(dest_path) and !modified? @@mtimes[path] = mtime FileUtils.mkdir_p(File.dirname(dest_path)) FileUtils.cp(path, dest_path) true end # Reset the mtimes cache (for testing purposes). # # Returns nothing. def self.reset_cache @@mtimes = Hash.new nil end end end jekyll-0.11.2/lib/jekyll/site.rb0000644000175000017500000002414611752165402016264 0ustar uwabamiuwabamirequire 'set' module Jekyll class Site attr_accessor :config, :layouts, :posts, :pages, :static_files, :categories, :exclude, :source, :dest, :lsi, :pygments, :permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts attr_accessor :converters, :generators # Public: Initialize a new Site. # # config - A Hash containing site configuration details. def initialize(config) self.config = config.clone self.safe = config['safe'] self.source = File.expand_path(config['source']) self.dest = File.expand_path(config['destination']) self.plugins = File.expand_path(config['plugins']) self.lsi = config['lsi'] self.pygments = config['pygments'] self.permalink_style = config['permalink'].to_sym self.exclude = config['exclude'] || [] self.future = config['future'] self.limit_posts = config['limit_posts'] || nil self.reset self.setup end # Public: Read, process, and write this Site to output. # # Returns nothing. def process self.reset self.read self.generate self.render self.cleanup self.write end # Reset Site details. # # Returns nothing def reset self.time = if self.config['time'] Time.parse(self.config['time'].to_s) else Time.now end self.layouts = {} self.posts = [] self.pages = [] self.static_files = [] self.categories = Hash.new { |hash, key| hash[key] = [] } self.tags = Hash.new { |hash, key| hash[key] = [] } if !self.limit_posts.nil? && self.limit_posts < 1 raise ArgumentError, "Limit posts must be nil or >= 1" end end # Load necessary libraries, plugins, converters, and generators. # # Returns nothing. def setup require 'classifier' if self.lsi # If safe mode is off, load in any Ruby files under the plugins # directory. unless self.safe Dir[File.join(self.plugins, "**/*.rb")].each do |f| require f end end self.converters = Jekyll::Converter.subclasses.select do |c| !self.safe || c.safe end.map do |c| c.new(self.config) end self.generators = Jekyll::Generator.subclasses.select do |c| !self.safe || c.safe end.map do |c| c.new(self.config) end end # Read Site data from disk and load it into internal data structures. # # Returns nothing. def read self.read_layouts self.read_directories end # Read all the files in //_layouts and create a new Layout # object with each one. # # Returns nothing. def read_layouts(dir = '') base = File.join(self.source, dir, "_layouts") return unless File.exists?(base) entries = [] Dir.chdir(base) { entries = filter_entries(Dir['*.*']) } entries.each do |f| name = f.split(".")[0..-2].join(".") self.layouts[name] = Layout.new(self, base, f) end end # Recursively traverse directories to find posts, pages and static files # that will become part of the site according to the rules in # filter_entries. # # dir - The String relative path of the directory to read. # # Returns nothing. def read_directories(dir = '') base = File.join(self.source, dir) entries = Dir.chdir(base) { filter_entries(Dir['*']) } self.read_posts(dir) entries.each do |f| f_abs = File.join(base, f) f_rel = File.join(dir, f) if File.directory?(f_abs) next if self.dest.sub(/\/$/, '') == f_abs read_directories(f_rel) elsif !File.symlink?(f_abs) first3 = File.open(f_abs) { |fd| fd.read(3) } if first3 == "---" # file appears to have a YAML header so process it as a page pages << Page.new(self, self.source, dir, f) else # otherwise treat it as a static file static_files << StaticFile.new(self, self.source, dir, f) end end end end # Read all the files in //_posts and create a new Post # object with each one. # # dir - The String relative path of the directory to read. # # Returns nothing. def read_posts(dir) base = File.join(self.source, dir, '_posts') return unless File.exists?(base) entries = Dir.chdir(base) { filter_entries(Dir['**/*']) } # first pass processes, but does not yet render post content entries.each do |f| if Post.valid?(f) post = Post.new(self, self.source, dir, f) if post.published && (self.future || post.date <= self.time) self.posts << post post.categories.each { |c| self.categories[c] << post } post.tags.each { |c| self.tags[c] << post } end end end self.posts.sort! # limit the posts if :limit_posts option is set self.posts = self.posts[-limit_posts, limit_posts] if limit_posts end # Run each of the Generators. # # Returns nothing. def generate self.generators.each do |generator| generator.generate(self) end end # Render the site to the destination. # # Returns nothing. def render self.posts.each do |post| post.render(self.layouts, site_payload) end self.pages.each do |page| page.render(self.layouts, site_payload) end self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a } } self.tags.values.map { |ps| ps.sort! { |a, b| b <=> a } } rescue Errno::ENOENT => e # ignore missing layout dir end # Remove orphaned files and empty directories in destination. # # Returns nothing. def cleanup # all files and directories in destination, including hidden ones dest_files = Set.new Dir.glob(File.join(self.dest, "**", "*"), File::FNM_DOTMATCH) do |file| dest_files << file unless file =~ /\/\.{1,2}$/ end # files to be written files = Set.new self.posts.each do |post| files << post.destination(self.dest) end self.pages.each do |page| files << page.destination(self.dest) end self.static_files.each do |sf| files << sf.destination(self.dest) end # adding files' parent directories dirs = Set.new files.each { |file| dirs << File.dirname(file) } files.merge(dirs) obsolete_files = dest_files - files FileUtils.rm_rf(obsolete_files.to_a) end # Write static files, pages, and posts. # # Returns nothing. def write self.posts.each do |post| post.write(self.dest) end self.pages.each do |page| page.write(self.dest) end self.static_files.each do |sf| sf.write(self.dest) end end # Constructs a Hash of Posts indexed by the specified Post attribute. # # post_attr - The String name of the Post attribute. # # Examples # # post_attr_hash('categories') # # => { 'tech' => [, ], # # 'ruby' => [] } # # Returns the Hash: { attr => posts } where # attr - One of the values for the requested attribute. # posts - The Array of Posts with the given attr value. def post_attr_hash(post_attr) # Build a hash map based on the specified post attribute ( post attr => # array of posts ) then sort each array in reverse order. hash = Hash.new { |hsh, key| hsh[key] = Array.new } self.posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } } hash.values.map { |sortme| sortme.sort! { |a, b| b <=> a } } hash end # The Hash payload containing site-wide data. # # Returns the Hash: { "site" => data } where data is a Hash with keys: # "time" - The Time as specified in the configuration or the # current time if none was specified. # "posts" - The Array of Posts, sorted chronologically by post date # and then title. # "pages" - The Array of all Pages. # "html_pages" - The Array of HTML Pages. # "categories" - The Hash of category values and Posts. # See Site#post_attr_hash for type info. # "tags" - The Hash of tag values and Posts. # See Site#post_attr_hash for type info. def site_payload {"site" => self.config.merge({ "time" => self.time, "posts" => self.posts.sort { |a, b| b <=> a }, "pages" => self.pages, "html_pages" => self.pages.reject { |page| !page.html? }, "categories" => post_attr_hash('categories'), "tags" => post_attr_hash('tags')})} end # Filter out any files/directories that are hidden or backup files (start # with "." or "#" or end with "~"), or contain site content (start with "_"), # or are excluded in the site configuration, unless they are web server # files such as '.htaccess'. # # entries - The Array of file/directory entries to filter. # # Returns the Array of filtered entries. def filter_entries(entries) entries = entries.reject do |e| unless ['.htaccess'].include?(e) ['.', '_', '#'].include?(e[0..0]) || e[-1..-1] == '~' || self.exclude.include?(e) || File.symlink?(e) end end end # Get the implementation class for the given Converter. # # klass - The Class of the Converter to fetch. # # Returns the Converter instance implementing the given Converter. def getConverterImpl(klass) matches = self.converters.select { |c| c.class == klass } if impl = matches.first impl else raise "Converter implementation not found for #{klass}" end end end end jekyll-0.11.2/lib/jekyll/post.rb0000644000175000017500000001533711752165402016307 0ustar uwabamiuwabamimodule Jekyll class Post include Comparable include Convertible class << self attr_accessor :lsi end MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/ # Post name validator. Post filenames must be like: # 2008-11-05-my-awesome-post.textile # # Returns def self.valid?(name) name =~ MATCHER end attr_accessor :site attr_accessor :data, :content, :output, :ext attr_accessor :date, :slug, :published, :tags, :categories # Initialize this Post instance. # +site+ is the Site # +base+ is the String path to the dir containing the post file # +name+ is the String filename of the post file # +categories+ is an Array of Strings for the categories for this post # # Returns def initialize(site, source, dir, name) @site = site @base = File.join(source, dir, '_posts') @name = name self.categories = dir.split('/').reject { |x| x.empty? } self.process(name) self.read_yaml(@base, name) #If we've added a date and time to the yaml, use that instead of the filename date #Means we'll sort correctly. if self.data.has_key?('date') # ensure Time via to_s and reparse self.date = Time.parse(self.data["date"].to_s) end if self.data.has_key?('published') && self.data['published'] == false self.published = false else self.published = true end self.tags = self.data.pluralized_array("tag", "tags") if self.categories.empty? self.categories = self.data.pluralized_array('category', 'categories') end end # Spaceship is based on Post#date, slug # # Returns -1, 0, 1 def <=>(other) cmp = self.date <=> other.date if 0 == cmp cmp = self.slug <=> other.slug end return cmp end # Extract information from the post filename # +name+ is the String filename of the post file # # Returns nothing def process(name) m, cats, date, slug, ext = *name.match(MATCHER) self.date = Time.parse(date) self.slug = slug self.ext = ext rescue ArgumentError raise FatalException.new("Post #{name} does not have a valid date.") end # The generated directory into which the post will be placed # upon generation. This is derived from the permalink or, if # permalink is absent, set to the default date # e.g. "/2008/11/05/" if the permalink style is :date, otherwise nothing # # Returns def dir File.dirname(url) end # The full path and filename of the post. # Defined in the YAML of the post body # (Optional) # # Returns def permalink self.data && self.data['permalink'] end def template case self.site.permalink_style when :pretty "/:categories/:year/:month/:day/:title/" when :none "/:categories/:title.html" when :date "/:categories/:year/:month/:day/:title.html" else self.site.permalink_style.to_s end end # The generated relative url of this post # e.g. /2008/11/05/my-awesome-post.html # # Returns def url return @url if @url url = if permalink permalink else { "year" => date.strftime("%Y"), "month" => date.strftime("%m"), "day" => date.strftime("%d"), "title" => CGI.escape(slug), "i_day" => date.strftime("%d").to_i.to_s, "i_month" => date.strftime("%m").to_i.to_s, "categories" => categories.join('/'), "output_ext" => self.output_ext }.inject(template) { |result, token| result.gsub(/:#{Regexp.escape token.first}/, token.last) }.gsub(/\/\//, "/") end # sanitize url @url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/') @url += "/" if url =~ /\/$/ @url end # The UID for this post (useful in feeds) # e.g. /2008/11/05/my-awesome-post # # Returns def id File.join(self.dir, self.slug) end # Calculate related posts. # # Returns [] def related_posts(posts) return [] unless posts.size > 1 if self.site.lsi self.class.lsi ||= begin puts "Running the classifier... this could take a while." lsi = Classifier::LSI.new posts.each { |x| $stdout.print(".");$stdout.flush;lsi.add_item(x) } puts "" lsi end related = self.class.lsi.find_related(self.content, 11) related - [self] else (posts - [self])[0..9] end end # Add any necessary layouts to this post # +layouts+ is a Hash of {"name" => "layout"} # +site_payload+ is the site payload hash # # Returns nothing def render(layouts, site_payload) # construct payload payload = { "site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) }, "page" => self.to_liquid }.deep_merge(site_payload) do_layout(payload, layouts) end # Obtain destination path. # +dest+ is the String path to the destination dir # # Returns destination file path. def destination(dest) # The url needs to be unescaped in order to preserve the correct filename path = File.join(dest, CGI.unescape(self.url)) path = File.join(path, "index.html") if template[/\.html$/].nil? path end # Write the generated post file to the destination directory. # +dest+ is the String path to the destination dir # # Returns nothing def write(dest) path = destination(dest) FileUtils.mkdir_p(File.dirname(path)) File.open(path, 'w') do |f| f.write(self.output) end end # Convert this post into a Hash for use in Liquid templates. # # Returns def to_liquid self.data.deep_merge({ "title" => self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '), "url" => self.url, "date" => self.date, "id" => self.id, "categories" => self.categories, "next" => self.next, "previous" => self.previous, "tags" => self.tags, "content" => self.content }) end def inspect "" end def next pos = self.site.posts.index(self) if pos && pos < self.site.posts.length-1 self.site.posts[pos+1] else nil end end def previous pos = self.site.posts.index(self) if pos && pos > 0 self.site.posts[pos-1] else nil end end end end jekyll-0.11.2/lib/jekyll/plugin.rb0000644000175000017500000000366711752165402016623 0ustar uwabamiuwabamimodule Jekyll class Plugin PRIORITIES = { :lowest => -100, :low => -10, :normal => 0, :high => 10, :highest => 100 } # Install a hook so that subclasses are recorded. This method is only # ever called by Ruby itself. # # base - The Class subclass. # # Returns nothing. def self.inherited(base) subclasses << base subclasses.sort! end # The list of Classes that have been subclassed. # # Returns an Array of Class objects. def self.subclasses @subclasses ||= [] end # Get or set the priority of this plugin. When called without an # argument it returns the priority. When an argument is given, it will # set the priority. # # priority - The Symbol priority (default: nil). Valid options are: # :lowest, :low, :normal, :high, :highest # # Returns the Symbol priority. def self.priority(priority = nil) @priority ||= nil if priority && PRIORITIES.has_key?(priority) @priority = priority end @priority || :normal end # Get or set the safety of this plugin. When called without an argument # it returns the safety. When an argument is given, it will set the # safety. # # safe - The Boolean safety (default: nil). # # Returns the safety Boolean. def self.safe(safe = nil) if safe @safe = safe end @safe || false end # Spaceship is priority [higher -> lower] # # other - The class to be compared. # # Returns -1, 0, 1. def self.<=>(other) PRIORITIES[other.priority] <=> PRIORITIES[self.priority] end # Initialize a new plugin. This should be overridden by the subclass. # # config - The Hash of configuration options. # # Returns a new instance. def initialize(config = {}) # no-op for default end end end jekyll-0.11.2/lib/jekyll/page.rb0000644000175000017500000000756711752165402016244 0ustar uwabamiuwabamimodule Jekyll class Page include Convertible attr_writer :dir attr_accessor :site, :pager attr_accessor :name, :ext, :basename attr_accessor :data, :content, :output # Initialize a new Page. # # site - The Site object. # base - The String path to the source. # dir - The String path between the source and the file. # name - The String filename of the file. def initialize(site, base, dir, name) @site = site @base = base @dir = dir @name = name self.process(name) self.read_yaml(File.join(base, dir), name) end # The generated directory into which the page will be placed # upon generation. This is derived from the permalink or, if # permalink is absent, we be '/' # # Returns the String destination directory. def dir url[-1, 1] == '/' ? url : File.dirname(url) end # The full path and filename of the post. Defined in the YAML of the post # body. # # Returns the String permalink or nil if none has been set. def permalink self.data && self.data['permalink'] end # The template of the permalink. # # Returns the template String. def template if self.site.permalink_style == :pretty && !index? && html? "/:basename/" else "/:basename:output_ext" end end # The generated relative url of this page. e.g. /about.html. # # Returns the String url. def url return @url if @url url = if permalink permalink else { "basename" => self.basename, "output_ext" => self.output_ext, }.inject(template) { |result, token| result.gsub(/:#{token.first}/, token.last) }.gsub(/\/\//, "/") end # sanitize url @url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/') @url += "/" if url =~ /\/$/ @url end # Extract information from the page filename. # # name - The String filename of the page file. # # Returns nothing. def process(name) self.ext = File.extname(name) self.basename = name[0 .. -self.ext.length-1] end # Add any necessary layouts to this post # # layouts - The Hash of {"name" => "layout"}. # site_payload - The site payload Hash. # # Returns nothing. def render(layouts, site_payload) payload = { "page" => self.to_liquid, 'paginator' => pager.to_liquid }.deep_merge(site_payload) do_layout(payload, layouts) end # Convert this Page's data to a Hash suitable for use by Liquid. # # Returns the Hash representation of this Page. def to_liquid self.data.deep_merge({ "url" => File.join(@dir, self.url), "content" => self.content }) end # Obtain destination path. # # dest - The String path to the destination dir. # # Returns the destination file path String. def destination(dest) # The url needs to be unescaped in order to preserve the correct # filename. path = File.join(dest, @dir, CGI.unescape(self.url)) path = File.join(path, "index.html") if self.url =~ /\/$/ path end # Write the generated page file to the destination directory. # # dest - The String path to the destination dir. # # Returns nothing. def write(dest) path = destination(dest) FileUtils.mkdir_p(File.dirname(path)) File.open(path, 'w') do |f| f.write(self.output) end end # Returns the object as a debug String. def inspect "#" end # Returns the Boolean of whether this Page is HTML or not. def html? output_ext == '.html' end # Returns the Boolean of whether this Page is an index file or not. def index? basename == 'index' end end end jekyll-0.11.2/lib/jekyll/migrators/0000775000175000017500000000000011752165402016775 5ustar uwabamiuwabamijekyll-0.11.2/lib/jekyll/migrators/wordpressdotcom.rb0000644000175000017500000000371211752165402022561 0ustar uwabamiuwabami# coding: utf-8 require 'rubygems' require 'hpricot' require 'fileutils' require 'yaml' require 'time' module Jekyll # This importer takes a wordpress.xml file, which can be exported from your # wordpress.com blog (/wp-admin/export.php). module WordpressDotCom def self.process(filename = "wordpress.xml") import_count = Hash.new(0) doc = Hpricot::XML(File.read(filename)) (doc/:channel/:item).each do |item| title = item.at(:title).inner_text.strip permalink_title = item.at('wp:post_name').inner_text # Fallback to "prettified" title if post_name is empty (can happen) if permalink_title == "" permalink_title = title.downcase.split.join('-') end date = Time.parse(item.at('wp:post_date').inner_text) status = item.at('wp:status').inner_text if status == "publish" published = true else published = false end type = item.at('wp:post_type').inner_text tags = (item/:category).map{|c| c.inner_text}.reject{|c| c == 'Uncategorized'}.uniq metas = Hash.new item.search("wp:postmeta").each do |meta| key = meta.at('wp:meta_key').inner_text value = meta.at('wp:meta_value').inner_text metas[key] = value; end name = "#{date.strftime('%Y-%m-%d')}-#{permalink_title}.html" header = { 'layout' => type, 'title' => title, 'tags' => tags, 'status' => status, 'type' => type, 'published' => published, 'meta' => metas } FileUtils.mkdir_p "_#{type}s" File.open("_#{type}s/#{name}", "w") do |f| f.puts header.to_yaml f.puts '---' f.puts item.at('content:encoded').inner_text end import_count[type] += 1 end import_count.each do |key, value| puts "Imported #{value} #{key}s" end end end end jekyll-0.11.2/lib/jekyll/migrators/wordpress.rb0000644000175000017500000000425211752165402021353 0ustar uwabamiuwabamirequire 'rubygems' require 'sequel' require 'fileutils' require 'yaml' # NOTE: This converter requires Sequel and the MySQL gems. # The MySQL gem can be difficult to install on OS X. Once you have MySQL # installed, running the following commands should work: # $ sudo gem install sequel # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config module Jekyll module WordPress def self.process(dbname, user, pass, host = 'localhost', table_prefix = 'wp_') db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8') FileUtils.mkdir_p("_posts") # Reads a MySQL database via Sequel and creates a post file for each # post in wp_posts that has post_status = 'publish'. This restriction is # made because 'draft' posts are not guaranteed to have valid dates. query = "SELECT post_title, \ post_name, \ post_date, \ post_content, \ post_excerpt, \ ID, \ guid \ FROM #{table_prefix}posts \ WHERE post_status = 'publish' AND \ post_type = 'post'" db[query].each do |post| # Get required fields and construct Jekyll compatible name. title = post[:post_title] slug = post[:post_name] date = post[:post_date] content = post[:post_content] name = "%02d-%02d-%02d-%s.markdown" % [date.year, date.month, date.day, slug] # Get the relevant fields as a hash, delete empty fields and convert # to YAML for the header. data = { 'layout' => 'post', 'title' => title.to_s, 'excerpt' => post[:post_excerpt].to_s, 'wordpress_id' => post[:ID], 'wordpress_url' => post[:guid], 'date' => date }.delete_if { |k,v| v.nil? || v == '' }.to_yaml # Write out the data and content to file File.open("_posts/#{name}", "w") do |f| f.puts data f.puts "---" f.puts content end end end end end jekyll-0.11.2/lib/jekyll/migrators/typo.rb0000644000175000017500000000310511752165402020312 0ustar uwabamiuwabami# Author: Toby DiPasquale require 'fileutils' require 'rubygems' require 'sequel' require 'yaml' module Jekyll module Typo # This SQL *should* work for both MySQL and PostgreSQL, but I haven't # tested PostgreSQL yet (as of 2008-12-16). SQL = <<-EOS SELECT c.id id, c.title title, c.permalink slug, c.body body, c.published_at date, c.state state, COALESCE(tf.name, 'html') filter FROM contents c LEFT OUTER JOIN text_filters tf ON c.text_filter_id = tf.id EOS def self.process dbname, user, pass, host='localhost' FileUtils.mkdir_p '_posts' db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8') db[SQL].each do |post| next unless post[:state] =~ /published/ name = [ sprintf("%.04d", post[:date].year), sprintf("%.02d", post[:date].month), sprintf("%.02d", post[:date].day), post[:slug].strip ].join('-') # Can have more than one text filter in this field, but we just want # the first one for this. name += '.' + post[:filter].split(' ')[0] File.open("_posts/#{name}", 'w') do |f| f.puts({ 'layout' => 'post', 'title' => post[:title].to_s, 'typo_id' => post[:id] }.delete_if { |k, v| v.nil? || v == '' }.to_yaml) f.puts '---' f.puts post[:body].delete("\r") end end end end end jekyll-0.11.2/lib/jekyll/migrators/tumblr.rb0000644000175000017500000001036011752165402020625 0ustar uwabamiuwabamirequire 'rubygems' require 'nokogiri' require 'open-uri' require 'fileutils' require 'CGI' require 'iconv' require 'date' module Jekyll module Tumblr def self.process(url, grab_images = false) current_page = 0 while true f = open(url + "/api/read?num=50&start=#{current_page * 50}") doc = Nokogiri::HTML(Iconv.conv("utf-8", f.charset, f.readlines.join("\n"))) puts "Page: #{current_page + 1} - Posts: #{(doc/:tumblr/:posts/:post).size}" FileUtils.mkdir_p "_posts/tumblr" (doc/:tumblr/:posts/:post).each do |post| title = "" content = nil name = nil if post['type'] == "regular" title_element = post.at("regular-title") title = title_element.inner_text unless title_element == nil content = CGI::unescapeHTML post.at("regular-body").inner_html unless post.at("regular-body") == nil elsif post['type'] == "link" title = post.at("link-text").inner_html unless post.at("link-text") == nil if post.at("link-text") != nil content = "#{post.at("link-text").inner_html}" else content = "#{post.at("link-url").inner_html}" end content << "
" + CGI::unescapeHTML(post.at("link-description").inner_html) unless post.at("link-description") == nil elsif post['type'] == "photo" content = "" if post.at("photo-link-url") != nil content = "" else content = "" end if post.at("photo-caption") != nil content << "
" unless content == nil content << CGI::unescapeHTML(post.at("photo-caption").inner_html) end elsif post['type'] == "audio" content = CGI::unescapeHTML(post.at("audio-player").inner_html) content << CGI::unescapeHTML(post.at("audio-caption").inner_html) unless post.at("audio-caption") == nil elsif post['type'] == "quote" content = "
" + CGI::unescapeHTML(post.at("quote-text").inner_html) + "
" content << "—" + CGI::unescapeHTML(post.at("quote-source").inner_html) unless post.at("quote-source") == nil elsif post['type'] == "conversation" title = post.at("conversation-title").inner_html unless post.at("conversation-title") == nil content = "
" (post/:conversation/:line).each do |line| content << "
" + line['label'] + "
" + line.inner_html + "
" unless line['label'] == nil || line == nil end content << "
" elsif post['type'] == "video" title = post.at("video-title").inner_html unless post.at("video-title") == nil content = CGI::unescapeHTML(post.at("video-player").inner_html) content << CGI::unescapeHTML(post.at("video-caption").inner_html) unless post.at("video-caption") == nil end # End post types name = "#{Date.parse(post['date']).to_s}-#{post['id'].downcase.gsub(/[^a-z0-9]/, '-')}.html" if title != nil || content != nil && name != nil File.open("_posts/tumblr/#{name}", "w") do |f| f.puts <<-HEADER --- layout: post title: #{title} --- HEADER f.puts content end # End file end end # End post XML if (doc/:tumblr/:posts/:post).size < 50 break else current_page = current_page + 1 end end # End while loop end # End method private def self.save_file(url, grab_image = false) unless grab_image == false FileUtils.mkdir_p "tumblr_files" File.open("tumblr_files/#{url.split('/').last}", "w") do |f| f.write(open(url).read) end return "/tumblr_files/#{url.split('/').last}" else return url end end end end jekyll-0.11.2/lib/jekyll/migrators/textpattern.rb0000644000175000017500000000356411752165402021712 0ustar uwabamiuwabamirequire 'rubygems' require 'sequel' require 'fileutils' # NOTE: This converter requires Sequel and the MySQL gems. # The MySQL gem can be difficult to install on OS X. Once you have MySQL # installed, running the following commands should work: # $ sudo gem install sequel # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config module Jekyll module TextPattern # Reads a MySQL database via Sequel and creates a post file for each post. # The only posts selected are those with a status of 4 or 5, which means # "live" and "sticky" respectively. # Other statuses are 1 => draft, 2 => hidden and 3 => pending. QUERY = "SELECT Title, \ url_title, \ Posted, \ Body, \ Keywords \ FROM textpattern \ WHERE Status = '4' OR \ Status = '5'" def self.process(dbname, user, pass, host = 'localhost') db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8') FileUtils.mkdir_p "_posts" db[QUERY].each do |post| # Get required fields and construct Jekyll compatible name. title = post[:Title] slug = post[:url_title] date = post[:Posted] content = post[:Body] name = [date.strftime("%Y-%m-%d"), slug].join('-') + ".textile" # Get the relevant fields as a hash, delete empty fields and convert # to YAML for the header. data = { 'layout' => 'post', 'title' => title.to_s, 'tags' => post[:Keywords].split(',') }.delete_if { |k,v| v.nil? || v == ''}.to_yaml # Write out the data and content to file. File.open("_posts/#{name}", "w") do |f| f.puts data f.puts "---" f.puts content end end end end end jekyll-0.11.2/lib/jekyll/migrators/posterous.rb0000644000175000017500000000420111752165402021360 0ustar uwabamiuwabamirequire 'rubygems' require 'jekyll' require 'fileutils' require 'net/http' require 'uri' require "json" # ruby -r './lib/jekyll/migrators/posterous.rb' -e 'Jekyll::Posterous.process(email, pass, blog)' module Jekyll module Posterous def self.fetch(uri_str, limit = 10) # You should choose better exception. raise ArgumentError, 'Stuck in a redirect loop. Please double check your email and password' if limit == 0 response = nil Net::HTTP.start('posterous.com') do |http| req = Net::HTTP::Get.new(uri_str) req.basic_auth @email, @pass response = http.request(req) end case response when Net::HTTPSuccess then response when Net::HTTPRedirection then fetch(response['location'], limit - 1) else response.error! end end def self.process(email, pass, blog = 'primary') @email, @pass = email, pass @api_token = JSON.parse(self.fetch("/api/2/auth/token").body)['api_token'] FileUtils.mkdir_p "_posts" posts = JSON.parse(self.fetch("/api/v2/users/me/sites/#{blog}/posts?api_token=#{@api_token}").body) page = 1 while posts.any? posts.each do |post| title = post["title"] slug = title.gsub(/[^[:alnum:]]+/, '-').downcase date = Date.parse(post["display_date"]) content = post["body_html"] published = !post["is_private"] name = "%02d-%02d-%02d-%s.html" % [date.year, date.month, date.day, slug] # Get the relevant fields as a hash, delete empty fields and convert # to YAML for the header data = { 'layout' => 'post', 'title' => title.to_s, 'published' => published }.delete_if { |k,v| v.nil? || v == ''}.to_yaml # Write out the data and content to file File.open("_posts/#{name}", "w") do |f| f.puts data f.puts "---" f.puts content end end page += 1 posts = JSON.parse(self.fetch("/api/v2/users/me/sites/#{blog}/posts?api_token=#{@api_token}&page=#{page}").body) end end end end jekyll-0.11.2/lib/jekyll/migrators/mt.rb0000644000175000017500000000600011752165402017734 0ustar uwabamiuwabami# Created by Nick Gerakines, open source and publically available under the # MIT license. Use this module at your own risk. # I'm an Erlang/Perl/C++ guy so please forgive my dirty ruby. require 'rubygems' require 'sequel' require 'fileutils' require 'yaml' # NOTE: This converter requires Sequel and the MySQL gems. # The MySQL gem can be difficult to install on OS X. Once you have MySQL # installed, running the following commands should work: # $ sudo gem install sequel # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config module Jekyll module MT # This query will pull blog posts from all entries across all blogs. If # you've got unpublished, deleted or otherwise hidden posts please sift # through the created posts to make sure nothing is accidently published. QUERY = "SELECT entry_id, \ entry_basename, \ entry_text, \ entry_text_more, \ entry_authored_on, \ entry_title, \ entry_convert_breaks \ FROM mt_entry" def self.process(dbname, user, pass, host = 'localhost') db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8') FileUtils.mkdir_p "_posts" db[QUERY].each do |post| title = post[:entry_title] slug = post[:entry_basename].gsub(/_/, '-') date = post[:entry_authored_on] content = post[:entry_text] more_content = post[:entry_text_more] entry_convert_breaks = post[:entry_convert_breaks] # Be sure to include the body and extended body. if more_content != nil content = content + " \n" + more_content end # Ideally, this script would determine the post format (markdown, # html, etc) and create files with proper extensions. At this point # it just assumes that markdown will be acceptable. name = [date.year, date.month, date.day, slug].join('-') + '.' + self.suffix(entry_convert_breaks) data = { 'layout' => 'post', 'title' => title.to_s, 'mt_id' => post[:entry_id], 'date' => date }.delete_if { |k,v| v.nil? || v == '' }.to_yaml File.open("_posts/#{name}", "w") do |f| f.puts data f.puts "---" f.puts content end end end def self.suffix(entry_type) if entry_type.nil? || entry_type.include?("markdown") # The markdown plugin I have saves this as # "markdown_with_smarty_pants", so I just look for "markdown". "markdown" elsif entry_type.include?("textile") # This is saved as "textile_2" on my installation of MT 5.1. "textile" elsif entry_type == "0" || entry_type.include?("richtext") # Richtext looks to me like it's saved as HTML, so I include it here. "html" else # Other values might need custom work. entry_type end end end end jekyll-0.11.2/lib/jekyll/migrators/mephisto.rb0000644000175000017500000000554711752165402021163 0ustar uwabamiuwabami# Quickly hacked together my Michael Ivey # Based on mt.rb by Nick Gerakines, open source and publically # available under the MIT license. Use this module at your own risk. require 'rubygems' require 'sequel' require 'fastercsv' require 'fileutils' require File.join(File.dirname(__FILE__),"csv.rb") # NOTE: This converter requires Sequel and the MySQL gems. # The MySQL gem can be difficult to install on OS X. Once you have MySQL # installed, running the following commands should work: # $ sudo gem install sequel # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config module Jekyll module Mephisto #Accepts a hash with database config variables, exports mephisto posts into a csv #export PGPASSWORD if you must def self.postgres(c) sql = <<-SQL BEGIN; CREATE TEMP TABLE jekyll AS SELECT title, permalink, body, published_at, filter FROM contents WHERE user_id = 1 AND type = 'Article' ORDER BY published_at; COPY jekyll TO STDOUT WITH CSV HEADER; ROLLBACK; SQL command = %Q(psql -h #{c[:host] || "localhost"} -c "#{sql.strip}" #{c[:database]} #{c[:username]} -o #{c[:filename] || "posts.csv"}) puts command `#{command}` CSV.process end # This query will pull blog posts from all entries across all blogs. If # you've got unpublished, deleted or otherwise hidden posts please sift # through the created posts to make sure nothing is accidently published. QUERY = "SELECT id, \ permalink, \ body, \ published_at, \ title \ FROM contents \ WHERE user_id = 1 AND \ type = 'Article' AND \ published_at IS NOT NULL \ ORDER BY published_at" def self.process(dbname, user, pass, host = 'localhost') db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8') FileUtils.mkdir_p "_posts" db[QUERY].each do |post| title = post[:title] slug = post[:permalink] date = post[:published_at] content = post[:body] # Ideally, this script would determine the post format (markdown, # html, etc) and create files with proper extensions. At this point # it just assumes that markdown will be acceptable. name = [date.year, date.month, date.day, slug].join('-') + ".markdown" data = { 'layout' => 'post', 'title' => title.to_s, 'mt_id' => post[:entry_id], }.delete_if { |k,v| v.nil? || v == ''}.to_yaml File.open("_posts/#{name}", "w") do |f| f.puts data f.puts "---" f.puts content end end end end end jekyll-0.11.2/lib/jekyll/migrators/marley.rb0000644000175000017500000000341211752165402020611 0ustar uwabamiuwabamirequire 'yaml' require 'fileutils' module Jekyll module Marley def self.regexp { :id => /^\d{0,4}-{0,1}(.*)$/, :title => /^#\s*(.*)\s+$/, :title_with_date => /^#\s*(.*)\s+\(([0-9\/]+)\)$/, :published_on => /.*\s+\(([0-9\/]+)\)$/, :perex => /^([^\#\n]+\n)$/, :meta => /^\{\{\n(.*)\}\}\n$/mi # Multiline Regexp } end def self.process(marley_data_dir) raise ArgumentError, "marley dir #{marley_data_dir} not found" unless File.directory?(marley_data_dir) FileUtils.mkdir_p "_posts" posts = 0 Dir["#{marley_data_dir}/**/*.txt"].each do |f| next unless File.exists?(f) #copied over from marley's app/lib/post.rb file_content = File.read(f) meta_content = file_content.slice!( self.regexp[:meta] ) body = file_content.sub( self.regexp[:title], '').sub( self.regexp[:perex], '').strip title = file_content.scan( self.regexp[:title] ).first.to_s.strip prerex = file_content.scan( self.regexp[:perex] ).first.to_s.strip published_on = DateTime.parse( post[:published_on] ) rescue File.mtime( File.dirname(f) ) meta = ( meta_content ) ? YAML::load( meta_content.scan( self.regexp[:meta]).to_s ) : {} meta['title'] = title meta['layout'] = 'post' formatted_date = published_on.strftime('%Y-%m-%d') post_name = File.dirname(f).split(%r{/}).last.gsub(/\A\d+-/, '') name = "#{formatted_date}-#{post_name}" File.open("_posts/#{name}.markdown", "w") do |f| f.puts meta.to_yaml f.puts "---\n" f.puts "\n#{prerex}\n\n" if prerex f.puts body end posts += 1 end "Created #{posts} posts!" end end end jekyll-0.11.2/lib/jekyll/migrators/enki.rb0000644000175000017500000000270011752165402020245 0ustar uwabamiuwabami# Adapted by Rodrigo Pinto # Based on typo.rb by Toby DiPasquale require 'fileutils' require 'rubygems' require 'sequel' module Jekyll module Enki SQL = <<-EOS SELECT p.id, p.title, p.slug, p.body, p.published_at as date, p.cached_tag_list as tags FROM posts p EOS # Just working with postgres, but can be easily adapted # to work with both mysql and postgres. def self.process(dbname, user, pass, host = 'localhost') FileUtils.mkdir_p('_posts') db = Sequel.postgres(:database => dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8') db[SQL].each do |post| name = [ sprintf("%.04d", post[:date].year), sprintf("%.02d", post[:date].month), sprintf("%.02d", post[:date].day), post[:slug].strip ].join('-') name += '.textile' File.open("_posts/#{name}", 'w') do |f| f.puts({ 'layout' => 'post', 'title' => post[:title].to_s, 'enki_id' => post[:id], 'categories' => post[:tags] }.delete_if { |k, v| v.nil? || v == '' }.to_yaml) f.puts '---' f.puts post[:body].delete("\r") end end end end end jekyll-0.11.2/lib/jekyll/migrators/drupal.rb0000644000175000017500000000623111752165402020611 0ustar uwabamiuwabamirequire 'rubygems' require 'sequel' require 'fileutils' require 'yaml' # NOTE: This converter requires Sequel and the MySQL gems. # The MySQL gem can be difficult to install on OS X. Once you have MySQL # installed, running the following commands should work: # $ sudo gem install sequel # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config module Jekyll module Drupal # Reads a MySQL database via Sequel and creates a post file for each post # in wp_posts that has post_status = 'publish'. This restriction is made # because 'draft' posts are not guaranteed to have valid dates. 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" def self.process(dbname, user, pass, host = 'localhost') db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8') FileUtils.mkdir_p "_posts" FileUtils.mkdir_p "_drafts" # Create the refresh layout # Change the refresh url if you customized your permalink config File.open("_layouts/refresh.html", "w") do |f| f.puts < EOF end db[QUERY].each do |post| # Get required fields and construct Jekyll compatible name node_id = post[:nid] title = post[:title] content = post[:body] created = post[:created] time = Time.at(created) is_published = post[:status] == 1 dir = is_published ? "_posts" : "_drafts" slug = title.strip.downcase.gsub(/(&|&)/, ' and ').gsub(/[\s\.\/\\]/, '-').gsub(/[^\w-]/, '').gsub(/[-_]{2,}/, '-').gsub(/^[-_]/, '').gsub(/[-_]$/, '') name = time.strftime("%Y-%m-%d-") + slug + '.md' # Get the relevant fields as a hash, delete empty fields and convert # to YAML for the header data = { 'layout' => 'post', 'title' => title.to_s, 'created' => created, }.delete_if { |k,v| v.nil? || v == ''}.to_yaml # Write out the data and content to file File.open("#{dir}/#{name}", "w") do |f| f.puts data f.puts "---" f.puts content end # Make a file to redirect from the old Drupal URL if is_published FileUtils.mkdir_p "node/#{node_id}" File.open("node/#{node_id}/index.md", "w") do |f| f.puts "---" f.puts "layout: refresh" f.puts "refresh_to_post_id: /#{time.strftime("%Y/%m/%d/") + slug}" f.puts "---" end end end # TODO: Make dirs & files for nodes of type 'page' # Make refresh pages for these as well # TODO: Make refresh dirs & files according to entries in url_alias table end end end jekyll-0.11.2/lib/jekyll/migrators/csv.rb0000644000175000017500000000122311752165402020111 0ustar uwabamiuwabamimodule Jekyll module CSV # Reads a csv with title, permalink, body, published_at, and filter. # It creates a post file for each row in the csv def self.process(file = "posts.csv") FileUtils.mkdir_p "_posts" posts = 0 FasterCSV.foreach(file) do |row| next if row[0] == "title" posts += 1 name = row[3].split(" ")[0]+"-"+row[1]+(row[4] =~ /markdown/ ? ".markdown" : ".textile") File.open("_posts/#{name}", "w") do |f| f.puts <<-HEADER --- layout: post title: #{row[0]} --- HEADER f.puts row[2] end end "Created #{posts} posts!" end end end jekyll-0.11.2/lib/jekyll/layout.rb0000644000175000017500000000157711752165402016640 0ustar uwabamiuwabamimodule Jekyll class Layout include Convertible # Gets the Site object. attr_reader :site # Gets/Sets the extension of this layout. attr_accessor :ext # Gets/Sets the Hash that holds the metadata for this layout. attr_accessor :data # Gets/Sets the content of this layout. attr_accessor :content # Initialize a new Layout. # # site - The Site. # base - The String path to the source. # name - The String filename of the post file. def initialize(site, base, name) @site = site @base = base @name = name self.data = {} self.process(name) self.read_yaml(base, name) end # Extract information from the layout filename. # # name - The String filename of the layout file. # # Returns nothing. def process(name) self.ext = File.extname(name) end end end jekyll-0.11.2/lib/jekyll/generators/0000775000175000017500000000000011752165402017137 5ustar uwabamiuwabamijekyll-0.11.2/lib/jekyll/generators/pagination.rb0000644000175000017500000000715311752165402021621 0ustar uwabamiuwabamimodule Jekyll class Pagination < Generator # This generator is safe from arbitrary code execution. safe true # Generate paginated pages if necessary. # # site - The Site. # # Returns nothing. def generate(site) site.pages.dup.each do |page| paginate(site, page) if Pager.pagination_enabled?(site.config, page.name) end end # Paginates the blog's posts. Renders the index.html file into paginated # directories, e.g.: page2/index.html, page3/index.html, etc and adds more # site-wide data. # # site - The Site. # page - The index.html Page that requires pagination. # # {"paginator" => { "page" => , # "per_page" => , # "posts" => [], # "total_posts" => , # "total_pages" => , # "previous_page" => , # "next_page" => }} def paginate(site, page) all_posts = site.site_payload['site']['posts'] pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i) (1..pages).each do |num_page| pager = Pager.new(site.config, num_page, all_posts, pages) if num_page > 1 newpage = Page.new(site, site.source, page.dir, page.name) newpage.pager = pager newpage.dir = File.join(page.dir, "page#{num_page}") site.pages << newpage else page.pager = pager end end end end class Pager attr_reader :page, :per_page, :posts, :total_posts, :total_pages, :previous_page, :next_page # Calculate the number of pages. # # all_posts - The Array of all Posts. # per_page - The Integer of entries per page. # # Returns the Integer number of pages. def self.calculate_pages(all_posts, per_page) (all_posts.size.to_f / per_page.to_i).ceil end # Determine if pagination is enabled for a given file. # # config - The configuration Hash. # file - The String filename of the file. # # Returns true if pagination is enabled, false otherwise. def self.pagination_enabled?(config, file) file == 'index.html' && !config['paginate'].nil? end # Initialize a new Pager. # # config - The Hash configuration of the site. # page - The Integer page number. # all_posts - The Array of all the site's Posts. # num_pages - The Integer number of pages or nil if you'd like the number # of pages calculated. def initialize(config, page, all_posts, num_pages = nil) @page = page @per_page = config['paginate'].to_i @total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page) if @page > @total_pages raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}" end init = (@page - 1) * @per_page offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1) @total_posts = all_posts.size @posts = all_posts[init..offset] @previous_page = @page != 1 ? @page - 1 : nil @next_page = @page != @total_pages ? @page + 1 : nil end # Convert this Pager's data to a Hash suitable for use by Liquid. # # Returns the Hash representation of this Pager. def to_liquid { 'page' => page, 'per_page' => per_page, 'posts' => posts, 'total_posts' => total_posts, 'total_pages' => total_pages, 'previous_page' => previous_page, 'next_page' => next_page } end end end jekyll-0.11.2/lib/jekyll/generator.rb0000644000175000017500000000006511752165402017300 0ustar uwabamiuwabamimodule Jekyll class Generator < Plugin end endjekyll-0.11.2/lib/jekyll/filters.rb0000644000175000017500000000526011752165402016764 0ustar uwabamiuwabamirequire 'uri' module Jekyll module Filters # Convert a Textile string into HTML output. # # input - The Textile String to convert. # # Returns the HTML formatted String. def textilize(input) site = @context.registers[:site] converter = site.getConverterImpl(Jekyll::TextileConverter) converter.convert(input) end # Convert a Markdown string into HTML output. # # input - The Markdown String to convert. # # Returns the HTML formatted String. def markdownify(input) site = @context.registers[:site] converter = site.getConverterImpl(Jekyll::MarkdownConverter) converter.convert(input) end # Format a date in short format e.g. "27 Jan 2011". # # date - the Time to format. # # Returns the formatting String. def date_to_string(date) date.strftime("%d %b %Y") end # Format a date in long format e.g. "27 January 2011". # # date - The Time to format. # # Returns the formatted String. def date_to_long_string(date) date.strftime("%d %B %Y") end # Format a date for use in XML. # # date - The Time to format. # # Examples # # date_to_xmlschema(Time.now) # # => "2011-04-24T20:34:46+08:00" # # Returns the formatted String. def date_to_xmlschema(date) date.xmlschema end def xml_escape(input) CGI.escapeHTML(input) end # CGI escape a string for use in a URL. Replaces any special characters # with appropriate %XX replacements. # # input - The String to escape. # # Examples # # cgi_escape('foo,bar;baz?') # # => "foo%2Cbar%3Bbaz%3F" # # Returns the escaped String. def cgi_escape(input) CGI::escape(input) end def uri_escape(input) URI.escape(input) end # Count the number of words in the input string. # # input - The String on which to operate. # # Returns the Integer word count. def number_of_words(input) input.split.length end # Join an array of things into a string by separating with commes and the # word "and" for the last one. # # array - The Array of Strings to join. # # Examples # # array_to_sentence_string(["apples", "oranges", "grapes"]) # # => "apples, oranges, and grapes" # # Returns the formatted String. def array_to_sentence_string(array) connector = "and" case array.length when 0 "" when 1 array[0].to_s when 2 "#{array[0]} #{connector} #{array[1]}" else "#{array[0...-1].join(', ')}, #{connector} #{array[-1]}" end end end end jekyll-0.11.2/lib/jekyll/errors.rb0000644000175000017500000000010011752165402016614 0ustar uwabamiuwabamimodule Jekyll class FatalException < StandardError end endjekyll-0.11.2/lib/jekyll/core_ext.rb0000644000175000017500000000242111752165402017120 0ustar uwabamiuwabamiclass Hash # Merges self with another hash, recursively. # # This code was lovingly stolen from some random gem: # http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html # # Thanks to whoever made it. def deep_merge(hash) target = dup hash.keys.each do |key| if hash[key].is_a? Hash and self[key].is_a? Hash target[key] = target[key].deep_merge(hash[key]) next end target[key] = hash[key] end target end # Read array from the supplied hash favouring the singular key # and then the plural key, and handling any nil entries. # +hash+ the hash to read from # +singular_key+ the singular key # +plural_key+ the singular key # # Returns an array def pluralized_array(singular_key, plural_key) hash = self if hash.has_key?(singular_key) array = [hash[singular_key]] if hash[singular_key] elsif hash.has_key?(plural_key) case hash[plural_key] when String array = hash[plural_key].split when Array array = hash[plural_key].compact end end array || [] end end # Thanks, ActiveSupport! class Date # Converts datetime to an appropriate format for use in XML def xmlschema strftime("%Y-%m-%dT%H:%M:%S%Z") end if RUBY_VERSION < '1.9' end jekyll-0.11.2/lib/jekyll/convertible.rb0000644000175000017500000000570211752165402017631 0ustar uwabamiuwabamirequire 'set' # Convertible provides methods for converting a pagelike item # from a certain type of markup into actual content # # Requires # self.site -> Jekyll::Site # self.content # self.content= # self.data= # self.ext= # self.output= module Jekyll module Convertible # Returns the contents as a String. def to_s self.content || '' end # Read the YAML frontmatter. # # base - The String path to the dir containing the file. # name - The String filename of the file. # # Returns nothing. def read_yaml(base, name) self.content = File.read(File.join(base, name)) if self.content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m self.content = $POSTMATCH begin self.data = YAML.load($1) rescue => e puts "YAML Exception reading #{name}: #{e.message}" end end self.data ||= {} end # Transform the contents based on the content type. # # Returns nothing. def transform self.content = converter.convert(self.content) end # Determine the extension depending on content_type. # # Returns the String extension for the output file. # e.g. ".html" for an HTML output file. def output_ext converter.output_ext(self.ext) end # Determine which converter to use based on this convertible's # extension. # # Returns the Converter instance. def converter @converter ||= self.site.converters.find { |c| c.matches(self.ext) } end # Add any necessary layouts to this convertible document. # # payload - The site payload Hash. # layouts - A Hash of {"name" => "layout"}. # # Returns nothing. def do_layout(payload, layouts) info = { :filters => [Jekyll::Filters], :registers => { :site => self.site } } # render and transform content (this becomes the final content of the object) payload["pygments_prefix"] = converter.pygments_prefix payload["pygments_suffix"] = converter.pygments_suffix begin self.content = Liquid::Template.parse(self.content).render(payload, info) rescue => e puts "Liquid Exception: #{e.message} in #{self.name}" end self.transform # output keeps track of what will finally be written self.output = self.content # recursively render layouts layout = layouts[self.data["layout"]] used = Set.new([layout]) while layout payload = payload.deep_merge({"content" => self.output, "page" => layout.data}) begin self.output = Liquid::Template.parse(layout.content).render(payload, info) rescue => e puts "Liquid Exception: #{e.message} in #{self.data["layout"]}" end if layout = layouts[layout.data["layout"]] if used.include?(layout) layout = nil # avoid recursive chain else used << layout end end end end end end jekyll-0.11.2/lib/jekyll/converters/0000775000175000017500000000000011752165402017160 5ustar uwabamiuwabamijekyll-0.11.2/lib/jekyll/converters/textile.rb0000644000175000017500000000132211752165402021157 0ustar uwabamiuwabamimodule Jekyll class TextileConverter < Converter safe true pygments_prefix '' pygments_suffix '' def setup return if @setup require 'redcloth' @setup = true rescue LoadError STDERR.puts 'You are missing a library required for Textile. Please run:' STDERR.puts ' $ [sudo] gem install RedCloth' raise FatalException.new("Missing dependency: RedCloth") end def matches(ext) rgx = '(' + @config['textile_ext'].gsub(',','|') +')' ext =~ Regexp.new(rgx, Regexp::IGNORECASE) end def output_ext(ext) ".html" end def convert(content) setup RedCloth.new(content).to_html end end end jekyll-0.11.2/lib/jekyll/converters/markdown.rb0000644000175000017500000001161311752165402021327 0ustar uwabamiuwabamimodule Jekyll class MarkdownConverter < Converter safe true pygments_prefix "\n" pygments_suffix "\n" def setup return if @setup # Set the Markdown interpreter (and Maruku self.config, if necessary) case @config['markdown'] when 'redcarpet' begin require 'redcarpet' @redcarpet_extensions = @config['redcarpet']['extensions'].map { |e| e.to_sym } rescue LoadError STDERR.puts 'You are missing a library required for Markdown. Please run:' STDERR.puts ' $ [sudo] gem install redcarpet' raise FatalException.new("Missing dependency: redcarpet") end when 'kramdown' begin require 'kramdown' rescue LoadError STDERR.puts 'You are missing a library required for Markdown. Please run:' STDERR.puts ' $ [sudo] gem install kramdown' raise FatalException.new("Missing dependency: kramdown") end when 'rdiscount' begin require 'rdiscount' # Load rdiscount extensions @rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym } rescue LoadError STDERR.puts 'You are missing a library required for Markdown. Please run:' STDERR.puts ' $ [sudo] gem install rdiscount' raise FatalException.new("Missing dependency: rdiscount") end when 'maruku' begin require 'maruku' if @config['maruku']['use_divs'] require 'maruku/ext/div' STDERR.puts 'Maruku: Using extended syntax for div elements.' end if @config['maruku']['use_tex'] require 'maruku/ext/math' STDERR.puts "Maruku: Using LaTeX extension. Images in `#{@config['maruku']['png_dir']}`." # Switch off MathML output MaRuKu::Globals[:html_math_output_mathml] = false MaRuKu::Globals[:html_math_engine] = 'none' # Turn on math to PNG support with blahtex # Resulting PNGs stored in `images/latex` MaRuKu::Globals[:html_math_output_png] = true MaRuKu::Globals[:html_png_engine] = @config['maruku']['png_engine'] MaRuKu::Globals[:html_png_dir] = @config['maruku']['png_dir'] MaRuKu::Globals[:html_png_url] = @config['maruku']['png_url'] end rescue LoadError STDERR.puts 'You are missing a library required for Markdown. Please run:' STDERR.puts ' $ [sudo] gem install maruku' raise FatalException.new("Missing dependency: maruku") end else STDERR.puts "Invalid Markdown processor: #{@config['markdown']}" STDERR.puts " Valid options are [ maruku | rdiscount | kramdown ]" raise FatalException.new("Invalid Markdown process: #{@config['markdown']}") end @setup = true end def matches(ext) rgx = '(' + @config['markdown_ext'].gsub(',','|') +')' ext =~ Regexp.new(rgx, Regexp::IGNORECASE) end def output_ext(ext) ".html" end def convert(content) setup case @config['markdown'] when 'redcarpet' Redcarpet.new(content, *@redcarpet_extensions).to_html when 'kramdown' # Check for use of coderay if @config['kramdown']['use_coderay'] Kramdown::Document.new(content, { :auto_ids => @config['kramdown']['auto_ids'], :footnote_nr => @config['kramdown']['footnote_nr'], :entity_output => @config['kramdown']['entity_output'], :toc_levels => @config['kramdown']['toc_levels'], :coderay_wrap => @config['kramdown']['coderay']['coderay_wrap'], :coderay_line_numbers => @config['kramdown']['coderay']['coderay_line_numbers'], :coderay_line_number_start => @config['kramdown']['coderay']['coderay_line_number_start'], :coderay_tab_width => @config['kramdown']['coderay']['coderay_tab_width'], :coderay_bold_every => @config['kramdown']['coderay']['coderay_bold_every'], :coderay_css => @config['kramdown']['coderay']['coderay_css'] }).to_html else # not using coderay Kramdown::Document.new(content, { :auto_ids => @config['kramdown']['auto_ids'], :footnote_nr => @config['kramdown']['footnote_nr'], :entity_output => @config['kramdown']['entity_output'], :toc_levels => @config['kramdown']['toc_levels'] }).to_html end when 'rdiscount' RDiscount.new(content, *@rdiscount_extensions).to_html when 'maruku' Maruku.new(content).to_html end end end end jekyll-0.11.2/lib/jekyll/converters/identity.rb0000644000175000017500000000035111752165402021333 0ustar uwabamiuwabamimodule Jekyll class IdentityConverter < Converter safe true priority :lowest def matches(ext) true end def output_ext(ext) ext end def convert(content) content end end end jekyll-0.11.2/lib/jekyll/converter.rb0000644000175000017500000000244511752165402017325 0ustar uwabamiuwabamimodule Jekyll class Converter < Plugin # Public: Get or set the pygments prefix. When an argument is specified, # the prefix will be set. If no argument is specified, the current prefix # will be returned. # # pygments_prefix - The String prefix (default: nil). # # Returns the String prefix. def self.pygments_prefix(pygments_prefix = nil) @pygments_prefix = pygments_prefix if pygments_prefix @pygments_prefix end # Public: Get or set the pygments suffix. When an argument is specified, # the suffix will be set. If no argument is specified, the current suffix # will be returned. # # pygments_suffix - The String suffix (default: nil). # # Returns the String suffix. def self.pygments_suffix(pygments_suffix = nil) @pygments_suffix = pygments_suffix if pygments_suffix @pygments_suffix end # Initialize the converter. # # Returns an initialized Converter. def initialize(config = {}) @config = config end # Get the pygments prefix. # # Returns the String prefix. def pygments_prefix self.class.pygments_prefix end # Get the pygments suffix. # # Returns the String suffix. def pygments_suffix self.class.pygments_suffix end end endjekyll-0.11.2/lib/jekyll.rb0000644000175000017500000000711311752165402015313 0ustar uwabamiuwabami$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed # Require all of the Ruby files in the given directory. # # path - The String relative path from here to the directory. # # Returns nothing. def require_all(path) glob = File.join(File.dirname(__FILE__), path, '*.rb') Dir[glob].each do |f| require f end end # rubygems require 'rubygems' # stdlib require 'fileutils' require 'time' require 'yaml' require 'English' # 3rd party require 'liquid' require 'maruku' require 'albino' # internal requires require 'jekyll/core_ext' require 'jekyll/site' require 'jekyll/convertible' require 'jekyll/layout' require 'jekyll/page' require 'jekyll/post' require 'jekyll/filters' require 'jekyll/static_file' require 'jekyll/errors' # extensions require 'jekyll/plugin' require 'jekyll/converter' require 'jekyll/generator' require_all 'jekyll/converters' require_all 'jekyll/generators' require_all 'jekyll/tags' module Jekyll VERSION = '0.11.2' # Default options. Overriden by values in _config.yml or command-line opts. # (Strings rather symbols used for compatability with YAML). DEFAULTS = { 'safe' => false, 'auto' => false, 'server' => false, 'server_port' => 4000, 'source' => Dir.pwd, 'destination' => File.join(Dir.pwd, '_site'), 'plugins' => File.join(Dir.pwd, '_plugins'), 'future' => true, 'lsi' => false, 'pygments' => false, 'markdown' => 'maruku', 'permalink' => 'date', 'markdown_ext' => 'markdown,mkd,mkdn,md', 'textile_ext' => 'textile', 'maruku' => { 'use_tex' => false, 'use_divs' => false, 'png_engine' => 'blahtex', 'png_dir' => 'images/latex', 'png_url' => '/images/latex' }, 'rdiscount' => { 'extensions' => [] }, 'redcarpet' => { 'extensions' => [] }, 'kramdown' => { 'auto_ids' => true, 'footnote_nr' => 1, 'entity_output' => 'as_char', 'toc_levels' => '1..6', 'use_coderay' => false, 'coderay' => { 'coderay_wrap' => 'div', 'coderay_line_numbers' => 'inline', 'coderay_line_number_start' => 1, 'coderay_tab_width' => 4, 'coderay_bold_every' => 10, 'coderay_css' => 'style' } } } # Public: Generate a Jekyll configuration Hash by merging the default # options with anything in _config.yml, and adding the given options on top. # # override - A Hash of config directives that override any options in both # the defaults and the config file. See Jekyll::DEFAULTS for a # list of option names and their defaults. # # Returns the final configuration Hash. def self.configuration(override) # _config.yml may override default source location, but until # then, we need to know where to look for _config.yml source = override['source'] || Jekyll::DEFAULTS['source'] # Get configuration from /_config.yml config_file = File.join(source, '_config.yml') begin config = YAML.load_file(config_file) raise "Invalid configuration - #{config_file}" if !config.is_a?(Hash) $stdout.puts "Configuration from #{config_file}" rescue => err $stderr.puts "WARNING: Could not read configuration. " + "Using defaults (and options)." $stderr.puts "\t" + err.to_s config = {} end # Merge DEFAULTS < _config.yml < override Jekyll::DEFAULTS.deep_merge(config).deep_merge(override) end end jekyll-0.11.2/jekyll.gemspec0000644000175000017500000001237511752165402015573 0ustar uwabamiuwabamiGem::Specification.new do |s| s.specification_version = 2 if s.respond_to? :specification_version= s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.rubygems_version = '1.3.5' s.name = 'jekyll' s.version = '0.11.2' s.date = '2011-12-27' s.rubyforge_project = 'jekyll' s.summary = "A simple, blog aware, static site generator." s.description = "Jekyll is a simple, blog aware, static site generator." s.authors = ["Tom Preston-Werner"] s.email = 'tom@mojombo.com' s.homepage = 'http://github.com/mojombo/jekyll' s.require_paths = %w[lib] s.executables = ["jekyll"] s.rdoc_options = ["--charset=UTF-8"] s.extra_rdoc_files = %w[README.textile LICENSE] s.add_runtime_dependency('liquid', "~> 2.3") s.add_runtime_dependency('classifier', "~> 1.3") s.add_runtime_dependency('directory_watcher', "~> 1.1") s.add_runtime_dependency('maruku', "~> 0.5") s.add_runtime_dependency('kramdown', "~> 0.13") s.add_runtime_dependency('albino', "~> 1.3") s.add_development_dependency('rake', "~> 0.9") s.add_development_dependency('rdoc', "~> 3.11") s.add_development_dependency('redgreen', "~> 1.2") s.add_development_dependency('shoulda', "~> 2.11") s.add_development_dependency('rr', "~> 1.0") s.add_development_dependency('cucumber', "1.1") s.add_development_dependency('RedCloth', "~> 4.2") s.add_development_dependency('rdiscount', "~> 1.6") s.add_development_dependency('redcarpet', "~> 1.9") # = MANIFEST = s.files = %w[ Gemfile History.txt LICENSE README.textile Rakefile bin/jekyll cucumber.yml features/create_sites.feature features/embed_filters.feature features/markdown.feature features/pagination.feature features/permalinks.feature features/post_data.feature features/site_configuration.feature features/site_data.feature features/step_definitions/jekyll_steps.rb features/support/env.rb jekyll.gemspec lib/jekyll.rb lib/jekyll/converter.rb lib/jekyll/converters/identity.rb lib/jekyll/converters/markdown.rb lib/jekyll/converters/textile.rb lib/jekyll/convertible.rb lib/jekyll/core_ext.rb lib/jekyll/errors.rb lib/jekyll/filters.rb lib/jekyll/generator.rb lib/jekyll/generators/pagination.rb lib/jekyll/layout.rb lib/jekyll/migrators/csv.rb lib/jekyll/migrators/drupal.rb lib/jekyll/migrators/enki.rb lib/jekyll/migrators/marley.rb lib/jekyll/migrators/mephisto.rb lib/jekyll/migrators/mt.rb lib/jekyll/migrators/posterous.rb lib/jekyll/migrators/textpattern.rb lib/jekyll/migrators/tumblr.rb lib/jekyll/migrators/typo.rb lib/jekyll/migrators/wordpress.rb lib/jekyll/migrators/wordpressdotcom.rb lib/jekyll/page.rb lib/jekyll/plugin.rb lib/jekyll/post.rb lib/jekyll/site.rb lib/jekyll/static_file.rb lib/jekyll/tags/highlight.rb lib/jekyll/tags/include.rb test/helper.rb test/source/.htaccess test/source/_includes/sig.markdown test/source/_layouts/default.html test/source/_layouts/simple.html test/source/_posts/2008-02-02-not-published.textile test/source/_posts/2008-02-02-published.textile 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/_posts/2009-01-27-array-categories.textile test/source/_posts/2009-01-27-categories.textile test/source/_posts/2009-01-27-category.textile test/source/_posts/2009-01-27-empty-categories.textile test/source/_posts/2009-01-27-empty-category.textile test/source/_posts/2009-03-12-hash-#1.markdown test/source/_posts/2009-05-18-empty-tag.textile test/source/_posts/2009-05-18-empty-tags.textile test/source/_posts/2009-05-18-tag.textile test/source/_posts/2009-05-18-tags.textile test/source/_posts/2009-06-22-empty-yaml.textile test/source/_posts/2009-06-22-no-yaml.textile test/source/_posts/2010-01-08-triple-dash.markdown test/source/_posts/2010-01-09-date-override.textile test/source/_posts/2010-01-09-time-override.textile test/source/_posts/2010-01-09-timezone-override.textile test/source/_posts/2010-01-16-override-data.textile test/source/_posts/2011-04-12-md-extension.md test/source/_posts/2011-04-12-text-extension.text test/source/about.html test/source/category/_posts/2008-9-23-categories.textile test/source/contacts.html test/source/css/screen.css test/source/deal.with.dots.html test/source/foo/_posts/bar/2008-12-12-topical-post.textile test/source/index.html test/source/sitemap.xml test/source/win/_posts/2009-05-24-yaml-linebreak.markdown test/source/z_category/_posts/2008-9-23-categories.textile test/suite.rb test/test_configuration.rb test/test_core_ext.rb test/test_filters.rb test/test_generated_site.rb test/test_kramdown.rb test/test_page.rb test/test_pager.rb test/test_post.rb test/test_rdiscount.rb test/test_redcarpet.rb test/test_site.rb test/test_tags.rb ] # = MANIFEST = s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ } end jekyll-0.11.2/features/0000775000175000017500000000000011752165402014544 5ustar uwabamiuwabamijekyll-0.11.2/features/support/0000775000175000017500000000000011752165402016260 5ustar uwabamiuwabamijekyll-0.11.2/features/support/env.rb0000644000175000017500000000066711752165402017404 0ustar uwabamiuwabamirequire 'fileutils' require 'rr' require 'test/unit' World do include Test::Unit::Assertions end TEST_DIR = File.join('/', 'tmp', 'jekyll') JEKYLL_PATH = File.join(ENV['PWD'], 'bin', 'jekyll') def run_jekyll(opts = {}) command = JEKYLL_PATH command << " >> /dev/null 2>&1" if opts[:debug].nil? system command end # work around "invalid option: --format" cucumber bug (see #296) Test::Unit.run = true if RUBY_VERSION < '1.9' jekyll-0.11.2/features/step_definitions/0000775000175000017500000000000011752165402020112 5ustar uwabamiuwabamijekyll-0.11.2/features/step_definitions/jekyll_steps.rb0000644000175000017500000000654611752165402023160 0ustar uwabamiuwabamiBefore do FileUtils.mkdir(TEST_DIR) Dir.chdir(TEST_DIR) end After do Dir.chdir(TEST_DIR) FileUtils.rm_rf(TEST_DIR) end Given /^I have a blank site in "(.*)"$/ do |path| FileUtils.mkdir(path) end # Like "I have a foo file" but gives a yaml front matter so jekyll actually processes it Given /^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$/ do |file, key, value, text| File.open(file, 'w') do |f| f.write < true) end When /^I change "(.*)" to contain "(.*)"$/ do |file, text| File.open(file, 'a') do |f| f.write(text) end end Then /^the (.*) directory should exist$/ do |dir| assert File.directory?(dir) end Then /^I should see "(.*)" in "(.*)"$/ do |text, file| assert_match Regexp.new(text), File.open(file).readlines.join end Then /^the "(.*)" file should exist$/ do |file| assert File.file?(file) end Then /^the "(.*)" file should not exist$/ do |file| assert !File.exists?(file) end Then /^I should see today's time in "(.*)"$/ do |file| assert_match Regexp.new(Regexp.escape(Time.now.to_s)), File.open(file).readlines.join end Then /^I should see today's date in "(.*)"$/ do |file| assert_match Regexp.new(Date.today.to_s), File.open(file).readlines.join end jekyll-0.11.2/features/site_data.feature0000644000175000017500000000736411752165402020066 0ustar uwabamiuwabamiFeature: Site data As a hacker who likes to blog I want to be able to embed data into my site In order to make the site slightly dynamic Scenario: Use page variable in a page Given I have an "contact.html" page with title "Contact" that contains "{{ page.title }}: email@me.com" When I run jekyll Then the _site directory should exist And I should see "Contact: email@me.com" in "_site/contact.html" Scenario: Use site.time variable Given I have an "index.html" page that contains "{{ site.time }}" When I run jekyll Then the _site directory should exist And I should see today's time in "_site/index.html" Scenario: Use site.posts variable for latest post Given I have a _posts directory And I have an "index.html" page that contains "{{ site.posts.first.title }}: {{ site.posts.first.url }}" And I have the following posts: | title | date | content | | First Post | 3/25/2009 | My First Post | | Second Post | 3/26/2009 | My Second Post | | Third Post | 3/27/2009 | My Third Post | When I run jekyll Then the _site directory should exist And I should see "Third Post: /2009/03/27/third-post.html" in "_site/index.html" Scenario: Use site.posts variable in a loop Given I have a _posts directory And I have an "index.html" page that contains "{% for post in site.posts %} {{ post.title }} {% endfor %}" And I have the following posts: | title | date | content | | First Post | 3/25/2009 | My First Post | | Second Post | 3/26/2009 | My Second Post | | Third Post | 3/27/2009 | My Third Post | When I run jekyll Then the _site directory should exist And I should see "Third Post Second Post First Post" in "_site/index.html" Scenario: Use site.categories.code variable Given I have a _posts directory And I have an "index.html" page that contains "{% for post in site.categories.code %} {{ post.title }} {% endfor %}" And I have the following posts: | title | date | category | content | | Awesome Hack | 3/26/2009 | code | puts 'Hello World' | | Delicious Beer | 3/26/2009 | food | 1) Yuengling | When I run jekyll Then the _site directory should exist And I should see "Awesome Hack" in "_site/index.html" Scenario: Use site.tags variable Given I have a _posts directory And I have an "index.html" page that contains "{% for post in site.tags.beer %} {{ post.content }} {% endfor %}" And I have the following posts: | title | date | tag | content | | Delicious Beer | 3/26/2009 | beer | 1) Yuengling | When I run jekyll Then the _site directory should exist And I should see "Yuengling" in "_site/index.html" Scenario: Order Posts by name when on the same date Given I have a _posts directory And I have an "index.html" page that contains "{% for post in site.posts %}{{ post.title }}:{{ post.previous.title}},{{ post.next.title}} {% endfor %}" And I have the following posts: | title | date | content | | first | 2/26/2009 | first | | A | 3/26/2009 | A | | B | 3/26/2009 | B | | C | 3/26/2009 | C | | last | 4/26/2009 | last | When I run jekyll Then the _site directory should exist And I should see "last:C, C:B,last B:A,C A:first,B first:,A" in "_site/index.html" Scenario: Use configuration date in site payload Given I have an "index.html" page that contains "{{ site.url }}" And I have a configuration file with "url" set to "http://mysite.com" When I run jekyll Then the _site directory should exist And I should see "http://mysite.com" in "_site/index.html" jekyll-0.11.2/features/site_configuration.feature0000644000175000017500000001507011752165402022015 0ustar uwabamiuwabamiFeature: Site configuration As a hacker who likes to blog I want to be able to configure jekyll In order to make setting up a site easier Scenario: Change destination directory Given I have a blank site in "_sourcedir" And I have an "_sourcedir/index.html" file that contains "Changing source directory" And I have a configuration file with "source" set to "_sourcedir" When I run jekyll Then the _site directory should exist And I should see "Changing source directory" in "_site/index.html" Scenario: Change destination directory Given I have an "index.html" file that contains "Changing destination directory" And I have a configuration file with "destination" set to "_mysite" When I run jekyll Then the _mysite directory should exist And I should see "Changing destination directory" in "_mysite/index.html" Scenario: Exclude files inline Given I have an "Rakefile" file that contains "I want to be excluded" And I have an "README" file that contains "I want to be excluded" And I have an "index.html" file that contains "I want to be included" And I have a configuration file with "exclude" set to "Rakefile", "README" When I run jekyll Then I should see "I want to be included" in "_site/index.html" And the "_site/Rakefile" file should not exist And the "_site/README" file should not exist Scenario: Exclude files with YAML array Given I have an "Rakefile" file that contains "I want to be excluded" And I have an "README" file that contains "I want to be excluded" And I have an "index.html" file that contains "I want to be included" And I have a configuration file with "exclude" set to: | value | | README | | Rakefile | When I run jekyll Then I should see "I want to be included" in "_site/index.html" And the "_site/Rakefile" file should not exist And the "_site/README" file should not exist Scenario: Use RDiscount for markup Given I have an "index.markdown" page that contains "[Google](http://google.com)" And I have a configuration file with "markdown" set to "rdiscount" When I run jekyll Then the _site directory should exist And I should see "Google" in "_site/index.html" Scenario: Use Kramdown for markup Given I have an "index.markdown" page that contains "[Google](http://google.com)" And I have a configuration file with "markdown" set to "kramdown" When I run jekyll Then the _site directory should exist And I should see "Google" in "_site/index.html" Scenario: Use Redcarpet for markup Given I have an "index.markdown" page that contains "[Google](http://google.com)" And I have a configuration file with "markdown" set to "redcarpet" When I run jekyll Then the _site directory should exist And I should see "Google" in "_site/index.html" Scenario: Use Maruku for markup Given I have an "index.markdown" page that contains "[Google](http://google.com)" And I have a configuration file with "markdown" set to "maruku" When I run jekyll Then the _site directory should exist And I should see "Google" in "_site/index.html" Scenario: Highlight code with pygments Given I have an "index.html" file that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}" And I have a configuration file with "pygments" set to "true" When I run jekyll Then the _site directory should exist And I should see "puts 'Hello world!'" in "_site/index.html" Scenario: Set time and no future dated posts Given I have a _layouts directory And I have a page layout that contains "Page Layout: {{ site.posts.size }} on {{ site.time | date: "%Y-%m-%d" }}" And I have a post layout that contains "Post Layout: {{ content }}" And I have an "index.html" page with layout "page" that contains "site index page" And I have a configuration file with: | key | value | | time | 2010-01-01 | | future | false | And I have a _posts directory And I have the following posts: | title | date | layout | content | | entry1 | 12/31/2007 | post | content for entry1. | | entry2 | 01/31/2020 | post | content for entry2. | When I run jekyll Then the _site directory should exist And I should see "Page Layout: 1 on 2010-01-01" in "_site/index.html" And I should see "Post Layout:

content for entry1.

" in "_site/2007/12/31/entry1.html" And the "_site/2020/01/31/entry2.html" file should not exist Scenario: Set time and future dated posts allowed Given I have a _layouts directory And I have a page layout that contains "Page Layout: {{ site.posts.size }} on {{ site.time | date: "%Y-%m-%d" }}" And I have a post layout that contains "Post Layout: {{ content }}" And I have an "index.html" page with layout "page" that contains "site index page" And I have a configuration file with: | key | value | | time | 2010-01-01 | | future | true | And I have a _posts directory And I have the following posts: | title | date | layout | content | | entry1 | 12/31/2007 | post | content for entry1. | | entry2 | 01/31/2020 | post | content for entry2. | When I run jekyll Then the _site directory should exist And I should see "Page Layout: 2 on 2010-01-01" in "_site/index.html" And I should see "Post Layout:

content for entry1.

" in "_site/2007/12/31/entry1.html" And I should see "Post Layout:

content for entry2.

" in "_site/2020/01/31/entry2.html" Scenario: Limit the number of posts generated by most recent date Given I have a _posts directory And I have a configuration file with: | key | value | | limit_posts | 2 | And I have the following posts: | title | date | content | | Apples | 3/27/2009 | An article about apples | | Oranges | 4/1/2009 | An article about oranges | | Bananas | 4/5/2009 | An article about bananas | When I run jekyll Then the _site directory should exist And the "_site/2009/04/05/bananas.html" file should exist And the "_site/2009/04/01/oranges.html" file should exist And the "_site/2009/03/27/apples.html" file should not exist jekyll-0.11.2/features/post_data.feature0000644000175000017500000001674111752165402020106 0ustar uwabamiuwabamiFeature: Post data As a hacker who likes to blog I want to be able to embed data into my posts In order to make the posts slightly dynamic Scenario: Use post.title variable Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | content | | Star Wars | 3/27/2009 | simple | Luke, I am your father. | And I have a simple layout that contains "Post title: {{ page.title }}" When I run jekyll Then the _site directory should exist And I should see "Post title: Star Wars" in "_site/2009/03/27/star-wars.html" Scenario: Use post.url variable Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | content | | Star Wars | 3/27/2009 | simple | Luke, I am your father. | And I have a simple layout that contains "Post url: {{ page.url }}" When I run jekyll Then the _site directory should exist And I should see "Post url: /2009/03/27/star-wars.html" in "_site/2009/03/27/star-wars.html" Scenario: Use post.date variable Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | content | | Star Wars | 3/27/2009 | simple | Luke, I am your father. | And I have a simple layout that contains "Post date: {{ page.date | date_to_string }}" When I run jekyll Then the _site directory should exist And I should see "Post date: 27 Mar 2009" in "_site/2009/03/27/star-wars.html" Scenario: Use post.id variable Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | content | | Star Wars | 3/27/2009 | simple | Luke, I am your father. | And I have a simple layout that contains "Post id: {{ page.id }}" When I run jekyll Then the _site directory should exist And I should see "Post id: /2009/03/27/star-wars" in "_site/2009/03/27/star-wars.html" Scenario: Use post.content variable Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | content | | Star Wars | 3/27/2009 | simple | Luke, I am your father. | And I have a simple layout that contains "Post content: {{ content }}" When I run jekyll Then the _site directory should exist And I should see "Post content:

Luke, I am your father.

" in "_site/2009/03/27/star-wars.html" Scenario: Use post.categories variable when category is in a folder Given I have a movies directory And I have a movies/_posts directory And I have a _layouts directory And I have the following post in "movies": | title | date | layout | content | | Star Wars | 3/27/2009 | simple | Luke, I am your father. | And I have a simple layout that contains "Post category: {{ page.categories }}" When I run jekyll Then the _site directory should exist And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html" Scenario: Use post.tags variable Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | tag | content | | Star Wars | 5/18/2009 | simple | twist | Luke, I am your father. | And I have a simple layout that contains "Post tags: {{ page.tags }}" When I run jekyll Then the _site directory should exist And I should see "Post tags: twist" in "_site/2009/05/18/star-wars.html" Scenario: Use post.categories variable when categories are in folders Given I have a scifi directory And I have a scifi/movies directory And I have a scifi/movies/_posts directory And I have a _layouts directory And I have the following post in "scifi/movies": | title | date | layout | content | | Star Wars | 3/27/2009 | simple | Luke, I am your father. | And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}" When I run jekyll Then the _site directory should exist And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html" Scenario: Use post.categories variable when category is in YAML Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | category | content | | Star Wars | 3/27/2009 | simple | movies | Luke, I am your father. | And I have a simple layout that contains "Post category: {{ page.categories }}" When I run jekyll Then the _site directory should exist And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html" Scenario: Use post.categories variable when categories are in YAML Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | categories | content | | Star Wars | 3/27/2009 | simple | ['scifi', 'movies'] | Luke, I am your father. | And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}" When I run jekyll Then the _site directory should exist And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html" Scenario: Disable a post from being published Given I have a _posts directory And I have an "index.html" file that contains "Published!" And I have the following post: | title | date | layout | published | content | | Star Wars | 3/27/2009 | simple | false | Luke, I am your father. | When I run jekyll Then the _site directory should exist And the "_site/2009/03/27/star-wars.html" file should not exist And I should see "Published!" in "_site/index.html" Scenario: Use a custom variable Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | author | content | | Star Wars | 3/27/2009 | simple | Darth Vader | Luke, I am your father. | And I have a simple layout that contains "Post author: {{ page.author }}" When I run jekyll Then the _site directory should exist And I should see "Post author: Darth Vader" in "_site/2009/03/27/star-wars.html" Scenario: Previous and next posts title Given I have a _posts directory And I have a _layouts directory And I have the following posts: | title | date | layout | author | content | | Star Wars | 3/27/2009 | ordered | Darth Vader | Luke, I am your father. | | Some like it hot | 4/27/2009 | ordered | Osgood | Nobody is perfect. | | Terminator | 5/27/2009 | ordered | Arnold | Sayonara, baby | And I have a ordered layout that contains "Previous post: {{ page.previous.title }} and next post: {{ page.next.title }}" When I run jekyll Then the _site directory should exist And I should see "next post: Some like it hot" in "_site/2009/03/27/star-wars.html" And I should see "Previous post: Some like it hot" in "_site/2009/05/27/terminator.html" jekyll-0.11.2/features/permalinks.feature0000644000175000017500000000622611752165402020272 0ustar uwabamiuwabamiFeature: Fancy permalinks As a hacker who likes to blog I want to be able to set permalinks In order to make my blog URLs awesome Scenario: Use none permalink schema Given I have a _posts directory And I have the following post: | title | date | content | | None Permalink Schema | 3/27/2009 | Totally nothing. | And I have a configuration file with "permalink" set to "none" When I run jekyll Then the _site directory should exist And I should see "Totally nothing." in "_site/none-permalink-schema.html" Scenario: Use pretty permalink schema Given I have a _posts directory And I have the following post: | title | date | content | | Pretty Permalink Schema | 3/27/2009 | Totally wordpress. | And I have a configuration file with "permalink" set to "pretty" When I run jekyll Then the _site directory should exist And I should see "Totally wordpress." in "_site/2009/03/27/pretty-permalink-schema/index.html" Scenario: Use pretty permalink schema for pages Given I have an "index.html" page that contains "Totally index" And I have an "awesome.html" page that contains "Totally awesome" And I have an "sitemap.xml" page that contains "Totally uhm, sitemap" And I have a configuration file with "permalink" set to "pretty" When I run jekyll Then the _site directory should exist And I should see "Totally index" in "_site/index.html" And I should see "Totally awesome" in "_site/awesome/index.html" And I should see "Totally uhm, sitemap" in "_site/sitemap.xml" Scenario: Use custom permalink schema with prefix Given I have a _posts directory And I have the following post: | title | category | date | content | | Custom Permalink Schema | stuff | 3/27/2009 | Totally custom. | And I have a configuration file with "permalink" set to "/blog/:year/:month/:day/:title" When I run jekyll Then the _site directory should exist And I should see "Totally custom." in "_site/blog/2009/03/27/custom-permalink-schema/index.html" Scenario: Use custom permalink schema with category Given I have a _posts directory And I have the following post: | title | category | date | content | | Custom Permalink Schema | stuff | 3/27/2009 | Totally custom. | And I have a configuration file with "permalink" set to "/:categories/:title.html" When I run jekyll Then the _site directory should exist And I should see "Totally custom." in "_site/stuff/custom-permalink-schema.html" Scenario: Use custom permalink schema with squished date Given I have a _posts directory And I have the following post: | title | category | date | content | | Custom Permalink Schema | stuff | 3/27/2009 | Totally custom. | And I have a configuration file with "permalink" set to "/:month-:day-:year/:title.html" When I run jekyll Then the _site directory should exist And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-schema.html" jekyll-0.11.2/features/pagination.feature0000644000175000017500000000242211752165402020250 0ustar uwabamiuwabamiFeature: Site pagination In order to paginate my blog As a blog's user I want divide the posts in several pages Scenario Outline: Paginate with N posts per page Given I have a configuration file with "paginate" set to "" And I have a _layouts directory And I have an "index.html" page that contains "{{ paginator.posts.size }}" And I have a _posts directory And I have the following post: | title | date | layout | content | | Wargames | 3/27/2009 | default | The only winning move is not to play. | | Wargames2 | 4/27/2009 | default | The only winning move is not to play2. | | Wargames3 | 5/27/2009 | default | The only winning move is not to play3. | | Wargames4 | 6/27/2009 | default | The only winning move is not to play4. | When I run jekyll Then the _site/page directory should exist And the "_site/page/index.html" file should exist And I should see "" in "_site/page/index.html" And the "_site/page/index.html" file should not exist Examples: | num | exist | posts | not_exist | | 1 | 4 | 1 | 5 | | 2 | 2 | 2 | 3 | | 3 | 2 | 1 | 3 | jekyll-0.11.2/features/markdown.feature0000644000175000017500000000264111752165402017744 0ustar uwabamiuwabamiFeature: Markdown As a hacker who likes to blog I want to be able to make a static site In order to share my awesome ideas with the interwebs Scenario: Markdown in list on index Given I have a configuration file with "paginate" set to "5" And I have an "index.html" page that contains "Index - {% for post in site.posts %} {{ post.content }} {% endfor %}" And I have a _posts directory And I have the following post: | title | date | content | type | | Hackers | 3/27/2009 | # My Title | markdown | When I run jekyll Then the _site directory should exist And I should see "Index" in "_site/index.html" And I should see "

My Title

" in "_site/2009/03/27/hackers.html" And I should see "

My Title

" in "_site/index.html" Scenario: Markdown in pagination on index Given I have a configuration file with "paginate" set to "5" And I have an "index.html" page that contains "Index - {% for post in paginator.posts %} {{ post.content }} {% endfor %}" And I have a _posts directory And I have the following post: | title | date | content | type | | Hackers | 3/27/2009 | # My Title | markdown | When I run jekyll Then the _site directory should exist And I should see "Index" in "_site/index.html" And I should see "

My Title

" in "_site/index.html" jekyll-0.11.2/features/embed_filters.feature0000644000175000017500000000557111752165402020733 0ustar uwabamiuwabamiFeature: Embed filters As a hacker who likes to blog I want to be able to transform text inside a post or page In order to perform cool stuff in my posts Scenario: Convert date to XML schema Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | content | | Star Wars | 3/27/2009 | default | These aren't the droids you're looking for. | And I have a default layout that contains "{{ site.time | date_to_xmlschema }}" When I run jekyll Then the _site directory should exist And I should see today's date in "_site/2009/03/27/star-wars.html" Scenario: Escape text for XML Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | content | | Star & Wars | 3/27/2009 | default | These aren't the droids you're looking for. | And I have a default layout that contains "{{ page.title | xml_escape }}" When I run jekyll Then the _site directory should exist And I should see "Star & Wars" in "_site/2009/03/27/star-wars.html" Scenario: Calculate number of words Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | content | | Star Wars | 3/27/2009 | default | These aren't the droids you're looking for. | And I have a default layout that contains "{{ content | xml_escape }}" When I run jekyll Then the _site directory should exist And I should see "7" in "_site/2009/03/27/star-wars.html" Scenario: Convert an array into a sentence Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | tags | content | | Star Wars | 3/27/2009 | default | [scifi, movies, force] | These aren't the droids you're looking for. | And I have a default layout that contains "{{ page.tags | array_to_sentence_string }}" When I run jekyll Then the _site directory should exist And I should see "scifi, movies, and force" in "_site/2009/03/27/star-wars.html" Scenario: Textilize a given string Given I have a _posts directory And I have a _layouts directory And I have the following post: | title | date | layout | content | | Star Wars | 3/27/2009 | default | These aren't the droids you're looking for. | And I have a default layout that contains "By {{ '_Obi-wan_' | textilize }}" When I run jekyll Then the _site directory should exist And I should see "By

Obi-wan

" in "_site/2009/03/27/star-wars.html" jekyll-0.11.2/features/create_sites.feature0000644000175000017500000001221511752165402020572 0ustar uwabamiuwabamiFeature: Create sites As a hacker who likes to blog I want to be able to make a static site In order to share my awesome ideas with the interwebs Scenario: Basic site Given I have an "index.html" file that contains "Basic Site" When I run jekyll Then the _site directory should exist And I should see "Basic Site" in "_site/index.html" Scenario: Basic site with a post Given I have a _posts directory And I have the following post: | title | date | content | | Hackers | 3/27/2009 | My First Exploit | When I run jekyll Then the _site directory should exist And I should see "My First Exploit" in "_site/2009/03/27/hackers.html" Scenario: Basic site with layout and a page Given I have a _layouts directory And I have an "index.html" page with layout "default" that contains "Basic Site with Layout" And I have a default layout that contains "Page Layout: {{ content }}" When I run jekyll Then the _site directory should exist And I should see "Page Layout: Basic Site with Layout" in "_site/index.html" Scenario: Basic site with layout and a post Given I have a _layouts directory And I have a _posts directory And I have the following posts: | title | date | layout | content | | Wargames | 3/27/2009 | default | The only winning move is not to play. | And I have a default layout that contains "Post Layout: {{ content }}" When I run jekyll Then the _site directory should exist And I should see "Post Layout:

The only winning move is not to play.

" in "_site/2009/03/27/wargames.html" Scenario: Basic site with layouts, pages, posts and files Given I have a _layouts directory And I have a page layout that contains "Page {{ page.title }}: {{ content }}" And I have a post layout that contains "Post {{ page.title }}: {{ content }}" And I have an "index.html" page with layout "page" that contains "Site contains {{ site.pages.size }} pages and {{ site.posts.size }} posts" And I have a blog directory And I have a "blog/index.html" page with layout "page" that contains "blog category index page" And I have an "about.html" file that contains "No replacement {{ site.posts.size }}" And I have an "another_file" file that contains "" And I have a _posts directory And I have the following posts: | title | date | layout | content | | entry1 | 3/27/2009 | post | content for entry1. | | entry2 | 4/27/2009 | post | content for entry2. | And I have a category/_posts directory And I have the following posts in "category": | title | date | layout | content | | entry3 | 5/27/2009 | post | content for entry3. | | entry4 | 6/27/2009 | post | content for entry4. | When I run jekyll Then the _site directory should exist And I should see "Page : Site contains 2 pages and 4 posts" in "_site/index.html" And I should see "No replacement \{\{ site.posts.size \}\}" in "_site/about.html" And I should see "" in "_site/another_file" And I should see "Page : blog category index page" in "_site/blog/index.html" And I should see "Post entry1:

content for entry1.

" in "_site/2009/03/27/entry1.html" And I should see "Post entry2:

content for entry2.

" in "_site/2009/04/27/entry2.html" And I should see "Post entry3:

content for entry3.

" in "_site/category/2009/05/27/entry3.html" And I should see "Post entry4:

content for entry4.

" in "_site/category/2009/06/27/entry4.html" Scenario: Basic site with include tag Given I have a _includes directory And I have an "index.html" page that contains "Basic Site with include tag: {% include about.textile %}" And I have an "_includes/about.textile" file that contains "Generated by Jekyll" When I run jekyll Then the _site directory should exist And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html" Scenario: Basic site with subdir include tag Given I have a _includes directory And I have an "_includes/about.textile" file that contains "Generated by Jekyll" And I have an info directory And I have an "info/index.html" page that contains "Basic Site with subdir include tag: {% include about.textile %}" When I run jekyll Then the _site directory should exist And I should see "Basic Site with subdir include tag: Generated by Jekyll" in "_site/info/index.html" Scenario: Basic site with nested include tag Given I have a _includes directory And I have an "_includes/about.textile" file that contains "Generated by {% include jekyll.textile %}" And I have an "_includes/jekyll.textile" file that contains "Jekyll" And I have an "index.html" page that contains "Basic Site with include tag: {% include about.textile %}" When I debug jekyll Then the _site directory should exist And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html" jekyll-0.11.2/cucumber.yml0000644000175000017500000000003211752165402015247 0ustar uwabamiuwabamidefault: --format progressjekyll-0.11.2/bin/0000775000175000017500000000000011752165402013476 5ustar uwabamiuwabamijekyll-0.11.2/bin/jekyll0000755000175000017500000001603311752165402014717 0ustar uwabamiuwabami#!/usr/bin/env ruby $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib]) help = < ./_site jekyll # . -> jekyll # -> jekyll import # imports posts using named import script Configuration is read from '/_config.yml' but can be overriden using the following options: HELP require 'optparse' require 'jekyll' exec = {} options = {} opts = OptionParser.new do |opts| opts.banner = help opts.on("--file [PATH]", "File to import from") do |import_file| options['file'] = import_file end opts.on("--dbname [TEXT]", "DB to import from") do |import_dbname| options['dbname'] = import_dbname end opts.on("--user [TEXT]", "Username to use when importing") do |import_user| options['user'] = import_user end opts.on("--pass [TEXT]", "Password to use when importing") do |import_pass| options['pass'] = import_pass end opts.on("--host [HOST ADDRESS]", "Host to import from") do |import_host| options['host'] = import_host end opts.on("--site [SITE NAME]", "Site to import from") do |import_site| options['site'] = import_site end opts.on("--[no-]safe", "Safe mode (default unsafe)") do |safe| options['safe'] = safe end opts.on("--[no-]auto", "Auto-regenerate") do |auto| options['auto'] = auto end opts.on("--server [PORT]", "Start web server (default port 4000)") do |port| options['server'] = true options['server_port'] = port unless port.nil? end opts.on("--no-server", "Do not start a web server") do |part| options['server'] = false end opts.on("--base-url [BASE_URL]", "Serve website from a given base URL (default '/'") do |baseurl| options['baseurl'] = baseurl end opts.on("--[no-]lsi", "Use LSI for better related posts") do |lsi| options['lsi'] = lsi end opts.on("--[no-]pygments", "Use pygments to highlight code") do |pygments| options['pygments'] = pygments end opts.on("--rdiscount", "Use rdiscount gem for Markdown") do options['markdown'] = 'rdiscount' end opts.on("--redcarpet", "Use redcarpet gem for Markdown") do options['markdown'] = 'redcarpet' end opts.on("--kramdown", "Use kramdown gem for Markdown") do options['markdown'] = 'kramdown' end opts.on("--time [TIME]", "Time to generate the site for") do |time| options['time'] = Time.parse(time) end opts.on("--[no-]future", "Render future dated posts") do |future| options['future'] = future end opts.on("--permalink [TYPE]", "Use 'date' (default) for YYYY/MM/DD") do |style| options['permalink'] = style unless style.nil? end opts.on("--paginate [POSTS_PER_PAGE]", "Paginate a blog's posts") do |per_page| begin options['paginate'] = per_page.to_i raise ArgumentError if options['paginate'] == 0 rescue puts 'you must specify a number of posts by page bigger than 0' exit 0 end end opts.on("--limit_posts [MAX_POSTS]", "Limit the number of posts to publish") do |limit_posts| begin options['limit_posts'] = limit_posts.to_i raise ArgumentError if options['limit_posts'] < 1 rescue puts 'you must specify a number of posts by page bigger than 0' exit 0 end end opts.on("--url [URL]", "Set custom site.url") do |url| options['url'] = url end opts.on("--version", "Display current version") do puts "Jekyll " + Jekyll::VERSION exit 0 end end # Read command line options into `options` hash opts.parse! # Check for import stuff if ARGV.size > 0 if ARGV[0] == 'import' migrator = ARGV[1] if migrator.nil? puts "Invalid options. Run `jekyll --help` for assistance." exit(1) else migrator = migrator.downcase end cmd_options = [] ['file', 'dbname', 'user', 'pass', 'host', 'site'].each do |p| cmd_options << "\"#{options[p]}\"" unless options[p].nil? end # It's import time puts "Importing..." # Ideally, this shouldn't be necessary. Maybe parse the actual # src files for the migrator name? migrators = { :posterous => 'Posterous', :wordpressdotcom => 'WordpressDotCom', :wordpress => 'Wordpress', :csv => 'CSV', :drupal => 'Drupal', :enki => 'Enki', :mephisto => 'Mephisto', :mt => 'MT', :textpattern => 'TextPattern', :tumblr => 'Tumblr', :typo => 'Typo' } app_root = File.join(File.dirname(__FILE__), '..') require "#{app_root}/lib/jekyll/migrators/#{migrator}" if Jekyll.const_defined?(migrators[migrator.to_sym]) migrator_class = Jekyll.const_get(migrators[migrator.to_sym]) migrator_class.process(*cmd_options) else puts "Invalid migrator. Run `jekyll --help` for assistance." exit(1) end exit(0) end end # Get source and destintation from command line case ARGV.size when 0 when 1 options['destination'] = ARGV[0] when 2 options['source'] = ARGV[0] options['destination'] = ARGV[1] else puts "Invalid options. Run `jekyll --help` for assistance." exit(1) end options = Jekyll.configuration(options) # Get source and destination directories (possibly set by config file) source = options['source'] destination = options['destination'] # Files to watch def globs(source) Dir.chdir(source) do dirs = Dir['*'].select { |x| File.directory?(x) } dirs -= ['_site'] dirs = dirs.map { |x| "#{x}/**/*" } dirs += ['*'] end end # Create the Site site = Jekyll::Site.new(options) # Run the directory watcher for auto-generation, if required if options['auto'] require 'directory_watcher' puts "Auto-regenerating enabled: #{source} -> #{destination}" dw = DirectoryWatcher.new(source) dw.interval = 1 dw.glob = globs(source) dw.add_observer do |*args| t = Time.now.strftime("%Y-%m-%d %H:%M:%S") puts "[#{t}] regeneration: #{args.size} files changed" site.process end dw.start unless options['server'] loop { sleep 1000 } end else puts "Building site: #{source} -> #{destination}" begin site.process rescue Jekyll::FatalException => e puts puts "ERROR: YOUR SITE COULD NOT BE BUILT:" puts "------------------------------------" puts e.message exit(1) end puts "Successfully generated site: #{source} -> #{destination}" end # Run the server on the specified port, if required if options['server'] require 'webrick' include WEBrick FileUtils.mkdir_p(destination) mime_types = WEBrick::HTTPUtils::DefaultMimeTypes mime_types.store 'js', 'application/javascript' s = HTTPServer.new( :Port => options['server_port'], :MimeTypes => mime_types ) s.mount(options['baseurl'], HTTPServlet::FileHandler, destination) t = Thread.new { s.start } trap("INT") { s.shutdown } t.join() end jekyll-0.11.2/Rakefile0000644000175000017500000001043711752165402014376 0ustar uwabamiuwabamirequire 'rubygems' require 'rake' require 'rdoc' require 'date' $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib])) ############################################################################# # # Helper functions # ############################################################################# def name @name ||= Dir['*.gemspec'].first.split('.').first end def version line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/] line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1] end def date Date.today.to_s end def rubyforge_project name end def gemspec_file "#{name}.gemspec" end def gem_file "#{name}-#{version}.gem" end def replace_header(head, header_name) head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"} end ############################################################################# # # Standard tasks # ############################################################################# task :default => [:test, :features] require 'rake/testtask' Rake::TestTask.new(:test) do |test| if `which pygmentize` == '' puts "You must have Pygments installed to run the tests." exit 1 end test.libs << 'lib' << 'test' test.pattern = 'test/**/test_*.rb' test.verbose = true end desc "Generate RCov test coverage and open in your browser" task :coverage do require 'rcov' sh "rm -fr coverage" sh "rcov test/test_*.rb" sh "open coverage/index.html" end require 'rdoc/task' Rake::RDocTask.new do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = "#{name} #{version}" rdoc.rdoc_files.include('README*') rdoc.rdoc_files.include('lib/**/*.rb') end desc "Open an irb session preloaded with this library" task :console do sh "irb -rubygems -r ./lib/#{name}.rb" end ############################################################################# # # Custom tasks (add your own tasks here) # ############################################################################# namespace :migrate do desc "Migrate from mephisto in the current directory" task :mephisto do sh %q(ruby -r './lib/jekyll/migrators/mephisto' -e 'Jekyll::Mephisto.postgres(:database => "#{ENV["DB"]}")') end desc "Migrate from Movable Type in the current directory" task :mt do sh %q(ruby -r './lib/jekyll/migrators/mt' -e 'Jekyll::MT.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")') end desc "Migrate from Typo in the current directory" task :typo do sh %q(ruby -r './lib/jekyll/migrators/typo' -e 'Jekyll::Typo.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")') end end begin require 'cucumber/rake/task' Cucumber::Rake::Task.new(:features) do |t| t.cucumber_opts = "--format progress" end rescue LoadError desc 'Cucumber rake task not available' task :features do abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin' end end ############################################################################# # # Packaging tasks # ############################################################################# task :release => :build do unless `git branch` =~ /^\* master$/ puts "You must be on the master branch to release!" exit! end sh "git commit --allow-empty -m 'Release #{version}'" sh "git tag v#{version}" sh "git push origin master" sh "git push origin v#{version}" sh "gem push pkg/#{name}-#{version}.gem" end task :build => :gemspec do sh "mkdir -p pkg" sh "gem build #{gemspec_file}" sh "mv #{gem_file} pkg" end task :gemspec do # read spec file and split out manifest section spec = File.read(gemspec_file) head, manifest, tail = spec.split(" # = MANIFEST =\n") # replace name version and date replace_header(head, :name) replace_header(head, :version) replace_header(head, :date) #comment this out if your rubyforge_project has a different name replace_header(head, :rubyforge_project) # determine file list from git ls-files files = `git ls-files`. split("\n"). sort. reject { |file| file =~ /^\./ }. reject { |file| file =~ /^(rdoc|pkg|coverage)/ }. map { |file| " #{file}" }. join("\n") # piece file back together and write manifest = " s.files = %w[\n#{files}\n ]\n" spec = [head, manifest, tail].join(" # = MANIFEST =\n") File.open(gemspec_file, 'w') { |io| io.write(spec) } puts "Updated #{gemspec_file}" endjekyll-0.11.2/README.textile0000644000175000017500000000376511752165402015274 0ustar uwabamiuwabamih1. Jekyll By Tom Preston-Werner, Nick Quaranto, and many awesome contributors! Jekyll is a simple, blog aware, static site generator. It takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server. This is also the engine behind "GitHub Pages":http://pages.github.com, which you can use to host your project's page or blog right here from GitHub. h2. Getting Started * "Install":http://wiki.github.com/mojombo/jekyll/install the gem * Read up about its "Usage":http://wiki.github.com/mojombo/jekyll/usage and "Configuration":http://wiki.github.com/mojombo/jekyll/configuration * Take a gander at some existing "Sites":http://wiki.github.com/mojombo/jekyll/sites * Fork and "Contribute":http://wiki.github.com/mojombo/jekyll/contribute your own modifications * Have questions? Post them on the "Mailing List":http://groups.google.com/group/jekyll-rb h2. Diving In * "Migrate":http://wiki.github.com/mojombo/jekyll/blog-migrations from your previous system * Learn how the "YAML Front Matter":http://wiki.github.com/mojombo/jekyll/yaml-front-matter works * Put information on your site with "Template Data":http://wiki.github.com/mojombo/jekyll/template-data * Customize the "Permalinks":http://wiki.github.com/mojombo/jekyll/permalinks your posts are generated with * Use the built-in "Liquid Extensions":http://wiki.github.com/mojombo/jekyll/liquid-extensions to make your life easier h2. Runtime Dependencies * RedCloth: Textile support (Ruby) * Liquid: Templating system (Ruby) * Classifier: Generating related posts (Ruby) * Maruku: Default markdown engine (Ruby) * Directory Watcher: Auto-regeneration of sites (Ruby) * Pygments: Syntax highlighting (Python) h2. Developer Dependencies * Shoulda: Test framework (Ruby) * RR: Mocking (Ruby) * RedGreen: Nicer test output (Ruby) * RDiscount: Discount Markdown Processor (Ruby) h2. License See LICENSE. jekyll-0.11.2/LICENSE0000644000175000017500000000207011752165402013730 0ustar uwabamiuwabami(The MIT License) Copyright (c) 2008 Tom Preston-Werner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.jekyll-0.11.2/History.txt0000644000175000017500000002661711752165402015142 0ustar uwabamiuwabami== 0.11.2 / 2011-12-27 * Bug Fixes * Fix gemspec == 0.11.1 / 2011-12-27 * Bug Fixes * Fix extra blank line in highlight blocks (#409) * Update dependencies == 0.11.0 / 2011-07-10 * Major Enhancements * Add command line importer functionality (#253) * Add Redcarpet Markdown support (#318) * Make markdown/textile extensions configurable (#312) * Add `markdownify` filter * Minor Enhancements * Switch to Albino gem * Bundler support * Use English library to avoid hoops (#292) * Add Posterous importer (#254) * Fixes for Wordpress importer (#274, #252, #271) * Better error message for invalid post date (#291) * Print formatted fatal exceptions to stdout on build failure * Add Tumblr importer (#323) * Add Enki importer (#320) * Bug Fixes * Secure additional path exploits == 0.10.0 / 2010-12-16 * Bug Fixes * Add --no-server option. == 0.9.0 / 2010-12-15 * Minor Enhancements * Use OptionParser's [no-] functionality for better boolean parsing. * Add Drupal migrator (#245) * Complain about YAML and Liquid errors (#249) * Remove orphaned files during regeneration (#247) * Add Marley migrator (#28) == 0.8.0 / 2010-11-22 * Minor Enhancements * Add wordpress.com importer (#207) * Add --limit-posts cli option (#212) * Add uri_escape filter (#234) * Add --base-url cli option (#235) * Improve MT migrator (#238) * Add kramdown support (#239) * Bug Fixes * Fixed filename basename generation (#208) * Set mode to UTF8 on Sequel connections (#237) * Prevent _includes dir from being a symlink == 0.7.0 / 2010-08-24 * Minor Enhancements * Add support for rdiscount extensions (#173) * Bug Fixes * Highlight should not be able to render local files * The site configuration may not always provide a 'time' setting (#184) == 0.6.2 / 2010-06-25 * Bug Fixes * Fix Rakefile 'release' task (tag pushing was missing origin) * Ensure that RedCloth is loaded when textilize filter is used (#183) * Expand source, destination, and plugin paths (#180) * Fix page.url to include full relative path (#181) == 0.6.1 / 2010-06-24 * Bug Fixes * Fix Markdown Pygments prefix and suffix (#178) == 0.6.0 / 2010-06-23 * Major Enhancements * Proper plugin system (#19, #100) * Add safe mode so unsafe converters/generators can be added * Maruku is now the only processor dependency installed by default. Other processors will be lazy-loaded when necessary (and prompt the user to install them when necessary) (#57) * Minor Enhancements * Inclusion/exclusion of future dated posts (#59) * Generation for a specific time (#59) * Allocate site.time on render not per site_payload invocation (#59) * Pages now present in the site payload and can be used through the site.pages and site.html_pages variables * Generate phase added to site#process and pagination is now a generator * Switch to RakeGem for build/test process * Only regenerate static files when they have changed (#142) * Allow arbitrary options to Pygments (#31) * Allow URL to be set via command line option (#147) * Bug Fixes * Render highlighted code for non markdown/textile pages (#116) * Fix highlighting on Ruby 1.9 (#65) * Fix extension munging when pretty permalinks are enabled (#64) * Stop sorting categories (#33) * Preserve generated attributes over front matter (#119) * Fix source directory binding using Dir.pwd (#75) == 0.5.7 / 2010-01-12 * Minor Enhancements * Allow overriding of post date in the front matter (#62, #38) * Bug Fixes * Categories isn't always an array (#73) * Empty tags causes error in read_posts (#84) * Fix pagination to adhere to read/render/write paradigm * Test Enhancement * cucumber features no longer use site.posts.first where a better alternative is available == 0.5.6 / 2010-01-08 * Bug Fixes * Require redcloth >= 4.2.1 in tests (#92) * Don't break on triple dashes in yaml frontmatter (#93) * Minor Enhancements * Allow .mkd as markdown extension * Use $stdout/err instead of constants (#99) * Properly wrap code blocks (#91) * Add javascript mime type for webrick (#98) == 0.5.5 / 2010-01-08 * Bug Fixes * Fix pagination % 0 bug (#78) * Ensure all posts are processed first (#71) == NOTE * After this point I will no longer be giving credit in the history; that is what the commit log is for. == 0.5.4 / 2009-08-23 * Bug Fixes * Do not allow symlinks (security vulnerability) == 0.5.3 / 2009-07-14 * Bug Fixes * Solving the permalink bug where non-html files wouldn't work [github.com/jeffrydegrande] == 0.5.2 / 2009-06-24 * Enhancements * Added --paginate option to the executable along with a paginator object for the payload [github.com/calavera] * Upgraded RedCloth to 4.2.1, which makes tags work once again. * Configuration options set in config.yml are now available through the site payload [github.com/vilcans] * Posts can now have an empty YAML front matter or none at all [github.com/bahuvrihi] * Bug Fixes * Fixing Ruby 1.9 issue that requires to_s on the err object [github.com/Chrononaut] * Fixes for pagination and ordering posts on the same day [github.com/ujh] * Made pages respect permalinks style and permalinks in yml front matter [github.com/eugenebolshakov] * Index.html file should always have index.html permalink [github.com/eugenebolshakov] * Added trailing slash to pretty permalink style so Apache is happy [github.com/eugenebolshakov] * Bad markdown processor in config fails sooner and with better message [github.com/gcnovus] * Allow CRLFs in yaml frontmatter [github.com/juretta] * Added Date#xmlschema for Ruby versions < 1.9 == 0.5.1 / 2009-05-06 * Major Enhancements * Next/previous posts in site payload [github.com/pantulis, github.com/tomo] * Permalink templating system * Moved most of the README out to the GitHub wiki * Exclude option in configuration so specified files won't be brought over with generated site [github.com/duritong] * Bug Fixes * Making sure config.yaml references are all gone, using only config.yml * Fixed syntax highlighting breaking for UTF-8 code [github.com/henrik] * Worked around RDiscount bug that prevents Markdown from getting parsed after highlight [github.com/henrik] * CGI escaped post titles [github.com/Chrononaut] == 0.5.0 / 2009-04-07 * Minor Enhancements * Ability to set post categories via YAML [github.com/qrush] * Ability to set prevent a post from publishing via YAML [github.com/qrush] * Add textilize filter [github.com/willcodeforfoo] * Add 'pretty' permalink style for wordpress-like urls [github.com/dysinger] * Made it possible to enter categories from YAML as an array [github.com/Chrononaut] * Ignore Emacs autosave files [github.com/Chrononaut] * Bug Fixes * Use block syntax of popen4 to ensure that subprocesses are properly disposed [github.com/jqr] * Close open4 streams to prevent zombies [github.com/rtomayko] * Only query required fields from the WP Database [github.com/ariejan] * Prevent _posts from being copied to the destination directory [github.com/bdimcheff] * Refactors * Factored the filtering code into a method [github.com/Chrononaut] * Fix tests and convert to Shoulda [github.com/qrush, github.com/technicalpickles] * Add Cucumber acceptance test suite [github.com/qrush, github.com/technicalpickles] == 0.4.1 * Minor Enhancements * Changed date format on wordpress converter (zeropadding) [github.com/dysinger] * Bug Fixes * Add jekyll binary as executable to gemspec [github.com/dysinger] == 0.4.0 / 2009-02-03 * Major Enhancements * Switch to Jeweler for packaging tasks * Minor Enhancements * Type importer [github.com/codeslinger] * site.topics accessor [github.com/baz] * Add array_to_sentence_string filter [github.com/mchung] * Add a converter for textpattern [github.com/PerfectlyNormal] * Add a working Mephisto / MySQL converter [github.com/ivey] * Allowing .htaccess files to be copied over into the generated site [github.com/briandoll] * Add option to not put file date in permalink URL [github.com/mreid] * Add line number capabilities to highlight blocks [github.com/jcon] * Bug Fixes * Fix permalink behavior [github.com/cavalle] * Fixed an issue with pygments, markdown, and newlines [github.com/zpinter] * Ampersands need to be escaped [github.com/pufuwozu, github.com/ap] * Test and fix the site.categories hash [github.com/zzot] * Fix site payload available to files [github.com/matrix9180] == 0.3.0 / 2008-12-24 * Major Enhancements * Added --server option to start a simple WEBrick server on destination directory [github.com/johnreilly and github.com/mchung] * Minor Enhancements * Added post categories based on directories containing _posts [github.com/mreid] * Added post topics based on directories underneath _posts * Added new date filter that shows the full month name [github.com/mreid] * Merge Post's YAML front matter into its to_liquid payload [github.com/remi] * Restrict includes to regular files underneath _includes * Bug Fixes * Change YAML delimiter matcher so as to not chew up 2nd level markdown headers [github.com/mreid] * Fix bug that meant page data (such as the date) was not available in templates [github.com/mreid] * Properly reject directories in _layouts == 0.2.1 / 2008-12-15 * Major Changes * Use Maruku (pure Ruby) for Markdown by default [github.com/mreid] * Allow use of RDiscount with --rdiscount flag * Minor Enhancements * Don't load directory_watcher unless it's needed [github.com/pjhyett] == 0.2.0 / 2008-12-14 * Major Changes * related_posts is now found in site.related_posts == 0.1.6 / 2008-12-13 * Major Features * Include files in _includes with {% include x.textile %} == 0.1.5 / 2008-12-12 * Major Features * Code highlighting with Pygments if --pygments is specified * Disable true LSI by default, enable with --lsi * Minor Enhancements * Output informative message if RDiscount is not available [github.com/JackDanger] * Bug Fixes * Prevent Jekyll from picking up the output directory as a source [github.com/JackDanger] * Skip related_posts when there is only one post [github.com/JackDanger] == 0.1.4 / 2008-12-08 * Bug Fixes * DATA does not work properly with rubygems == 0.1.3 / 2008-12-06 * Major Features * Markdown support [github.com/vanpelt] * Mephisto and CSV converters [github.com/vanpelt] * Code hilighting [github.com/vanpelt] * Autobuild * Bug Fixes * Accept both \r\n and \n in YAML header [github.com/vanpelt] == 0.1.2 / 2008-11-22 * Major Features * Add a real "related posts" implementation using Classifier * Command Line Changes * Allow cli to be called with 0, 1, or 2 args intuiting dir paths if they are omitted == 0.1.1 / 2008-11-22 * Minor Additions * Posts now support introspectional data e.g. {{ page.url }} == 0.1.0 / 2008-11-05 * First release * Converts posts written in Textile * Converts regular site pages * Simple copy of binary files == 0.0.0 / 2008-10-19 * Birthday! jekyll-0.11.2/Gemfile0000644000175000017500000000003111752165402014211 0ustar uwabamiuwabamisource :rubygems gemspec