[DRE-commits] [jekyll] 01/01: Imported Upstream version 1.4.2
Youhei SASAKI
uwabami-guest at moszumanska.debian.org
Tue Jan 14 13:50:18 UTC 2014
This is an automated email from the git hooks/post-receive script.
uwabami-guest pushed a commit to annotated tag upstream/1.4.2
in repository jekyll.
commit a9b1cbd6dc6d8db877bc87c160e8f29b2044fe94
Author: Youhei SASAKI <uwabami at gfd-dennou.org>
Date: Fri Jan 10 22:16:55 2014 +0900
Imported Upstream version 1.4.2
---
CONTRIBUTING.markdown | 91 ++
Gemfile | 2 +-
History.markdown | 873 +++++++++++++++++++
History.txt | 308 -------
README.markdown | 56 ++
README.textile | 41 -
Rakefile | 204 ++++-
bin/jekyll | 354 +++-----
checksums.yaml.gz | Bin 0 -> 267 bytes
cucumber.yml | 4 +-
features/create_sites.feature | 61 +-
features/data.feature | 65 ++
features/drafts.feature | 25 +
features/embed_filters.feature | 10 +-
features/include_tag.feature | 57 ++
features/markdown.feature | 49 +-
features/pagination.feature | 69 +-
features/permalinks.feature | 30 +-
features/post_data.feature | 95 ++-
features/post_excerpts.feature | 50 ++
features/site_configuration.feature | 128 ++-
features/site_data.feature | 61 +-
features/step_definitions/jekyll_steps.rb | 114 ++-
features/support/env.rb | 68 +-
jekyll.gemspec | 208 ++++-
lib/jekyll.rb | 114 +--
lib/jekyll/cleaner.rb | 73 ++
lib/jekyll/command.rb | 27 +
lib/jekyll/commands/build.rb | 70 ++
lib/jekyll/commands/doctor.rb | 67 ++
lib/jekyll/commands/new.rb | 67 ++
lib/jekyll/commands/serve.rb | 65 ++
lib/jekyll/configuration.rb | 238 ++++++
lib/jekyll/converter.rb | 4 +-
lib/jekyll/converters/identity.rb | 27 +-
lib/jekyll/converters/markdown.rb | 150 +---
lib/jekyll/converters/markdown/kramdown_parser.rb | 29 +
lib/jekyll/converters/markdown/maruku_parser.rb | 56 ++
lib/jekyll/converters/markdown/rdiscount_parser.rb | 37 +
lib/jekyll/converters/markdown/redcarpet_parser.rb | 70 ++
lib/jekyll/converters/textile.rb | 64 +-
lib/jekyll/convertible.rb | 132 ++-
lib/jekyll/core_ext.rb | 36 +-
lib/jekyll/deprecator.rb | 36 +
lib/jekyll/draft.rb | 35 +
lib/jekyll/entry_filter.rb | 35 +
lib/jekyll/errors.rb | 4 +-
lib/jekyll/excerpt.rb | 113 +++
lib/jekyll/filters.rb | 70 +-
lib/jekyll/generator.rb | 5 +-
lib/jekyll/generators/pagination.rb | 200 +++--
lib/jekyll/layout.rb | 5 +-
lib/jekyll/migrators/csv.rb | 26 -
lib/jekyll/migrators/drupal.rb | 92 --
lib/jekyll/migrators/enki.rb | 49 --
lib/jekyll/migrators/marley.rb | 52 --
lib/jekyll/migrators/mephisto.rb | 84 --
lib/jekyll/migrators/mt.rb | 86 --
lib/jekyll/migrators/posterous.rb | 68 --
lib/jekyll/migrators/textpattern.rb | 57 --
lib/jekyll/migrators/tumblr.rb | 119 ---
lib/jekyll/migrators/typo.rb | 51 --
lib/jekyll/migrators/wordpress.rb | 62 --
lib/jekyll/migrators/wordpressdotcom.rb | 70 --
lib/jekyll/mime.types | 85 ++
lib/jekyll/page.rb | 93 +-
lib/jekyll/plugin.rb | 2 -
lib/jekyll/post.rb | 289 ++++---
lib/jekyll/related_posts.rb | 59 ++
lib/jekyll/site.rb | 320 ++++---
lib/jekyll/static_file.rb | 2 -
lib/jekyll/stevenson.rb | 89 ++
lib/jekyll/tags/gist.rb | 48 ++
lib/jekyll/tags/highlight.rb | 120 +--
lib/jekyll/tags/include.rb | 140 ++-
lib/jekyll/tags/post_url.rb | 63 ++
lib/jekyll/url.rb | 67 ++
lib/site_template/.gitignore | 1 +
lib/site_template/_config.yml | 3 +
lib/site_template/_layouts/default.html | 44 +
lib/site_template/_layouts/post.html | 9 +
.../0000-00-00-welcome-to-jekyll.markdown.erb | 24 +
lib/site_template/css/main.css | 160 ++++
lib/site_template/css/syntax.css | 60 ++
lib/site_template/index.html | 13 +
metadata.yml | 773 +++++++++++------
script/bootstrap | 2 +
site/.gitignore | 4 +
site/CNAME | 1 +
site/README | 1 +
site/_config.yml | 6 +
site/_includes/analytics.html | 32 +
site/_includes/docs_contents.html | 16 +
site/_includes/docs_contents_mobile.html | 23 +
site/_includes/docs_option.html | 11 +
site/_includes/docs_ul.html | 20 +
site/_includes/footer.html | 15 +
site/_includes/header.html | 18 +
site/_includes/news_contents.html | 23 +
site/_includes/news_contents_mobile.html | 11 +
site/_includes/news_item.html | 24 +
site/_includes/primary-nav-items.html | 14 +
site/_includes/section_nav.html | 22 +
site/_includes/top.html | 17 +
site/_layouts/default.html | 12 +
site/_layouts/docs.html | 23 +
site/_layouts/news.html | 19 +
site/_layouts/news_item.html | 27 +
.../2013-05-06-jekyll-1-0-0-released.markdown | 23 +
.../2013-05-08-jekyll-1-0-1-released.markdown | 27 +
.../2013-05-12-jekyll-1-0-2-released.markdown | 28 +
.../2013-06-07-jekyll-1-0-3-released.markdown | 25 +
.../2013-07-14-jekyll-1-1-0-released.markdown | 27 +
.../2013-07-24-jekyll-1-1-1-released.markdown | 31 +
.../2013-07-25-jekyll-1-0-4-released.markdown | 20 +
.../2013-07-25-jekyll-1-1-2-released.markdown | 20 +
.../2013-09-06-jekyll-1-2-0-released.markdown | 23 +
.../2013-09-14-jekyll-1-2-1-released.markdown | 19 +
.../2013-10-28-jekyll-1-3-0-rc1-released.markdown | 19 +
.../2013-11-04-jekyll-1-3-0-released.markdown | 43 +
.../2013-11-26-jekyll-1-3-1-released.markdown | 21 +
.../2013-12-07-jekyll-1-4-0-released.markdown | 30 +
.../2013-12-16-jekyll-1-4-2-released.markdown | 16 +
site/css/gridism.css | 110 +++
site/css/normalize.css | 1 +
site/css/pygments.css | 70 ++
site/css/style.css | 946 +++++++++++++++++++++
site/docs/configuration.md | 375 ++++++++
site/docs/contributing.md | 128 +++
site/docs/datafiles.md | 63 ++
site/docs/deployment-methods.md | 109 +++
site/docs/drafts.md | 21 +
site/docs/extras.md | 56 ++
site/docs/frontmatter.md | 180 ++++
site/docs/github-pages.md | 91 ++
site/docs/heroku.md | 9 +
site/docs/history.md | 850 ++++++++++++++++++
site/docs/index.md | 52 ++
site/docs/installation.md | 76 ++
site/docs/migrations.md | 11 +
site/docs/pages.md | 86 ++
site/docs/pagination.md | 211 +++++
site/docs/permalinks.md | 180 ++++
site/docs/plugins.md | 534 ++++++++++++
site/docs/posts.md | 181 ++++
site/docs/quickstart.md | 32 +
site/docs/resources.md | 46 +
site/docs/sites.md | 29 +
site/docs/structure.md | 190 +++++
site/docs/templates.md | 339 ++++++++
site/docs/troubleshooting.md | 150 ++++
site/docs/upgrading.md | 146 ++++
site/docs/usage.md | 63 ++
site/docs/variables.md | 322 +++++++
site/favicon.png | Bin 0 -> 1359 bytes
site/feed.xml | 36 +
site/freenode.txt | 1 +
site/img/article-footer.png | Bin 0 -> 1898 bytes
site/img/footer-arrow.png | Bin 0 -> 846 bytes
site/img/footer-logo.png | Bin 0 -> 3906 bytes
site/img/logo-2x.png | Bin 0 -> 46587 bytes
site/img/octojekyll.png | Bin 0 -> 23728 bytes
site/img/tube.png | Bin 0 -> 9387 bytes
site/img/tube1x.png | Bin 0 -> 4036 bytes
site/index.html | 90 ++
site/js/modernizr-2.5.3.min.js | 4 +
site/news/index.html | 10 +
site/news/releases/index.html | 10 +
test/fixtures/broken_front_matter1.erb | 5 +
test/fixtures/broken_front_matter2.erb | 4 +
test/fixtures/broken_front_matter3.erb | 7 +
test/fixtures/exploit_front_matter.erb | 4 +
test/fixtures/front_matter.erb | 4 +
test/helper.rb | 35 +-
test/source/+/foo.md | 7 +
test/source/_config.dev.toml | 2 +
test/source/_data/languages.yml | 2 +
test/source/_data/members.yaml | 7 +
test/source/_data/products.yml | 4 +
test/source/_includes/params.html | 7 +
test/source/_layouts/default.html | 2 +-
test/source/_layouts/post/simple.html | 1 +
test/source/_plugins/dummy.rb | 8 +
.../source/_posts/2013-01-02-post-excerpt.markdown | 14 +
test/source/_posts/2013-01-12-nil-layout.textile | 6 +
test/source/_posts/2013-01-12-no-layout.textile | 5 +
.../_posts/2013-03-19-not-a-post.markdown/.gitkeep | 0
.../_posts/2013-04-11-custom-excerpt.markdown | 10 +
.../_posts/2013-05-10-number-category.textile | 7 +
.../2013-07-22-post-excerpt-with-layout.markdown | 23 +
test/source/_posts/2013-08-01-mkdn-extension.mkdn | 0
test/source/_posts/es/2008-11-21-nested.textile | 8 +
test/source/contacts/bar.html | 5 +
test/source/contacts/index.html | 5 +
test/source/products.yml | 4 +
test/source/symlink-test/symlinked-file | 22 +
test/suite.rb | 2 +-
test/test_command.rb | 39 +
test/test_configuration.rb | 174 +++-
test/test_convertible.rb | 51 ++
test/test_core_ext.rb | 22 +
test/test_entry_filter.rb | 74 ++
test/test_excerpt.rb | 78 ++
test/test_filters.rb | 51 ++
test/test_generated_site.rb | 21 +-
test/test_kramdown.rb | 45 +-
test/test_new_command.rb | 104 +++
test/test_page.rb | 91 +-
test/test_pager.rb | 65 +-
test/test_post.rb | 178 +++-
test/test_rdiscount.rb | 10 +-
test/test_redcarpet.rb | 52 +-
test/test_redcloth.rb | 86 ++
test/test_related_posts.rb | 47 +
test/test_site.rb | 205 ++++-
test/test_tags.rb | 327 ++++++-
test/test_url.rb | 28 +
217 files changed, 13969 insertions(+), 2642 deletions(-)
diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown
new file mode 100644
index 0000000..6df9962
--- /dev/null
+++ b/CONTRIBUTING.markdown
@@ -0,0 +1,91 @@
+Contribute
+==========
+
+So you've got an awesome idea to throw into Jekyll. Great! Please keep the
+following in mind:
+
+* **Contributions will not be accepted without tests.**
+* If you're creating a small fix or patch to an existing feature, just a simple
+ test will do. Please stay in the confines of the current test suite and use
+ [Shoulda](http://github.com/thoughtbot/shoulda/tree/master) and
+ [RR](http://github.com/btakita/rr/tree/master).
+* If it's a brand new feature, make sure to create a new
+ [Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
+ where appropriate. Also, whipping up some documentation in your fork's `site`
+ would be appreciated, and once merged it will be transferred over to the main
+ `site`, jekyllrb.com.
+* If your contribution changes any Jekyll behavior, make sure to update the
+ documentation. It lives in `site/docs`. If the docs are missing information,
+ please feel free to add it in. Great docs make a great project!
+* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
+ when modifying Ruby code.
+* Please do your best to submit **small pull requests**. The easier the proposed
+ change is to review, the more likely it will be merged.
+* When submitting a pull request, please make judicious use of the pull request
+ body. A description of what changes were made, the motivations behind the
+ changes and [any tasks completed or left to complete](http://git.io/gfm-tasks)
+ will also speed up review time.
+
+Test Dependencies
+-----------------
+
+To run the test suite and build the gem you'll need to install Jekyll's
+dependencies. Jekyll uses Bundler, so a quick run of the bundle command and
+you're all set!
+
+ $ bundle
+
+Before you start, run the tests and make sure that they pass (to confirm your
+environment is configured properly):
+
+ $ bundle exec rake test
+ $ bundle exec rake features
+
+Workflow
+--------
+
+Here's the most direct way to get your work merged into the project:
+
+* Fork the project.
+* Clone down your fork ( `git clone git at github.com:<username>/jekyll.git` ).
+* Create a topic branch to contain your change ( `git checkout -b my_awesome_feature` ).
+* Hack away, add tests. Not necessarily in that order.
+* Make sure everything still passes by running `rake`.
+* If necessary, rebase your commits into logical chunks, without errors.
+* Push the branch up ( `git push origin my_awesome_feature` ).
+* Create a pull request against mojombo/jekyll and describe what your change
+ does and the why you think it should be merged.
+
+Updating Documentation
+----------------------
+
+We want the Jekyll documentation to be the best it can be. We've
+open-sourced our docs and we welcome any pull requests if you find it
+lacking.
+
+You can find the documentation for jekyllrb.com in the
+[site](https://github.com/mojombo/jekyll/tree/master/site) directory of
+Jekyll's repo on GitHub.com.
+
+All documentation pull requests should be directed at `master`. Pull
+requests directed at another branch will not be accepted.
+
+The [Jekyll wiki](https://github.com/mojombo/jekyll/wiki) on GitHub
+can be freely updated without a pull request as all GitHub users have access.
+
+Gotchas
+-------
+
+* If you want to bump the gem version, please put that in a separate commit.
+ This way, the maintainers can control when the gem gets released.
+* Try to keep your patch(es) based from the latest commit on mojombo/jekyll.
+ The easier it is to apply your work, the less work the maintainers have to do,
+ which is always a good thing.
+* Please don't tag your GitHub issue with [fix], [feature], etc. The maintainers
+ actively read the issues and will label it once they come across it.
+
+Finally...
+----------
+
+Thanks! Hacking on Jekyll should be fun. If you find any of this hard to figure
+out, let us know so we can improve our process or documentation!
diff --git a/Gemfile b/Gemfile
index e45e65f..851fabc 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,2 +1,2 @@
-source :rubygems
+source 'https://rubygems.org'
gemspec
diff --git a/History.markdown b/History.markdown
new file mode 100644
index 0000000..7781f16
--- /dev/null
+++ b/History.markdown
@@ -0,0 +1,873 @@
+## HEAD
+
+### Major Enhancements
+
+### Minor Enhancements
+
+### Bug Fixes
+
+### Development Fixes
+
+### Site Enhancements
+
+## 1.4.2 / 2013-12-16
+
+### Bug Fixes
+ * Turn on Maruku fenced code blocks by default (#1830)
+
+## 1.4.1 / 2013-12-09
+
+### Major Enhancements
+
+### Minor Enhancements
+
+### Bug Fixes
+ * Don't allow nil entries when loading posts (#1796)
+
+### Development Fixes
+
+### Site Enhancements
+
+## 1.4.0 / 2013-12-07
+
+### Major Enhancements
+ * Add support for TOML config files (#1765)
+
+### Minor Enhancements
+ * Sort plugins as a way to establish a load order (#1682)
+ * Update Maruku to 0.7.0 (#1775)
+
+### Bug Fixes
+ * Add a space between two words in a Pagination warning message (#1769)
+ * Upgrade `toml` gem to `v0.1.0` to maintain compat with Ruby 1.8.7 (#1778)
+
+### Development Fixes
+ * Remove some whitespace in the code (#1755)
+ * Remove some duplication in the reading of posts and drafts (#1779)
+
+### Site Enhancements
+ * Fixed case of a word in the Jekyll v1.3.0 release post (#1762)
+ * Fixed the mime type for the favicon (#1772)
+
+## 1.3.1 / 2013-11-26
+
+### Minor Enhancements
+ * Add a `--prefix` option to passthrough for the importers (#1669)
+ * Push the paginator plugin lower in the plugin priority order so
+ other plugins run before it (#1759)
+
+### Bug Fixes
+ * Fix the include tag when ran in a loop (#1726)
+ * Fix errors when using `--watch` on 1.8.7 (#1730)
+ * Specify where the include is called from if an included file is
+ missing (#1746)
+
+### Development Fixes
+ * Extract `Site#filter_entries` into its own object (#1697)
+ * Enable Travis' bundle caching (#1734)
+ * Remove trailing whitespace in some files (#1736)
+ * Fix a duplicate test name (#1754)
+
+### Site Enhancements
+ * Update link to example Rakefile to point to specific commit (#1741)
+ * Fix drafts docs to indicate that draft time is based on file modification
+ time, not `Time.now` (#1695)
+ * Add `jekyll-monthly-archive-plugin` and `jekyll-category-archive-plugin` to
+ list of third-party plugins (#1693)
+ * Add `jekyll-asset-path-plugin` to list of third-party plugins (#1670)
+ * Add `emoji-for-jekyll` to list of third-part plugins (#1708)
+ * Fix previous section link on plugins page to point to pagination page (#1707)
+ * Add `org-mode` converter plugin to third-party plugins (#1711)
+ * Point "Blog migrations" page to http://import.jekyllrb.com (#1732)
+ * Add docs for `post_url` when posts are in subdirectories (#1718)
+ * Update the docs to point to `example.com` (#1448)
+
+## 1.3.0 / 2013-11-04
+
+### Major Enhancements
+ * Add support for adding data as YAML files under a site's `_data`
+ directory (#1003)
+ * Allow variables to be used with `include` tags (#1495)
+ * Allow using gems for plugin management (#1557)
+
+### Minor Enhancements
+ * Decrease the specificity in the site template CSS (#1574)
+ * Add `encoding` configuration option (#1449)
+ * Provide better error handling for Jekyll's custom Liquid tags
+ (#1514)
+ * If an included file causes a Liquid error, add the path to the
+ include file that caused the error to the error message (#1596)
+ * If a layout causes a Liquid error, change the error message so that
+ we know it comes from the layout (#1601)
+ * Update Kramdown dependency to `~> 1.2` (#1610)
+ * Update `safe_yaml` dependency to `~> 0.9.7` (#1602)
+ * Allow layouts to be in subfolders like includes (#1622)
+ * Switch to listen for site watching while serving (#1589)
+ * Add a `json` liquid filter to be used in sites (#1651)
+ * Point people to the migration docs when the `jekyll-import` gem is
+ missing (#1662)
+
+### Bug Fixes
+ * Fix up matching against source and destination when the two
+ locations are similar (#1556)
+ * Fix the missing `pathname` require in certain cases (#1255)
+ * Use `+` instead of `Array#concat` when building `Post` attribute list (#1571)
+ * Print server address when launching a server (#1586)
+ * Downgrade to Maruku `~> 0.6.0` in order to avoid changes in rendering (#1598)
+ * Fix error with failing include tag when variable was file name (#1613)
+ * Downcase lexers before passing them to pygments (#1615)
+ * Capitalize the short verbose switch because it conflicts with the
+ built-in Commander switch (#1660)
+ * Fix compatibility with 1.8.x (#1665)
+ * Fix an error with the new file watching code due to library version
+ incompatibilities (#1687)
+
+### Development Fixes
+ * Add coverage reporting with Coveralls (#1539)
+ * Refactor the Liquid `include` tag (#1490)
+ * Update launchy dependency to `~> 2.3` (#1608)
+ * Update rr dependency to `~> 1.1` (#1604)
+ * Update cucumber dependency to `~> 1.3` (#1607)
+ * Update coveralls dependency to `~> 0.7.0` (#1606)
+ * Update rake dependency to `~> 10.1` (#1603)
+ * Clean up `site.rb` comments to be more concise/uniform (#1616)
+ * Use the master branch for the build badge in the readme (#1636)
+ * Refactor Site#render (#1638)
+ * Remove duplication in command line options (#1637)
+ * Add tests for all the coderay options (#1543)
+ * Improve some of the cucumber test code (#1493)
+ * Improve comparisons of timestamps by ignoring the seconds (#1582)
+
+### Site Enhancements
+ * Fix params for `JekyllImport::WordPress.process` arguments (#1554)
+ * Add `jekyll-suggested-tweet` to list of third-party plugins (#1555)
+ * Link to Liquid's docs for tags and filters (#1553)
+ * Add note about installing Xcode on the Mac in the Installation docs (#1561)
+ * Simplify/generalize pagination docs (#1577)
+ * Add documentation for the new data sources feature (#1503)
+ * Add more information on how to create generators (#1590, #1592)
+ * Improve the instructions for mimicking GitHub Flavored Markdown
+ (#1614)
+ * Add `jekyll-import` warning note of missing dependencies (#1626)
+ * Fix grammar in the Usage section (#1635)
+ * Add documentation for the use of gems as plugins (#1656)
+ * Document the existence of a few additional plugins (#1405)
+ * Document that the `date_to_string` always returns a two digit day (#1663)
+ * Fix navigation in the "Working with Drafts" page (#1667)
+ * Fix an error with the data documentation (#1691)
+
+## 1.2.1 / 2013-09-14
+
+### Minor Enhancements
+ * Print better messages for detached server. Mute output on detach. (#1518)
+ * Disable reverse lookup when running `jekyll serve` (#1363)
+ * Upgrade RedCarpet dependency to `~> 2.3.0` (#1515)
+ * Upgrade to Liquid `>= 2.5.2, < 2.6` (#1536)
+
+### Bug Fixes
+ * Fix file discrepancy in gemspec (#1522)
+ * Force rendering of Include tag (#1525)
+
+### Development Fixes
+ * Add a rake task to generate a new release post (#1404)
+ * Mute LSI output in tests (#1531)
+ * Update contributor documentation (#1537)
+
+### Site Enhancements
+ * Fix a couple of validation errors on the site (#1511)
+ * Make navigation menus reusable (#1507)
+ * Fix link to History page from Release v1.2.0 notes post.
+ * Fix markup in History file for command line options (#1512)
+ * Expand 1.2 release post title to 1.2.0 (#1516)
+
+## 1.2.0 / 2013-09-06
+
+### Major Enhancements
+ * Disable automatically-generated excerpts when `excerpt_separator` is `""`. (#1386)
+ * Add checking for URL conflicts when running `jekyll doctor` (#1389)
+
+### Minor Enhancements
+ * Catch and fix invalid `paginate` values (#1390)
+ * Remove superfluous `div.container` from the default html template for
+ `jekyll new` (#1315)
+ * Add `-D` short-form switch for the drafts option (#1394)
+ * Update the links in the site template for Twitter and GitHub (#1400)
+ * Update dummy email address to example.com domain (#1408)
+ * Update normalize.css to v2.1.2 and minify; add rake task to update
+ normalize.css with greater ease. (#1430)
+ * Add the ability to detach the server ran by `jekyll serve` from it's
+ controlling terminal (#1443)
+ * Improve permalink generation for URLs with special characters (#944)
+ * Expose the current Jekyll version to posts and pages via a new
+ `jekyll.version` variable (#1481)
+
+### Bug Fixes
+ * Markdown extension matching matches only exact matches (#1382)
+ * Fixed NoMethodError when message passed to `Stevenson#message` is nil (#1388)
+ * Use binary mode when writing file (#1364)
+ * Fix 'undefined method `encoding` for "mailto"' errors w/ Ruby 1.8 and
+ Kramdown > 0.14.0 (#1397)
+ * Do not force the permalink to be a dir if it ends on .html (#963)
+ * When a Liquid Exception is caught, show the full path rel. to site source (#1415)
+ * Properly read in the config options when serving the docs locally
+ (#1444)
+ * Fixed `--layouts` option for `build` and `serve` commands (#1458)
+ * Remove kramdown as a runtime dependency since it's optional (#1498)
+ * Provide proper error handling for invalid file names in the include
+ tag (#1494)
+
+### Development Fixes
+ * Remove redundant argument to
+ Jekyll::Commands::New#scaffold_post_content (#1356)
+ * Add new dependencies to the README (#1360)
+ * Fix link to contributing page in README (#1424)
+ * Update TomDoc in Pager#initialize to match params (#1441)
+ * Refactor `Site#cleanup` into `Jekyll::Site::Cleaner` class (#1429)
+ * Several other small minor refactorings (#1341)
+ * Ignore `_site` in jekyllrb.com deploy (#1480)
+ * Add Gem version and dependency badge to README (#1497)
+
+### Site Enhancements
+ * Add info about new releases (#1353)
+ * Update plugin list with jekyll-rss plugin (#1354)
+ * Update the site list page with Ruby's official site (#1358)
+ * Add `jekyll-ditaa` to list of third-party plugins (#1370)
+ * Add `postfiles` to list of third-party plugins (#1373)
+ * For internal links, use full path including trailing `/` (#1411)
+ * Use curly apostrophes in the docs (#1419)
+ * Update the docs for Redcarpet in Jekyll (#1418)
+ * Add `pluralize` and `reading_time` filters to docs (#1439)
+ * Fix markup for the Kramdown options (#1445)
+ * Fix typos in the History file (#1454)
+ * Add trailing slash to site's post URL (#1462)
+ * Clarify that `--config` will take multiple files (#1474)
+ * Fix docs/templates.md private gist example (#1477)
+ * Use `site.repository` for Jekyll's GitHub URL (#1463)
+ * Add `jekyll-pageless-redirects` to list of third-party plugins (#1486)
+ * Clarify that `date_to_xmlschema` returns an ISO 8601 string (#1488)
+ * Add `jekyll-good-include` to list of third-party plugins (#1491)
+ * XML escape the blog post title in our feed (#1501)
+ * Add `jekyll-toc-generator` to list of third-party plugins (#1506)
+
+## 1.1.2 / 2013-07-25
+
+### Bug Fixes
+ * Require Liquid 2.5.1 (#1349)
+
+## 1.1.1 / 2013-07-24
+
+### Minor Enhancements
+ * Remove superfluous `table` selector from main.css in `jekyll new` template (#1328)
+ * Abort with non-zero exit codes (#1338)
+
+### Bug Fixes
+ * Fix up the rendering of excerpts (#1339)
+
+### Site Enhancements
+ * Add Jekyll Image Tag to the plugins list (#1306)
+ * Remove erroneous statement that `site.pages` are sorted alphabetically.
+ * Add info about the `_drafts` directory to the directory structure
+ docs (#1320)
+ * Improve the layout of the plugin listing by organizing it into
+ categories (#1310)
+ * Add generator-jekyllrb and grunt-jekyll to plugins page (#1330)
+ * Mention Kramdown as option for markdown parser on Extras page (#1318)
+ * Update Quick-Start page to include reminder that all requirements must be installed (#1327)
+ * Change filename in `include` example to an HTML file so as not to indicate that Jekyll
+ will automatically convert them. (#1303)
+ * Add an RSS feed for commits to Jekyll (#1343)
+
+## 1.1.0 / 2013-07-14
+
+### Major Enhancements
+ * Add `docs` subcommand to read Jekyll's docs when offline. (#1046)
+ * Support passing parameters to templates in `include` tag (#1204)
+ * Add support for Liquid tags to post excerpts (#1302)
+
+### Minor Enhancements
+ * Search the hierarchy of pagination path up to site root to determine template page for
+ pagination. (#1198)
+ * Add the ability to generate a new Jekyll site without a template (#1171)
+ * Use redcarpet as the default markdown engine in newly generated
+ sites (#1245, #1247)
+ * Add `redcarpet` as a runtime dependency so `jekyll build` works out-of-the-box for new
+ sites. (#1247)
+ * In the generated site, remove files that will be replaced by a
+ directory (#1118)
+ * Fail loudly if a user-specified configuration file doesn't exist (#1098)
+ * Allow for all options for Kramdown HTML Converter (#1201)
+
+### Bug Fixes
+ * Fix pagination in subdirectories. (#1198)
+ * Fix an issue with directories and permalinks that have a plus sign
+ (+) in them (#1215)
+ * Provide better error reporting when generating sites (#1253)
+ * Latest posts first in non-LSI `related_posts` (#1271)
+
+### Development Fixes
+ * Merge the theme and layout cucumber steps into one step (#1151)
+ * Restrict activesupport dependency to pre-4.0.0 to maintain compatibility with `<= 1.9.2`
+ * Include/exclude deprecation handling simplification (#1284)
+ * Convert README to Markdown. (#1267)
+ * Refactor Jekyll::Site (#1144)
+
+### Site Enhancements
+ * Add "News" section for release notes, along with an RSS feed (#1093, #1285, #1286)
+ * Add "History" page.
+ * Restructured docs sections to include "Meta" section.
+ * Add message to "Templates" page that specifies that Python must be installed in order
+ to use Pygments. (#1182)
+ * Update link to the official Maruku repo (#1175)
+ * Add documentation about `paginate_path` to "Templates" page in docs (#1129)
+ * Give the quick-start guide its own page (#1191)
+ * Update ProTip on Installation page in docs to point to all the info about Pygments and
+ the 'highlight' tag. (#1196)
+ * Run `site/img` through ImageOptim (thanks @qrush!) (#1208)
+ * Added Jade Converter to `site/docs/plugins` (#1210)
+ * Fix location of docs pages in Contributing pages (#1214)
+ * Add ReadInXMinutes plugin to the plugin list (#1222)
+ * Remove plugins from the plugin list that have equivalents in Jekyll
+ proper (#1223)
+ * Add jekyll-assets to the plugin list (#1225)
+ * Add jekyll-pandoc-mulitple-formats to the plugin list (#1229)
+ * Remove dead link to "Using Git to maintain your blog" (#1227)
+ * Tidy up the third-party plugins listing (#1228)
+ * Update contributor information (#1192)
+ * Update URL of article about Blogger migration (#1242)
+ * Specify that RedCarpet is the default for new Jekyll sites on Quickstart page (#1247)
+ * Added site.pages to Variables page in docs (#1251)
+ * Add Youku and Tudou Embed link on Plugins page. (#1250)
+ * Add note that `gist` tag supports private gists. (#1248)
+ * Add `jekyll-timeago` to list of third-party plugins. (#1260)
+ * Add `jekyll-swfobject` to list of third-party plugins. (#1263)
+ * Add `jekyll-picture-tag` to list of third-party plugins. (#1280)
+ * Update the GitHub Pages documentation regarding relative URLs
+ (#1291)
+ * Update the S3 deployment documentation (#1294)
+ * Add suggestion for Xcode CLT install to troubleshooting page in docs (#1296)
+ * Add 'Working with drafts' page to docs (#1289)
+ * Add information about time zones to the documentation for a page's
+ date (#1304)
+
+## 1.0.3 / 2013-06-07
+
+### Minor Enhancements
+ * Add support to gist tag for private gists. (#1189)
+ * Fail loudly when MaRuKu errors out (#1190)
+ * Move the building of related posts into their own class (#1057)
+ * Removed trailing spaces in several places throughout the code (#1116)
+ * Add a `--force` option to `jekyll new` (#1115)
+ * Convert IDs in the site template to classes (#1170)
+
+### Bug Fixes
+ * Fix typo in Stevenson constant "ERROR". (#1166)
+ * Rename Jekyll::Logger to Jekyll::Stevenson to fix inheritance issue (#1106)
+ * Exit with a non-zero exit code when dealing with a Liquid error (#1121)
+ * Make the `exclude` and `include` options backwards compatible with
+ versions of Jekyll prior to 1.0 (#1114)
+ * Fix pagination on Windows (#1063)
+ * Fix the application of Pygments' Generic Output style to Go code
+ (#1156)
+
+### Site Enhancements
+ * Add a Pro Tip to docs about front matter variables being optional (#1147)
+ * Add changelog to site as History page in /docs/ (#1065)
+ * Add note to Upgrading page about new config options in 1.0.x (#1146)
+ * Documentation for `date_to_rfc822` and `uri_escape` (#1142)
+ * Documentation highlight boxes shouldn't show scrollbars if not necessary (#1123)
+ * Add link to jekyll-minibundle in the doc's plugins list (#1035)
+ * Quick patch for importers documentation
+ * Fix prefix for WordpressDotCom importer in docs (#1107)
+ * Add jekyll-contentblocks plugin to docs (#1068)
+ * Make code bits in notes look more natural, more readable (#1089)
+ * Fix logic for `relative_permalinks` instructions on Upgrading page (#1101)
+ * Add docs for post excerpt (#1072)
+ * Add docs for gist tag (#1072)
+ * Add docs indicating that Pygments does not need to be installed
+ separately (#1099, #1119)
+ * Update the migrator docs to be current (#1136)
+ * Add the Jekyll Gallery Plugin to the plugin list (#1143)
+
+### Development Fixes
+ * Use Jekyll.logger instead of Jekyll::Stevenson to log things (#1149)
+ * Fix pesky Cucumber infinite loop (#1139)
+ * Do not write posts with timezones in Cucumber tests (#1124)
+ * Use ISO formatted dates in Cucumber features (#1150)
+
+## 1.0.2 / 2013-05-12
+
+### Major Enhancements
+ * Add `jekyll doctor` command to check site for any known compatibility problems (#1081)
+ * Backwards-compatibilize relative permalinks (#1081)
+
+### Minor Enhancements
+ * Add a `data-lang="<lang>"` attribute to Redcarpet code blocks (#1066)
+ * Deprecate old config `server_port`, match to `port` if `port` isn't set (#1084)
+ * Update pygments.rb version to 0.5.0 (#1061)
+ * Update Kramdown version to 1.0.2 (#1067)
+
+### Bug Fixes
+ * Fix issue when categories are numbers (#1078)
+ * Catching that Redcarpet gem isn't installed (#1059)
+
+### Site Enhancements
+ * Add documentation about `relative_permalinks` (#1081)
+ * Remove pygments-installation instructions, as pygments.rb is bundled with it (#1079)
+ * Move pages to be Pages for realz (#985)
+ * Updated links to Liquid documentation (#1073)
+
+## 1.0.1 / 2013-05-08
+
+### Minor Enhancements
+ * Do not force use of toc_token when using generate_tok in RDiscount (#1048)
+ * Add newer `language-` class name prefix to code blocks (#1037)
+ * Commander error message now preferred over process abort with incorrect args (#1040)
+
+### Bug Fixes
+ * Make Redcarpet respect the pygments configuration option (#1053)
+ * Fix the index build with LSI (#1045)
+ * Don't print deprecation warning when no arguments are specified. (#1041)
+ * Add missing `</div>` to site template used by `new` subcommand, fixed typos in code (#1032)
+
+### Site Enhancements
+ * Changed https to http in the GitHub Pages link (#1051)
+ * Remove CSS cruft, fix typos, fix HTML errors (#1028)
+ * Removing manual install of Pip and Distribute (#1025)
+ * Updated URL for Markdown references plugin (#1022)
+
+### Development Fixes
+ * Markdownify history file (#1027)
+ * Update links on README to point to new jekyllrb.com (#1018)
+
+## 1.0.0 / 2013-05-06
+
+### Major Enhancements
+ * Add `jekyll new` subcommand: generate a jekyll scaffold (#764)
+ * Refactored jekyll commands into subcommands: build, serve, and migrate. (#690)
+ * Removed importers/migrators from main project, migrated to jekyll-import sub-gem (#793)
+ * Added ability to render drafts in `_drafts` folder via command line (#833)
+ * Add ordinal date permalink style (/:categories/:year/:y_day/:title.html) (#928)
+
+### Minor Enhancements
+ * Site template HTML5-ified (#964)
+ * Use post's directory path when matching for the post_url tag (#998)
+ * Loosen dependency on Pygments so it's only required when it's needed (#1015)
+ * Parse strings into Time objects for date-related Liquid filters (#1014)
+ * Tell the user if there is no subcommand specified (#1008)
+ * Freak out if the destination of `jekyll new` exists and is non-empty (#981)
+ * Add `timezone` configuration option for compilation (#957)
+ * Add deprecation messages for pre-1.0 CLI options (#959)
+ * Refactor and colorize logging (#959)
+ * Refactor Markdown parsing (#955)
+ * Added application/vnd.apple.pkpass to mime.types served by WEBrick (#907)
+ * Move template site to default markdown renderer (#961)
+ * Expose new attribute to Liquid via `page`: `page.path` (#951)
+ * Accept multiple config files from command line (#945)
+ * Add page variable to liquid custom tags and blocks (#413)
+ * Add paginator.previous_page_path and paginator.next_page_path (#942)
+ * Backwards compatibility for 'auto' (#821, #934)
+ * Added date_to_rfc822 used on RSS feeds (#892)
+ * Upgrade version of pygments.rb to 0.4.2 (#927)
+ * Added short month (e.g. "Sep") to permalink style options for posts (#890)
+ * Expose site.baseurl to Liquid templates (#869)
+ * Adds excerpt attribute to posts which contains first paragraph of content (#837)
+ * Accept custom configuration file via CLI (#863)
+ * Load in GitHub Pages MIME Types on `jekyll serve` (#847, #871)
+ * Improve debugability of error message for a malformed highlight tag (#785)
+ * Allow symlinked files in unsafe mode (#824)
+ * Add 'gist' Liquid tag to core (#822, #861)
+ * New format of Jekyll output (#795)
+ * Reinstate `--limit_posts` and `--future` switches (#788)
+ * Remove ambiguity from command descriptions (#815)
+ * Fix SafeYAML Warnings (#807)
+ * Relaxed Kramdown version to 0.14 (#808)
+ * Aliased `jekyll server` to `jekyll serve`. (#792)
+ * Updated gem versions for Kramdown, Rake, Shoulda, Cucumber, and RedCarpet. (#744)
+ * Refactored jekyll subcommands into Jekyll::Commands submodule, which now contains them (#768)
+ * Rescue from import errors in Wordpress.com migrator (#671)
+ * Massively accelerate LSI performance (#664)
+ * Truncate post slugs when importing from Tumblr (#496)
+ * Add glob support to include, exclude option (#743)
+ * Layout of Page or Post defaults to 'page' or 'post', respectively (#580)
+ REPEALED by (#977)
+ * "Keep files" feature (#685)
+ * Output full path & name for files that don't parse (#745)
+ * Add source and destination directory protection (#535)
+ * Better YAML error message (#718)
+ * Bug Fixes
+ * Paginate in subdirectories properly (#1016)
+ * Ensure post and page URLs have a leading slash (#992)
+ * Catch all exceptions, not just StandardError descendents (#1007)
+ * Bullet-proof limit_posts option (#1004)
+ * Read in YAML as UTF-8 to accept non-ASCII chars (#836)
+ * Fix the CLI option `--plugins` to actually accept dirs and files (#993)
+ * Allow 'excerpt' in YAML Front-Matter to override the extracted excerpt (#946)
+ * Fix cascade problem with site.baseurl, site.port and site.host. (#935)
+ * Filter out directories with valid post names (#875)
+ * Fix symlinked static files not being correctly built in unsafe mode (#909)
+ * Fix integration with directory_watcher 1.4.x (#916)
+ * Accepting strings as arguments to jekyll-import command (#910)
+ * Force usage of older directory_watcher gem as 1.5 is broken (#883)
+ * Ensure all Post categories are downcase (#842, #872)
+ * Force encoding of the rdiscount TOC to UTF8 to avoid conversion errors (#555)
+ * Patch for multibyte URI problem with jekyll serve (#723)
+ * Order plugin execution by priority (#864)
+ * Fixed Page#dir and Page#url for edge cases (#536)
+ * Fix broken post_url with posts with a time in their YAML Front-Matter (#831)
+ * Look for plugins under the source directory (#654)
+ * Tumblr Migrator: finds `_posts` dir correctly, fixes truncation of long
+ post names (#775)
+ * Force Categories to be Strings (#767)
+ * Safe YAML plugin to prevent vulnerability (#777)
+ * Add SVG support to Jekyll/WEBrick. (#407, #406)
+ * Prevent custom destination from causing continuous regen on watch (#528, #820, #862)
+
+### Site Enhancements
+ * Responsify (#860)
+ * Fix spelling, punctuation and phrasal errors (#989)
+ * Update quickstart instructions with `new` command (#966)
+ * Add docs for page.excerpt (#956)
+ * Add docs for page.path (#951)
+ * Clean up site docs to prepare for 1.0 release (#918)
+ * Bring site into master branch with better preview/deploy (#709)
+ * Redesigned site (#583)
+
+### Development Fixes
+ * Exclude Cucumber 1.2.4, which causes tests to fail in 1.9.2 (#938)
+ * Added "features:html" rake task for debugging purposes, cleaned up
+ cucumber profiles (#832)
+ * Explicitly require HTTPS rubygems source in Gemfile (#826)
+ * Changed Ruby version for development to 1.9.3-p374 from p362 (#801)
+ * Including a link to the GitHub Ruby style guide in CONTRIBUTING.md (#806)
+ * Added script/bootstrap (#776)
+ * Running Simplecov under 2 conditions: ENV(COVERAGE)=true and with Ruby version
+ of greater than 1.9 (#771)
+ * Switch to Simplecov for coverage report (#765)
+
+## 0.12.1 / 2013-02-19
+### Minor Enhancements
+ * Update Kramdown version to 0.14.1 (#744)
+ * Test Enhancements
+ * Update Rake version to 10.0.3 (#744)
+ * Update Shoulda version to 3.3.2 (#744)
+ * Update Redcarpet version to 2.2.2 (#744)
+
+## 0.12.0 / 2012-12-22
+### Minor Enhancements
+ * Add ability to explicitly specify included files (#261)
+ * Add --default-mimetype option (#279)
+ * Allow setting of RedCloth options (#284)
+ * Add post_url Liquid tag for internal post linking (#369)
+ * Allow multiple plugin dirs to be specified (#438)
+ * Inline TOC token support for RDiscount (#333)
+ * Add the option to specify the paginated url format (#342)
+ * Swap out albino for pygments.rb (#569)
+ * Support Redcarpet 2 and fenced code blocks (#619)
+ * Better reporting of Liquid errors (#624)
+ * Bug Fixes
+ * Allow some special characters in highlight names
+ * URL escape category names in URL generation (#360)
+ * Fix error with limit_posts (#442)
+ * Properly select dotfile during directory scan (#363, #431, #377)
+ * Allow setting of Kramdown smart_quotes (#482)
+ * Ensure front-matter is at start of file (#562)
+
+## 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
+ (@jeffrydegrande)
+
+## 0.5.2 / 2009-06-24
+ * Enhancements
+ * Added --paginate option to the executable along with a paginator object
+ for the payload (@calavera)
+ * Upgraded RedCloth to 4.2.1, which makes `<notextile>` tags work once
+ again.
+ * Configuration options set in config.yml are now available through the
+ site payload (@vilcans)
+ * Posts can now have an empty YAML front matter or none at all
+ (@bahuvrihi)
+ * Bug Fixes
+ * Fixing Ruby 1.9 issue that requires to_s on the err object
+ (@Chrononaut)
+ * Fixes for pagination and ordering posts on the same day (@ujh)
+ * Made pages respect permalinks style and permalinks in yml front matter
+ (@eugenebolshakov)
+ * Index.html file should always have index.html permalink
+ (@eugenebolshakov)
+ * Added trailing slash to pretty permalink style so Apache is happy
+ (@eugenebolshakov)
+ * Bad markdown processor in config fails sooner and with better message
+ (@gcnovus)
+ * Allow CRLFs in yaml frontmatter (@juretta)
+ * Added Date#xmlschema for Ruby versions < 1.9
+
+## 0.5.1 / 2009-05-06
+### Major Enhancements
+ * Next/previous posts in site payload (@pantulis, @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 (@duritong)
+ * Bug Fixes
+ * Making sure config.yaml references are all gone, using only config.yml
+ * Fixed syntax highlighting breaking for UTF-8 code (@henrik)
+ * Worked around RDiscount bug that prevents Markdown from getting parsed
+ after highlight (@henrik)
+ * CGI escaped post titles (@Chrononaut)
+
+## 0.5.0 / 2009-04-07
+### Minor Enhancements
+ * Ability to set post categories via YAML (@qrush)
+ * Ability to set prevent a post from publishing via YAML (@qrush)
+ * Add textilize filter (@willcodeforfoo)
+ * Add 'pretty' permalink style for wordpress-like urls (@dysinger)
+ * Made it possible to enter categories from YAML as an array (@Chrononaut)
+ * Ignore Emacs autosave files (@Chrononaut)
+ * Bug Fixes
+ * Use block syntax of popen4 to ensure that subprocesses are properly disposed (@jqr)
+ * Close open4 streams to prevent zombies (@rtomayko)
+ * Only query required fields from the WP Database (@ariejan)
+ * Prevent `_posts` from being copied to the destination directory (@bdimcheff)
+ * Refactors
+ * Factored the filtering code into a method (@Chrononaut)
+ * Fix tests and convert to Shoulda (@qrush, @technicalpickles)
+ * Add Cucumber acceptance test suite (@qrush, @technicalpickles)
+
+## 0.4.1
+### Minor Enhancements
+ * Changed date format on wordpress converter (zeropadding) (@dysinger)
+ * Bug Fixes
+ * Add jekyll binary as executable to gemspec (@dysinger)
+
+## 0.4.0 / 2009-02-03
+### Major Enhancements
+ * Switch to Jeweler for packaging tasks
+
+### Minor Enhancements
+ * Type importer (@codeslinger)
+ * site.topics accessor (@baz)
+ * Add `array_to_sentence_string` filter (@mchung)
+ * Add a converter for textpattern (@PerfectlyNormal)
+ * Add a working Mephisto / MySQL converter (@ivey)
+ * Allowing .htaccess files to be copied over into the generated site (@briandoll)
+ * Add option to not put file date in permalink URL (@mreid)
+ * Add line number capabilities to highlight blocks (@jcon)
+ * Bug Fixes
+ * Fix permalink behavior (@cavalle)
+ * Fixed an issue with pygments, markdown, and newlines (@zpinter)
+ * Ampersands need to be escaped (@pufuwozu, @ap)
+ * Test and fix the site.categories hash (@zzot)
+ * Fix site payload available to files (@matrix9180)
+
+## 0.3.0 / 2008-12-24
+### Major Enhancements
+ * Added --server option to start a simple WEBrick server on destination
+ directory (@johnreilly and @mchung)
+
+### Minor Enhancements
+ * Added post categories based on directories containing `_posts` (@mreid)
+ * Added post topics based on directories underneath `_posts`
+ * Added new date filter that shows the full month name (@mreid)
+ * Merge Post's YAML front matter into its to_liquid payload (@remi)
+ * Restrict includes to regular files underneath `_includes`
+ * Bug Fixes
+ * Change YAML delimiter matcher so as to not chew up 2nd level markdown
+ headers (@mreid)
+ * Fix bug that meant page data (such as the date) was not available in
+ templates (@mreid)
+ * Properly reject directories in `_layouts`
+
+## 0.2.1 / 2008-12-15
+ * Major Changes
+ * Use Maruku (pure Ruby) for Markdown by default (@mreid)
+ * Allow use of RDiscount with --rdiscount flag
+
+### Minor Enhancements
+ * Don't load directory_watcher unless it's needed (@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 Enhancements
+ * 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 (@JackDanger)
+ * Bug Fixes
+ * Prevent Jekyll from picking up the output directory as a source (@JackDanger)
+ * Skip `related_posts` when there is only one post (@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 (@vanpelt)
+ * Mephisto and CSV converters (@vanpelt)
+ * Code hilighting (@vanpelt)
+ * Autobuild
+ * Bug Fixes
+ * Accept both \r\n and \n in YAML header (@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!
diff --git a/History.txt b/History.txt
deleted file mode 100644
index 884b58e..0000000
--- a/History.txt
+++ /dev/null
@@ -1,308 +0,0 @@
-== 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 <notextile> 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!
-
diff --git a/README.markdown b/README.markdown
new file mode 100644
index 0000000..3d75f28
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,56 @@
+# Jekyll
+
+[](http://badge.fury.io/rb/jekyll)
+
+[](https://travis-ci.org/mojombo/jekyll)
+[](https://codeclimate.com/github/mojombo/jekyll)
+[](https://gemnasium.com/mojombo/jekyll)
+[](https://coveralls.io/r/mojombo/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.
+
+## Getting Started
+
+* [Install](http://jekyllrb.com/docs/installation/) the gem
+* Read up about its [Usage](http://jekyllrb.com/docs/usage/) and [Configuration](http://jekyllrb.com/docs/configuration/)
+* Take a gander at some existing [Sites](http://wiki.github.com/mojombo/jekyll/sites)
+* Fork and [Contribute](http://jekyllrb.com/docs/contributing/) your own modifications
+* Have questions? Check out `#jekyll` on irc.freenode.net.
+
+## Diving In
+
+* [Migrate](http://jekyllrb.com/docs/migrations/) from your previous system
+* Learn how the [YAML Front Matter](http://jekyllrb.com/docs/frontmatter/) works
+* Put information on your site with [Variables](http://jekyllrb.com/docs/variables/)
+* Customize the [Permalinks](http://jekyllrb.com/docs/permalinks/) your posts are generated with
+* Use the built-in [Liquid Extensions](http://jekyllrb.com/docs/templates/) to make your life easier
+* Use custom [Plugins](http://jekyllrb.com/docs/plugins/) to generate content specific to your site
+
+## Runtime Dependencies
+
+* Commander: Command-line interface constructor (Ruby)
+* Colorator: Colorizes command line output (Ruby)
+* Classifier: Generating related posts (Ruby)
+* Directory Watcher: Auto-regeneration of sites (Ruby)
+* Liquid: Templating system (Ruby)
+* Maruku: Default markdown engine (Ruby)
+* Pygments.rb: Syntax highlighting (Ruby/Python)
+* RedCarpet: Markdown engine (Ruby)
+* Safe YAML: YAML Parser built for security (Ruby)
+
+## Developer Dependencies
+
+* Kramdown: Markdown-superset converter (Ruby)
+* Launchy: Cross-platform file launcher (Ruby)
+* RDiscount: Discount Markdown Processor (Ruby)
+* RedCloth: Textile support (Ruby)
+* RedGreen: Nicer test output (Ruby)
+* RR: Mocking (Ruby)
+* Shoulda: Test framework (Ruby)
+* SimpleCov: Coverage framework (Ruby)
+
+## License
+
+See [LICENSE](https://github.com/mojombo/jekyll/blob/master/LICENSE).
diff --git a/README.textile b/README.textile
deleted file mode 100644
index 4cefb9f..0000000
--- a/README.textile
+++ /dev/null
@@ -1,41 +0,0 @@
-h1. 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.
diff --git a/Rakefile b/Rakefile
index a1f4b16..b8eb85a 100644
--- a/Rakefile
+++ b/Rakefile
@@ -2,6 +2,7 @@ require 'rubygems'
require 'rake'
require 'rdoc'
require 'date'
+require 'yaml'
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
@@ -24,6 +25,10 @@ def date
Date.today.to_s
end
+def file_date
+ Date.today.strftime("%F")
+end
+
def rubyforge_project
name
end
@@ -40,33 +45,61 @@ def replace_header(head, header_name)
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
end
+def normalize_bullets(markdown)
+ markdown.gsub(/\s{2}\*{1}/, "-")
+end
+
+def linkify_prs(markdown)
+ markdown.gsub(/#(\d+)/) do |word|
+ "[#{word}]({{ site.repository }}/issues/#{word.delete("#")})"
+ end
+end
+
+def linkify_users(markdown)
+ markdown.gsub(/(@\w+)/) do |username|
+ "[#{username}](https://github.com/#{username.delete("@")})"
+ end
+end
+
+def linkify(markdown)
+ linkify_users(linkify_prs(markdown))
+end
+
+def liquid_escape(markdown)
+ markdown.gsub(/(`{[{%].+[}%]}`)/, "{% raw %}\\1{% endraw %}")
+end
+
+def remove_head_from_history(markdown)
+ index = markdown =~ /^##\s+\d+\.\d+\.\d+/
+ markdown[index..-1]
+end
+
+def converted_history(markdown)
+ remove_head_from_history(liquid_escape(linkify(normalize_bullets(markdown))))
+end
+
#############################################################################
#
# Standard tasks
#
#############################################################################
-task :default => [:test, :features]
+if RUBY_VERSION > '1.9' && ENV["TRAVIS"] == "true"
+ require 'coveralls/rake/task'
+ Coveralls::RakeTask.new
+
+ task :default => [:test, :features, 'coveralls:push']
+else
+ task :default => [:test, :features]
+end
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'
@@ -75,6 +108,21 @@ Rake::RDocTask.new do |rdoc|
rdoc.rdoc_files.include('lib/**/*.rb')
end
+begin
+ require 'cucumber/rake/task'
+ Cucumber::Rake::Task.new(:features) do |t|
+ t.profile = "travis"
+ end
+ Cucumber::Rake::Task.new(:"features:html", "Run Cucumber features and produce HTML output") do |t|
+ t.profile = "html_report"
+ 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
+
desc "Open an irb session preloaded with this library"
task :console do
sh "irb -rubygems -r ./lib/#{name}.rb"
@@ -82,34 +130,118 @@ end
#############################################################################
#
-# Custom tasks (add your own tasks here)
+# Site tasks - http://jekyllrb.com
#
#############################################################################
-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"]}")')
+namespace :site do
+ desc "Generate and view the site locally"
+ task :preview do
+ require "launchy"
+
+ # Yep, it's a hack! Wait a few seconds for the Jekyll site to generate and
+ # then open it in a browser. Someday we can do better than this, I hope.
+ Thread.new do
+ sleep 4
+ puts "Opening in browser..."
+ Launchy.open("http://localhost:4000")
+ end
+
+ # Generate the site in server mode.
+ puts "Running Jekyll..."
+ Dir.chdir("site") do
+ sh "#{File.expand_path('bin/jekyll', File.dirname(__FILE__))} serve --watch"
+ end
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"]}")')
+
+ desc "Update normalize.css library to the latest version and minify"
+ task :update_normalize_css do
+ Dir.chdir("site/css") do
+ sh 'curl "http://necolas.github.io/normalize.css/latest/normalize.css" -o "normalize.scss"'
+ sh 'sass "normalize.scss":"normalize.css" --style compressed'
+ sh 'rm "normalize.scss"'
+ end
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"]}")')
+
+ desc "Commit the local site to the gh-pages branch and publish to GitHub Pages"
+ task :publish => [:history] do
+ # Ensure the gh-pages dir exists so we can generate into it.
+ puts "Checking for gh-pages dir..."
+ unless File.exist?("./gh-pages")
+ puts "No gh-pages directory found. Run the following commands first:"
+ puts " `git clone git at github.com:mojombo/jekyll gh-pages"
+ puts " `cd gh-pages"
+ puts " `git checkout gh-pages`"
+ exit(1)
+ end
+
+ # Ensure gh-pages branch is up to date.
+ Dir.chdir('gh-pages') do
+ sh "git pull origin gh-pages"
+ end
+
+ # Copy to gh-pages dir.
+ puts "Copying site to gh-pages branch..."
+ Dir.glob("site/*") do |path|
+ next if path.include? "_site"
+ sh "cp -R #{path} gh-pages/"
+ end
+
+ # Commit and push.
+ puts "Committing and pushing to GitHub Pages..."
+ sha = `git log`.match(/[a-z0-9]{40}/)[0]
+ Dir.chdir('gh-pages') do
+ sh "git add ."
+ sh "git commit -m 'Updating to #{sha}.'"
+ sh "git push origin gh-pages"
+ end
+ puts 'Done.'
end
-end
-begin
- require 'cucumber/rake/task'
- Cucumber::Rake::Task.new(:features) do |t|
- t.cucumber_opts = "--format progress"
+ desc "Create a nicely formatted history page for the jekyll site based on the repo history."
+ task :history do
+ if File.exist?("History.markdown")
+ history_file = File.read("History.markdown")
+ front_matter = {
+ "layout" => "docs",
+ "title" => "History",
+ "permalink" => "/docs/history/",
+ "prev_section" => "contributing"
+ }
+ Dir.chdir('site/docs/') do
+ File.open("history.md", "w") do |file|
+ file.write("#{front_matter.to_yaml}---\n\n")
+ file.write(converted_history(history_file))
+ end
+ end
+ else
+ abort "You seem to have misplaced your History.markdown file. I can haz?"
+ end
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'
+
+ namespace :releases do
+ desc "Create new release post"
+ task :new, :version do |t, args|
+ raise "Specify a version: rake site:releases:new['1.2.3']" unless args.version
+ today = Time.new.strftime('%Y-%m-%d')
+ release = args.version.to_s
+ filename = "site/_posts/#{today}-jekyll-#{release.split('.').join('-')}-released.markdown"
+
+ File.open(filename, "wb") do |post|
+ post.puts("---")
+ post.puts("layout: news_item")
+ post.puts("title: 'Jekyll #{release} Released'")
+ post.puts("date: #{Time.new.strftime('%Y-%m-%d %H:%M:%S %z')}")
+ post.puts("author: ")
+ post.puts("version: #{release}")
+ post.puts("categories: [release]")
+ post.puts("---")
+ post.puts
+ post.puts
+ end
+
+ puts "Created #{filename}"
+ end
end
end
@@ -120,8 +252,8 @@ end
#############################################################################
task :release => :build do
- unless `git branch` =~ /^\* master$/
- puts "You must be on the master branch to release!"
+ unless `git branch` =~ /^(\* master|\* v1-stable)$/
+ puts "You must be on the master branch or the v1-stable branch to release!"
exit!
end
sh "git commit --allow-empty -m 'Release #{version}'"
@@ -163,4 +295,4 @@ task :gemspec do
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
File.open(gemspec_file, 'w') { |io| io.write(spec) }
puts "Updated #{gemspec_file}"
-end
\ No newline at end of file
+end
diff --git a/bin/jekyll b/bin/jekyll
index 2e33f37..8f91698 100755
--- a/bin/jekyll
+++ b/bin/jekyll
@@ -1,282 +1,158 @@
#!/usr/bin/env ruby
+STDOUT.sync = true
-$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
+$:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
-help = <<HELP
-Jekyll is a blog-aware, static site generator.
-
-Basic Command Line Usage:
- jekyll # . -> ./_site
- jekyll <path to write generated site> # . -> <path>
- jekyll <path to source> <path to write generated site> # <path> -> <path>
- jekyll import <importer name> <options> # imports posts using named import script
-
- Configuration is read from '<source>/_config.yml' but can be overriden
- using the following options:
-
-HELP
-
-require 'optparse'
+require 'commander/import'
require 'jekyll'
+Jekyll::Deprecator.process(ARGV)
-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
+program :name, 'jekyll'
+program :version, Jekyll::VERSION
+program :description, 'Jekyll is a blog-aware, static site generator in Ruby'
- opts.on("--[no-]pygments", "Use pygments to highlight code") do |pygments|
- options['pygments'] = pygments
- end
+default_command :default
- 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
+global_option '-s', '--source [DIR]', 'Source directory (defaults to ./)'
+global_option '-d', '--destination [DIR]', 'Destination directory (defaults to ./_site)'
+global_option '--safe', 'Safe mode (defaults to false)'
+global_option '-p', '--plugins PLUGINS_DIR1[,PLUGINS_DIR2[,...]]', Array, 'Plugins directory (defaults to ./_plugins)'
+global_option '--layouts DIR', String, 'Layouts directory (defaults to ./_layouts)'
- 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)
+# Option names don't always directly match the configuration value we'd like.
+# This method will rename options to match what Jekyll configuration expects.
+#
+# options - The Hash of options from Commander.
+#
+# Returns the normalized Hash.
+def normalize_options(options)
+ if drafts_state = options.delete(:drafts)
+ options[:show_drafts] = drafts_state
end
+ options
+end
- opts.on("--[no-]future", "Render future dated posts") do |future|
- options['future'] = future
- end
+def add_build_options(c)
+ c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
+ c.option '--future', 'Publishes posts with a future date'
+ c.option '--limit_posts MAX_POSTS', Integer, 'Limits the number of posts to parse and publish'
+ c.option '-w', '--watch', 'Watch for changes and rebuild'
+ c.option '--lsi', 'Use LSI for improved related posts'
+ c.option '-D', '--drafts', 'Render posts in the _drafts folder'
+ c.option '-V', '--verbose', 'Print verbose output.'
+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
+command :default do |c|
+ c.action do |args, options|
+ if args.empty?
+ command(:help).run
+ else
+ Jekyll.logger.abort_with "Invalid command. Use --help for more information"
end
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
+command :new do |c|
+ c.syntax = 'jekyll new PATH'
+ c.description = 'Creates a new Jekyll site scaffold in PATH'
- opts.on("--url [URL]", "Set custom site.url") do |url|
- options['url'] = url
- end
+ c.option '--force', 'Force creation even if PATH already exists'
+ c.option '--blank', 'Creates scaffolding but with empty files'
- opts.on("--version", "Display current version") do
- puts "Jekyll " + Jekyll::VERSION
- exit 0
+ c.action do |args, options|
+ Jekyll::Commands::New.process(args, options.__hash__)
end
end
-# Read command line options into `options` hash
-opts.parse!
-
+command :build do |c|
+ c.syntax = 'jekyll build [options]'
+ c.description = 'Build your site'
-# Check for import stuff
-if ARGV.size > 0
- if ARGV[0] == 'import'
- migrator = ARGV[1]
+ add_build_options(c)
- 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)
+ c.action do |args, options|
+ options = normalize_options(options.__hash__)
+ options = Jekyll.configuration(options)
+ Jekyll::Commands::Build.process(options)
end
end
+command :serve do |c|
+ c.syntax = 'jekyll serve [options]'
+ c.description = 'Serve your site locally'
+ add_build_options(c)
-# 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)
+ c.option '-B', '--detach', 'Run the server in the background (detach)'
+ c.option '-P', '--port [PORT]', 'Port to listen on'
+ c.option '-H', '--host [HOST]', 'Host to bind to'
+ c.option '-b', '--baseurl [URL]', 'Base URL'
-# Get source and destination directories (possibly set by config file)
-source = options['source']
-destination = options['destination']
+ c.action do |args, options|
+ options.default :serving => true
-# 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 += ['*']
+ options = normalize_options(options.__hash__)
+ options = Jekyll.configuration(options)
+ Jekyll::Commands::Build.process(options)
+ Jekyll::Commands::Serve.process(options)
end
end
+alias_command :server, :serve
-# Create the Site
-site = Jekyll::Site.new(options)
+command :doctor do |c|
+ c.syntax = 'jekyll doctor'
+ c.description = 'Search site and print specific deprecation warnings'
-# Run the directory watcher for auto-generation, if required
-if options['auto']
- require 'directory_watcher'
+ c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
- 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
+ c.action do |args, options|
+ options = normalize_options(options.__hash__)
+ options = Jekyll.configuration(options)
+ Jekyll::Commands::Doctor.process(options)
end
+end
+alias_command :hyde, :doctor
- dw.start
+command :docs do |c|
+ c.syntax = 'jekyll docs'
+ c.description = "Launch local server with docs for Jekyll v#{Jekyll::VERSION}"
- 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)
+ c.option '-p', '--port [PORT]', 'Port to listen on'
+ c.option '-u', '--host [HOST]', 'Host to bind to'
+
+ c.action do |args, options|
+ options = normalize_options(options.__hash__)
+ options = Jekyll.configuration(options.merge!({
+ 'source' => File.expand_path("../site", File.dirname(__FILE__)),
+ 'destination' => File.expand_path("../site/_site", File.dirname(__FILE__))
+ }))
+ puts options
+ Jekyll::Commands::Build.process(options)
+ Jekyll::Commands::Serve.process(options)
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'
+command :import do |c|
+ c.syntax = 'jekyll import <platform> [options]'
+ c.description = 'Import your old blog to Jekyll'
- s = HTTPServer.new(
- :Port => options['server_port'],
- :MimeTypes => mime_types
- )
- s.mount(options['baseurl'], HTTPServlet::FileHandler, destination)
- t = Thread.new {
- s.start
- }
+ c.option '--source STRING', 'Source file or URL to migrate from'
+ c.option '--file STRING', 'File to migrate from'
+ c.option '--dbname STRING', 'Database name to migrate from'
+ c.option '--user STRING', 'Username to use when migrating'
+ c.option '--pass STRING', 'Password to use when migrating'
+ c.option '--host STRING', 'Host address to use when migrating'
+ c.option '--prefix STRING', 'Database table prefix to use when migrating'
- trap("INT") { s.shutdown }
- t.join()
+ c.action do |args, options|
+ begin
+ require 'jekyll-import'
+ rescue LoadError
+ msg = "You must install the 'jekyll-import' gem before continuing.\n"
+ msg += "* Please see the documentation at http://jekyllrb.com/docs/migrations/ for instructions.\n"
+ abort msg
+ end
+ Jekyll::Commands::Import.process(args.first, options)
+ end
end
diff --git a/checksums.yaml.gz b/checksums.yaml.gz
new file mode 100644
index 0000000..9f02114
Binary files /dev/null and b/checksums.yaml.gz differ
diff --git a/cucumber.yml b/cucumber.yml
index 9692830..78342a1 100644
--- a/cucumber.yml
+++ b/cucumber.yml
@@ -1 +1,3 @@
-default: --format progress
\ No newline at end of file
+default: --format pretty
+travis: --format progress
+html_report: --format progress --format html --out=features_report.html
diff --git a/features/create_sites.feature b/features/create_sites.feature
index a7b5d9b..a25a0d3 100644
--- a/features/create_sites.feature
+++ b/features/create_sites.feature
@@ -3,6 +3,13 @@ Feature: Create sites
I want to be able to make a static site
In order to share my awesome ideas with the interwebs
+ Scenario: Blank site
+ Given I do not have a "test_blank" directory
+ When I call jekyll new with test_blank --blank
+ Then the test_blank/_layouts directory should exist
+ And the test_blank/_posts directory should exist
+ And the "test_blank/index.html" file should exist
+
Scenario: Basic site
Given I have an "index.html" file that contains "Basic Site"
When I run jekyll
@@ -13,7 +20,7 @@ Feature: Create sites
Given I have a _posts directory
And I have the following post:
| title | date | content |
- | Hackers | 3/27/2009 | My First Exploit |
+ | Hackers | 2009-03-27 | 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"
@@ -31,12 +38,23 @@ Feature: Create sites
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. |
+ | Wargames | 2009-03-27 | 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: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
+ Scenario: Basic site with layout inside a subfolder 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 | 2009-03-27 | post/simple | The only winning move is not to play. |
+ And I have a post/simple layout that contains "Post Layout: {{ content }}"
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "Post Layout: <p>The only winning move is not to play.</p>" 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 }}"
@@ -49,13 +67,13 @@ Feature: Create sites
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. |
+ | entry1 | 2009-03-27 | post | content for entry1. |
+ | entry2 | 2009-04-27 | 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. |
+ | entry3 | 2009-05-27 | post | content for entry3. |
+ | entry4 | 2009-06-27 | 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"
@@ -89,6 +107,35 @@ Feature: Create sites
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
+ 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 internal post linking
+ Given I have an "index.html" page that contains "URL: {% post_url 2020-01-31-entry2 %}"
+ And I have a configuration file with "permalink" set to "pretty"
+ And I have a _posts directory
+ And I have the following posts:
+ | title | date | layout | content |
+ | entry1 | 2007-12-31 | post | content for entry1. |
+ | entry2 | 2020-01-31 | post | content for entry2. |
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "URL: /2020/01/31/entry2/" in "_site/index.html"
+
+ Scenario: Basic site with whitelisted dotfile
+ Given I have an ".htaccess" file that contains "SomeDirective"
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "SomeDirective" in "_site/.htaccess"
+
+ Scenario: File was replaced by a directory
+ Given I have a "test" file that contains "some stuff"
+ When I run jekyll
+ Then the _site directory should exist
+ When I delete the file "test"
+ Given I have a test directory
+ And I have a "test/index.html" file that contains "some other stuff"
+ When I run jekyll
+ Then the _site/test directory should exist
+ And I should see "some other stuff" in "_site/test/index.html"
diff --git a/features/data.feature b/features/data.feature
new file mode 100644
index 0000000..33adfaa
--- /dev/null
+++ b/features/data.feature
@@ -0,0 +1,65 @@
+Feature: Data
+ In order to use well-formatted data in my blog
+ As a blog's user
+ I want to use _data directory in my site
+
+ Scenario: autoload *.yaml files in _data directory
+ Given I have a _data directory
+ And I have a "_data/products.yaml" file with content:
+ """
+ - name: sugar
+ price: 5.3
+ - name: salt
+ price: 2.5
+ """
+ And I have an "index.html" page that contains "{% for product in site.data.products %}{{product.name}}{% endfor %}"
+ When I run jekyll
+ Then the "_site/index.html" file should exist
+ And I should see "sugar" in "_site/index.html"
+ And I should see "salt" in "_site/index.html"
+
+ Scenario: autoload *.yml files in _data directory
+ Given I have a _data directory
+ And I have a "_data/members.yml" file with content:
+ """
+ - name: Jack
+ age: 28
+ - name: Leon
+ age: 34
+ """
+ And I have an "index.html" page that contains "{% for member in site.data.members %}{{member.name}}{% endfor %}"
+ When I run jekyll
+ Then the "_site/index.html" file should exist
+ And I should see "Jack" in "_site/index.html"
+ And I should see "Leon" in "_site/index.html"
+
+ Scenario: autoload *.yml files in _data directory with space in file name
+ Given I have a _data directory
+ And I have a "_data/team members.yml" file with content:
+ """
+ - name: Jack
+ age: 28
+ - name: Leon
+ age: 34
+ """
+ And I have an "index.html" page that contains "{% for member in site.data.team_members %}{{member.name}}{% endfor %}"
+ When I run jekyll
+ Then the "_site/index.html" file should exist
+ And I should see "Jack" in "_site/index.html"
+ And I should see "Leon" in "_site/index.html"
+
+ Scenario: should be backward compatible with site.data in _config.yml
+ Given I have a "_config.yml" file with content:
+ """
+ data:
+ - name: Jack
+ age: 28
+ - name: Leon
+ age: 34
+ """
+ And I have an "index.html" page that contains "{% for member in site.data %}{{member.name}}{% endfor %}"
+ When I run jekyll
+ Then the "_site/index.html" file should exist
+ And I should see "Jack" in "_site/index.html"
+ And I should see "Leon" in "_site/index.html"
+
diff --git a/features/drafts.feature b/features/drafts.feature
new file mode 100644
index 0000000..5271120
--- /dev/null
+++ b/features/drafts.feature
@@ -0,0 +1,25 @@
+Feature: Draft Posts
+ As a hacker who likes to blog
+ I want to be able to preview drafts locally
+ In order to see if they look alright before publishing
+
+ Scenario: Preview a draft
+ Given I have a configuration file with "permalink" set to "none"
+ And I have a _drafts directory
+ And I have the following draft:
+ | title | date | layout | content |
+ | Recipe | 2009-03-27 | default | Not baked yet. |
+ When I run jekyll with drafts
+ Then the _site directory should exist
+ And I should see "Not baked yet." in "_site/recipe.html"
+
+ Scenario: Don't preview a draft
+ Given I have a configuration file with "permalink" set to "none"
+ And I have an "index.html" page that contains "Totally index"
+ And I have a _drafts directory
+ And I have the following draft:
+ | title | date | layout | content |
+ | Recipe | 2009-03-27 | default | Not baked yet. |
+ When I run jekyll
+ Then the _site directory should exist
+ And the "_site/recipe.html" file should not exist
diff --git a/features/embed_filters.feature b/features/embed_filters.feature
index 61bd8da..d61901c 100644
--- a/features/embed_filters.feature
+++ b/features/embed_filters.feature
@@ -8,7 +8,7 @@ Feature: Embed filters
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -19,7 +19,7 @@ Feature: Embed filters
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. |
+ | Star & Wars | 2009-03-27 | 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
@@ -30,7 +30,7 @@ Feature: Embed filters
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -41,7 +41,7 @@ Feature: Embed filters
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -52,7 +52,7 @@ Feature: Embed filters
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. |
+ | Star Wars | 2009-03-27 | 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
diff --git a/features/include_tag.feature b/features/include_tag.feature
new file mode 100644
index 0000000..587784d
--- /dev/null
+++ b/features/include_tag.feature
@@ -0,0 +1,57 @@
+Feature: Include tags
+ In order to share their content across several pages
+ As a hacker who likes to blog
+ I want to be able to include files in my blog posts
+
+ Scenario: Include a file with parameters
+ Given I have an _includes directory
+ And I have an "_includes/header.html" file that contains "<header>My awesome blog header: {{include.param}}</header>"
+ And I have an "_includes/params.html" file that contains "Parameters:<ul>{% for param in include %}<li>{{param[0]}} = {{param[1]}}</li>{% endfor %}</ul>"
+ And I have an "_includes/ignore.html" file that contains "<footer>My blog footer</footer>"
+ And I have a _posts directory
+ And I have the following post:
+ | title | date | layout | content |
+ | Include Files | 2013-03-21 | default | {% include header.html param="myparam" %} |
+ | Ignore params if unused | 2013-03-21 | default | {% include ignore.html date="today" %} |
+ | List multiple parameters | 2013-03-21 | default | {% include params.html date="today" start="tomorrow" %} |
+ | Dont keep parameters | 2013-03-21 | default | {% include ignore.html param="test" %}\n{% include header.html %} |
+ | Allow params with spaces and quotes | 2013-04-07 | default | {% include params.html cool="param with spaces" super="\"quoted\"" single='has "quotes"' escaped='\'single\' quotes' %} |
+ | Parameter syntax | 2013-04-12 | default | {% include params.html param1_or_2="value" %} |
+ | Pass a variable | 2013-06-22 | default | {% assign var = 'some text' %}{% include params.html local=var layout=page.layout %} |
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "<header>My awesome blog header: myparam</header>" in "_site/2013/03/21/include-files.html"
+ And I should not see "myparam" in "_site/2013/03/21/ignore-params-if-unused.html"
+ And I should see "<li>date = today</li>" in "_site/2013/03/21/list-multiple-parameters.html"
+ And I should see "<li>start = tomorrow</li>" in "_site/2013/03/21/list-multiple-parameters.html"
+ And I should not see "<header>My awesome blog header: myparam</header>" in "_site/2013/03/21/dont-keep-parameters.html"
+ But I should see "<header>My awesome blog header: </header>" in "_site/2013/03/21/dont-keep-parameters.html"
+ And I should see "<li>cool = param with spaces</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
+ And I should see "<li>super = “quoted”</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
+ And I should see "<li>single = has “quotes”</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
+ And I should see "<li>escaped = ‘single’ quotes</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
+ And I should see "<li>param1_or_2 = value</li>" in "_site/2013/04/12/parameter-syntax.html"
+ And I should see "<li>local = some text</li>" in "_site/2013/06/22/pass-a-variable.html"
+ And I should see "<li>layout = default</li>" in "_site/2013/06/22/pass-a-variable.html"
+
+ Scenario: Include a file from a variable
+ Given I have an _includes directory
+ And I have an "_includes/snippet.html" file that contains "a snippet"
+ And I have an "_includes/parametrized.html" file that contains "works with {{include.what}}"
+ And I have a configuration file with:
+ | key | value |
+ | include_file1 | snippet.html |
+ | include_file2 | parametrized.html |
+ And I have an "index.html" page that contains "{% include {{site.include_file1}} %} that {% include {{site.include_file2}} what='parameters' %}"
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "a snippet that works with parameters" in "_site/index.html"
+
+ Scenario: Include a variable file in a loop
+ Given I have an _includes directory
+ And I have an "_includes/one.html" file that contains "one"
+ And I have an "_includes/two.html" file that contains "two"
+ And I have an "index.html" page with files "[one.html, two.html]" that contains "{% for file in page.files %}{% include {{file}} %} {% endfor %}"
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "one two" in "_site/index.html"
diff --git a/features/markdown.feature b/features/markdown.feature
index 859e6f7..c76b061 100644
--- a/features/markdown.feature
+++ b/features/markdown.feature
@@ -9,12 +9,12 @@ Feature: Markdown
And I have a _posts directory
And I have the following post:
| title | date | content | type |
- | Hackers | 3/27/2009 | # My Title | markdown |
+ | Hackers | 2009-03-27 | # 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 "<h1 id='my_title'>My Title</h1>" in "_site/2009/03/27/hackers.html"
- And I should see "<h1 id='my_title'>My Title</h1>" in "_site/index.html"
+ And I should see "<h1 id=\"my_title\">My Title</h1>" in "_site/2009/03/27/hackers.html"
+ And I should see "<h1 id=\"my_title\">My Title</h1>" in "_site/index.html"
Scenario: Markdown in pagination on index
Given I have a configuration file with "paginate" set to "5"
@@ -22,9 +22,46 @@ Feature: Markdown
And I have a _posts directory
And I have the following post:
| title | date | content | type |
- | Hackers | 3/27/2009 | # My Title | markdown |
+ | Hackers | 2009-03-27 | # 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 "<h1 id='my_title'>My Title</h1>" in "_site/index.html"
-
\ No newline at end of file
+ And I should see "<h1 id=\"my_title\">My Title</h1>" in "_site/index.html"
+
+ Scenario: Maruku fenced codeblocks
+ Given I have a configuration file with "markdown" set to "maruku"
+ And I have an "index.markdown" file with content:
+ """
+ ---
+ title: My title
+ ---
+
+ # My title
+
+ ```
+ My awesome code
+ ```
+ """
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "My awesome code" in "_site/index.html"
+ And I should see "<pre><code>\nMy awesome code\n</code></pre>" in "_site/index.html"
+
+ Scenario: Maruku fenced codeblocks
+ Given I have a configuration file with "markdown" set to "maruku"
+ And I have an "index.markdown" file with content:
+ """
+ ---
+ title: My title
+ ---
+
+ # My title
+
+ ```ruby
+ puts "My awesome string"
+ ```
+ """
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "My awesome string" in "_site/index.html"
+ And I should see "<pre class="ruby"><code class="ruby">\nputs "My awesome string"\n</code></pre>" in "_site/index.html"
diff --git a/features/pagination.feature b/features/pagination.feature
index 90b1057..76c6236 100644
--- a/features/pagination.feature
+++ b/features/pagination.feature
@@ -2,26 +2,81 @@ Feature: 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 "<num>"
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:
+ And I have the following posts:
| 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. |
+ | Wargames | 2009-03-27 | default | The only winning move is not to play. |
+ | Wargames2 | 2009-04-27 | default | The only winning move is not to play2. |
+ | Wargames3 | 2009-05-27 | default | The only winning move is not to play3. |
+ | Wargames4 | 2009-06-27 | default | The only winning move is not to play4. |
When I run jekyll
Then the _site/page<exist> directory should exist
And the "_site/page<exist>/index.html" file should exist
And I should see "<posts>" in "_site/page<exist>/index.html"
And the "_site/page<not_exist>/index.html" file should not exist
-
+
Examples:
| num | exist | posts | not_exist |
| 1 | 4 | 1 | 5 |
| 2 | 2 | 2 | 3 |
| 3 | 2 | 1 | 3 |
+
+ Scenario Outline: Setting a custom pagination path
+ Given I have a configuration file with:
+ | key | value |
+ | paginate | 1 |
+ | paginate_path | /blog/page-:num |
+ | permalink | /blog/:year/:month/:day/:title |
+ And I have a blog directory
+ And I have an "blog/index.html" page that contains "{{ paginator.posts.size }}"
+ And I have a _posts directory
+ And I have the following posts:
+ | title | date | layout | content |
+ | Wargames | 2009-03-27 | default | The only winning move is not to play. |
+ | Wargames2 | 2009-04-27 | default | The only winning move is not to play2. |
+ | Wargames3 | 2009-05-27 | default | The only winning move is not to play3. |
+ | Wargames4 | 2009-06-27 | default | The only winning move is not to play4. |
+ When I run jekyll
+ Then the _site/blog/page-<exist> directory should exist
+ And the "_site/blog/page-<exist>/index.html" file should exist
+ And I should see "<posts>" in "_site/blog/page-<exist>/index.html"
+ And the "_site/blog/page-<not_exist>/index.html" file should not exist
+
+ Examples:
+ | exist | posts | not_exist |
+ | 2 | 1 | 5 |
+ | 3 | 1 | 6 |
+ | 4 | 1 | 7 |
+
+ Scenario Outline: Setting a custom pagination path without an index.html in it
+ Given I have a configuration file with:
+ | key | value |
+ | paginate | 1 |
+ | paginate_path | /blog/page/:num |
+ | permalink | /blog/:year/:month/:day/:title |
+ And I have a blog directory
+ And I have an "blog/index.html" page that contains "{{ paginator.posts.size }}"
+ And I have an "index.html" page that contains "Don't pick me!"
+ And I have a _posts directory
+ And I have the following posts:
+ | title | date | layout | content |
+ | Wargames | 2009-03-27 | default | The only winning move is not to play. |
+ | Wargames2 | 2009-04-27 | default | The only winning move is not to play2. |
+ | Wargames3 | 2009-05-27 | default | The only winning move is not to play3. |
+ | Wargames4 | 2009-06-27 | default | The only winning move is not to play4. |
+ When I run jekyll
+ Then the _site/blog/page/<exist> directory should exist
+ And the "_site/blog/page/<exist>/index.html" file should exist
+ And I should see "<posts>" in "_site/blog/page/<exist>/index.html"
+ And the "_site/blog/page/<not_exist>/index.html" file should not exist
+
+ Examples:
+ | exist | posts | not_exist |
+ | 2 | 1 | 5 |
+ | 3 | 1 | 6 |
+ | 4 | 1 | 7 |
diff --git a/features/permalinks.feature b/features/permalinks.feature
index 050e75c..64b3c17 100644
--- a/features/permalinks.feature
+++ b/features/permalinks.feature
@@ -7,7 +7,7 @@ Feature: Fancy permalinks
Given I have a _posts directory
And I have the following post:
| title | date | content |
- | None Permalink Schema | 3/27/2009 | Totally nothing. |
+ | None Permalink Schema | 2009-03-27 | Totally nothing. |
And I have a configuration file with "permalink" set to "none"
When I run jekyll
Then the _site directory should exist
@@ -17,7 +17,7 @@ Feature: Fancy permalinks
Given I have a _posts directory
And I have the following post:
| title | date | content |
- | Pretty Permalink Schema | 3/27/2009 | Totally wordpress. |
+ | Pretty Permalink Schema | 2009-03-27 | Totally wordpress. |
And I have a configuration file with "permalink" set to "pretty"
When I run jekyll
Then the _site directory should exist
@@ -38,7 +38,7 @@ Feature: Fancy permalinks
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. |
+ | Custom Permalink Schema | stuff | 2009-03-27 | 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
@@ -48,7 +48,7 @@ Feature: Fancy permalinks
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. |
+ | Custom Permalink Schema | stuff | 2009-03-27 | 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
@@ -58,8 +58,28 @@ Feature: Fancy permalinks
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. |
+ | Custom Permalink Schema | stuff | 2009-03-27 | 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"
+
+ Scenario: Use per-post permalink
+ Given I have a _posts directory
+ And I have the following post:
+ | title | date | permalink | content |
+ | Some post | 2013-04-14 | /custom/posts/1 | bla bla |
+ When I run jekyll
+ Then the _site directory should exist
+ And the _site/custom/posts/1 directory should exist
+ And I should see "bla bla" in "_site/custom/posts/1/index.html"
+
+ Scenario: Use per-post ending in .html
+ Given I have a _posts directory
+ And I have the following post:
+ | title | date | permalink | content |
+ | Some post | 2013-04-14 | /custom/posts/some.html | bla bla |
+ When I run jekyll
+ Then the _site directory should exist
+ And the _site/custom/posts directory should exist
+ And I should see "bla bla" in "_site/custom/posts/some.html"
diff --git a/features/post_data.feature b/features/post_data.feature
index c6d45b0..34f5818 100644
--- a/features/post_data.feature
+++ b/features/post_data.feature
@@ -8,7 +8,7 @@ Feature: Post data
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -19,7 +19,7 @@ Feature: Post data
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -30,7 +30,7 @@ Feature: Post data
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -41,7 +41,7 @@ Feature: Post data
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -52,7 +52,7 @@ Feature: Post data
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -64,7 +64,7 @@ Feature: Post data
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -75,7 +75,7 @@ Feature: Post data
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. |
+ | Star Wars | 2009-05-18 | 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
@@ -88,7 +88,20 @@ Feature: Post data
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. |
+ | Star Wars | 2009-03-27 | 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 categories are in folders with mixed case
+ 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 | 2009-03-27 | 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
@@ -99,29 +112,77 @@ Feature: Post data
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. |
+ | Star Wars | 2009-03-27 | 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 category is in YAML and is mixed-case
+ 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 | 2009-03-27 | 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
+ 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 | categories | content |
- | Star Wars | 3/27/2009 | simple | ['scifi', 'movies'] | Luke, I am your father. |
+ | title | date | layout | category | content |
+ | Star Wars | 2009-03-27 | 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 with mixed case
+ Given I have a _posts directory
+ And I have a _layouts directory
+ And I have the following posts:
+ | title | date | layout | categories | content |
+ | Star Wars | 2009-03-27 | simple | ['scifi', 'Movies'] | Luke, I am your father. |
+ | Star Trek | 2013-03-17 | simple | ['SciFi', 'movies'] | Jean Luc, 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"
+ And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2013/03/17/star-trek.html"
+
+ Scenario Outline: Use page.path variable
+ Given I have a <dir>/_posts directory
+ And I have the following post in "<dir>":
+ | title | type | date | content |
+ | my-post | html | 2013-04-12 | Source path: {{ page.path }} |
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "Source path: <path_prefix>_posts/2013-04-12-my-post.html" in "_site/<dir>/2013/04/12/my-post.html"
+
+ Examples:
+ | dir | path_prefix |
+ | . | |
+ | dir | dir/ |
+ | dir/nested | dir/nested/ |
+
+ Scenario: Override page.path variable
+ Given I have a _posts directory
+ And I have the following post:
+ | title | date | path | content |
+ | override | 2013-04-12 | override-path.html | Custom path: {{ page.path }} |
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "Custom path: override-path.html" in "_site/2013/04/12/override.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. |
+ | Star Wars | 2009-03-27 | 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
@@ -132,7 +193,7 @@ Feature: Post data
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. |
+ | Star Wars | 2009-03-27 | 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
@@ -143,9 +204,9 @@ Feature: Post data
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 |
+ | Star Wars | 2009-03-27 | ordered | Darth Vader | Luke, I am your father. |
+ | Some like it hot | 2009-04-27 | ordered | Osgood | Nobody is perfect. |
+ | Terminator | 2009-05-27 | 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
diff --git a/features/post_excerpts.feature b/features/post_excerpts.feature
new file mode 100644
index 0000000..09e4133
--- /dev/null
+++ b/features/post_excerpts.feature
@@ -0,0 +1,50 @@
+Feature: Post excerpts
+ 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
+ But some people can only focus for a few moments
+ So just give them a taste
+
+ Scenario: An excerpt without a layout
+ Given I have an "index.html" page that contains "{% for post in site.posts %}{{ post.excerpt }}{% endfor %}"
+ And I have a _posts directory
+ And I have the following posts:
+ | title | date | layout | content |
+ | entry1 | 2007-12-31 | post | content for entry1. |
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see exactly "<p>content for entry1.</p>" in "_site/index.html"
+
+ Scenario: An excerpt from a post with a layout
+ Given I have an "index.html" page that contains "{% for post in site.posts %}{{ post.excerpt }}{% endfor %}"
+ And I have a _posts directory
+ And I have a _layouts directory
+ And I have a post layout that contains "{{ page.excerpt }}"
+ And I have the following posts:
+ | title | date | layout | content |
+ | entry1 | 2007-12-31 | post | content for entry1. |
+ When I run jekyll
+ Then the _site directory should exist
+ And the _site/2007 directory should exist
+ And the _site/2007/12 directory should exist
+ And the _site/2007/12/31 directory should exist
+ And the "_site/2007/12/31/entry1.html" file should exist
+ And I should see exactly "<p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
+ And I should see exactly "<p>content for entry1.</p>" in "_site/index.html"
+
+ Scenario: An excerpt from a post with a layout which has context
+ Given I have an "index.html" page that contains "{% for post in site.posts %}{{ post.excerpt }}{% endfor %}"
+ And I have a _posts directory
+ And I have a _layouts directory
+ And I have a post layout that contains "<html><head></head><body>{{ page.excerpt }}</body></html>"
+ And I have the following posts:
+ | title | date | layout | content |
+ | entry1 | 2007-12-31 | post | content for entry1. |
+ When I run jekyll
+ Then the _site directory should exist
+ And the _site/2007 directory should exist
+ And the _site/2007/12 directory should exist
+ And the _site/2007/12/31 directory should exist
+ And the "_site/2007/12/31/entry1.html" file should exist
+ And I should see exactly "<p>content for entry1.</p>" in "_site/index.html"
+ And I should see exactly "<html><head></head><body><p>content for entry1.</p></body></html>" in "_site/2007/12/31/entry1.html"
diff --git a/features/site_configuration.feature b/features/site_configuration.feature
index 8d3bee5..4052315 100644
--- a/features/site_configuration.feature
+++ b/features/site_configuration.feature
@@ -3,7 +3,7 @@ Feature: Site configuration
I want to be able to configure jekyll
In order to make setting up a site easier
- Scenario: Change destination directory
+ Scenario: Change source 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"
@@ -18,11 +18,32 @@ Feature: Site configuration
Then the _mysite directory should exist
And I should see "Changing destination directory" in "_mysite/index.html"
+ Scenario Outline: Similarly named source and destination
+ Given I have a blank site in "<source>"
+ And I have an "<source>/index.md" page that contains "markdown"
+ And I have a configuration file with:
+ | key | value |
+ | source | <source> |
+ | destination | <dest> |
+ When I run jekyll
+ Then the <source> directory should exist
+ And the "<dest>/index.html" file should <file_exist> exist
+ And I should see "markdown" in "<source>/index.md"
+
+ Examples:
+ | source | dest | file_exist |
+ | mysite_source | mysite | |
+ | mysite | mysite_dest | |
+ | mysite/ | mysite | not |
+ | mysite | ./mysite | not |
+ | mysite/source | mysite | not |
+ | mysite | mysite/dest | |
+
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"
+ 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
@@ -46,28 +67,28 @@ Feature: Site configuration
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 "<a href="http://google.com">Google</a>" in "_site/index.html"
+ And I should see "<a href=\"http://google.com\">Google</a>" 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 "<a href="http://google.com">Google</a>" in "_site/index.html"
+ And I should see "<a href=\"http://google.com\">Google</a>" 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 "<a href="http://google.com">Google</a>" in "_site/index.html"
+ And I should see "<a href=\"http://google.com\">Google</a>" 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 "<a href='http://google.com'>Google</a>" in "_site/index.html"
+ And I should see "<a href=\"http://google.com\">Google</a>" in "_site/index.html"
Scenario: Highlight code with pygments
Given I have an "index.html" file that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}"
@@ -88,8 +109,8 @@ Feature: Site configuration
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. |
+ | entry1 | 2007-12-31 | post | content for entry1. |
+ | entry2 | 2020-01-31 | 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"
@@ -108,14 +129,54 @@ Feature: Site configuration
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. |
+ | entry1 | 2007-12-31 | post | content for entry1. |
+ | entry2 | 2020-01-31 | 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: <p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
And I should see "Post Layout: <p>content for entry2.</p>" in "_site/2020/01/31/entry2.html"
+ Scenario: Generate proper dates with explicitly set timezone (same as posts' time)
+ Given I have a _layouts directory
+ And I have a page layout that contains "Page Layout: {{ site.posts.size }}"
+ And I have a post layout that contains "Post Layout: {{ content }} built at {{ page.date | date_to_xmlschema }}"
+ And I have an "index.html" page with layout "page" that contains "site index page"
+ And I have a configuration file with:
+ | key | value |
+ | timezone | America/New_York |
+ And I have a _posts directory
+ And I have the following posts:
+ | title | date | layout | content |
+ | entry1 | 2013-04-09 23:22 -0400 | post | content for entry1. |
+ | entry2 | 2013-04-10 03:14 -0400 | post | content for entry2. |
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "Page Layout: 2" in "_site/index.html"
+ And I should see "Post Layout: <p>content for entry1.</p> built at 2013-04-09T23:22:00-04:00" in "_site/2013/04/09/entry1.html"
+ And I should see "Post Layout: <p>content for entry2.</p> built at 2013-04-10T03:14:00-04:00" in "_site/2013/04/10/entry2.html"
+
+ Scenario: Generate proper dates with explicitly set timezone (different than posts' time)
+ Given I have a _layouts directory
+ And I have a page layout that contains "Page Layout: {{ site.posts.size }}"
+ And I have a post layout that contains "Post Layout: {{ content }} built at {{ page.date | date_to_xmlschema }}"
+ And I have an "index.html" page with layout "page" that contains "site index page"
+ And I have a configuration file with:
+ | key | value |
+ | timezone | Australia/Melbourne |
+ And I have a _posts directory
+ And I have the following posts:
+ | title | date | layout | content |
+ | entry1 | 2013-04-09 23:22 -0400 | post | content for entry1. |
+ | entry2 | 2013-04-10 03:14 -0400 | post | content for entry2. |
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "Page Layout: 2" in "_site/index.html"
+ And the "_site/2013/04/10/entry1.html" file should exist
+ And the "_site/2013/04/10/entry2.html" file should exist
+ And I should see escaped "Post Layout: <p>content for entry1.</p> built at 2013-04-10T13:22:00+10:00" in "_site/2013/04/10/entry1.html"
+ And I should see escaped "Post Layout: <p>content for entry2.</p> built at 2013-04-10T17:14:00+10:00" in "_site/2013/04/10/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:
@@ -123,11 +184,52 @@ Feature: Site configuration
| 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 |
+ | Apples | 2009-03-27 | An article about apples |
+ | Oranges | 2009-04-01 | An article about oranges |
+ | Bananas | 2009-04-05 | 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
+
+ Scenario: Copy over normally excluded files when they are explicitly included
+ Given I have a ".gitignore" file that contains ".DS_Store"
+ And I have an ".htaccess" file that contains "SomeDirective"
+ And I have a configuration file with "include" set to:
+ | value |
+ | .gitignore |
+ | .foo |
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see ".DS_Store" in "_site/.gitignore"
+ And the "_site/.htaccess" file should not exist
+
+ Scenario: Using a different layouts directory
+ Given I have a _theme directory
+ And I have a page theme that contains "Page Layout: {{ site.posts.size }} on {{ site.time | date: "%Y-%m-%d" }}"
+ And I have a post theme 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 |
+ | layouts | _theme |
+ And I have a _posts directory
+ And I have the following posts:
+ | title | date | layout | content |
+ | entry1 | 2007-12-31 | post | content for entry1. |
+ | entry2 | 2020-01-31 | 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: <p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
+ And I should see "Post Layout: <p>content for entry2.</p>" in "_site/2020/01/31/entry2.html"
+
+ Scenario: Add a gem-based plugin
+ Given I have an "index.html" file that contains "Whatever"
+ And I have a configuration file with "gems" set to "[jekyll_test_plugin]"
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "Whatever" in "_site/index.html"
+ And I should see "this is a test" in "_site/test.txt"
diff --git a/features/site_data.feature b/features/site_data.feature
index 0a0b1a7..faa266b 100644
--- a/features/site_data.feature
+++ b/features/site_data.feature
@@ -4,10 +4,29 @@ Feature: Site data
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 at me.com"
+ Given I have an "contact.html" page with title "Contact" that contains "{{ page.title }}: email at example.com"
When I run jekyll
Then the _site directory should exist
- And I should see "Contact: email at me.com" in "_site/contact.html"
+ And I should see "Contact: email at example.com" in "_site/contact.html"
+
+ Scenario Outline: Use page.path variable in a page
+ Given I have a <dir> directory
+ And I have a "<path>" page that contains "Source path: {{ page.path }}"
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "Source path: <path>" in "_site/<path>"
+
+ Examples:
+ | dir | path |
+ | . | index.html |
+ | dir | dir/about.html |
+ | dir/nested | dir/nested/page.html |
+
+ Scenario: Override page.path
+ Given I have an "override.html" page with path "custom-override.html" that contains "Custom path: {{ page.path }}"
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "Custom path: custom-override.html" in "_site/override.html"
Scenario: Use site.time variable
Given I have an "index.html" page that contains "{{ site.time }}"
@@ -20,9 +39,9 @@ Feature: Site data
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 |
+ | First Post | 2009-03-25 | My First Post |
+ | Second Post | 2009-03-26 | My Second Post |
+ | Third Post | 2009-03-27 | 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"
@@ -32,9 +51,9 @@ Feature: Site data
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 |
+ | First Post | 2009-03-25 | My First Post |
+ | Second Post | 2009-03-26 | My Second Post |
+ | Third Post | 2009-03-27 | 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"
@@ -44,8 +63,8 @@ Feature: Site data
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 |
+ | Awesome Hack | 2009-03-26 | code | puts 'Hello World' |
+ | Delicious Beer | 2009-03-26 | food | 1) Yuengling |
When I run jekyll
Then the _site directory should exist
And I should see "Awesome Hack" in "_site/index.html"
@@ -55,7 +74,7 @@ Feature: Site data
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 |
+ | Delicious Beer | 2009-03-26 | beer | 1) Yuengling |
When I run jekyll
Then the _site directory should exist
And I should see "Yuengling" in "_site/index.html"
@@ -65,18 +84,24 @@ Feature: Site data
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 |
+ | first | 2009-02-26 | first |
+ | A | 2009-03-26 | A |
+ | B | 2009-03-26 | B |
+ | C | 2009-03-26 | C |
+ | last | 2009-04-26 | 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"
+ And I have a configuration file with "url" set to "http://example.com"
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "http://example.com" in "_site/index.html"
+
+ Scenario: Access Jekyll version via jekyll.version
+ Given I have an "index.html" page that contains "{{ jekyll.version }}"
When I run jekyll
Then the _site directory should exist
- And I should see "http://mysite.com" in "_site/index.html"
+ And I should see "\d+\.\d+\.\d+" in "_site/index.html"
diff --git a/features/step_definitions/jekyll_steps.rb b/features/step_definitions/jekyll_steps.rb
index 27239bd..7a74486 100644
--- a/features/step_definitions/jekyll_steps.rb
+++ b/features/step_definitions/jekyll_steps.rb
@@ -1,15 +1,17 @@
Before do
+ FileUtils.rm_rf(TEST_DIR)
FileUtils.mkdir(TEST_DIR)
Dir.chdir(TEST_DIR)
end
-After do
- Dir.chdir(TEST_DIR)
- FileUtils.rm_rf(TEST_DIR)
-end
+World(Test::Unit::Assertions)
Given /^I have a blank site in "(.*)"$/ do |path|
- FileUtils.mkdir(path)
+ FileUtils.mkdir_p(path)
+end
+
+Given /^I do not have a "(.*)" directory$/ do |path|
+ File.directory?("#{TEST_DIR}/#{path}")
end
# Like "I have a foo file" but gives a yaml front matter so jekyll actually processes it
@@ -21,21 +23,34 @@ Given /^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$/ do |
---
#{text}
EOF
- f.close
end
end
Given /^I have an? "(.*)" file that contains "(.*)"$/ do |file, text|
File.open(file, 'w') do |f|
f.write(text)
- f.close
end
end
-Given /^I have a (.*) layout that contains "(.*)"$/ do |layout, text|
- File.open(File.join('_layouts', layout + '.html'), 'w') do |f|
+Given /^I have an? (.*) (layout|theme) that contains "(.*)"$/ do |name, type, text|
+ folder = if type == 'layout'
+ '_layouts'
+ else
+ '_theme'
+ end
+ destination_file = File.join(folder, name + '.html')
+ destination_path = File.dirname(destination_file)
+ unless File.exist?(destination_path)
+ FileUtils.mkdir_p(destination_path)
+ end
+ File.open(destination_file, 'w') do |f|
+ f.write(text)
+ end
+end
+
+Given /^I have an? "(.*)" file with content:$/ do |file, text|
+ File.open(file, 'w') do |f|
f.write(text)
- f.close
end
end
@@ -43,28 +58,33 @@ Given /^I have an? (.*) directory$/ do |dir|
FileUtils.mkdir_p(dir)
end
-Given /^I have the following posts?(?: (.*) "(.*)")?:$/ do |direction, folder, table|
+Given /^I have the following (draft|post)s?(?: (in|under) "([^"]+)")?:$/ do |status, direction, folder, table|
table.hashes.each do |post|
- date = Date.strptime(post['date'], '%m/%d/%Y').strftime('%Y-%m-%d')
- title = post['title'].downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
-
- if direction && direction == "in"
- before = folder || '.'
- elsif direction && direction == "under"
- after = folder || '.'
+ title = slug(post['title'])
+ ext = post['type'] || 'textile'
+ before, after = location(folder, direction)
+
+ if "draft" == status
+ folder_post = '_drafts'
+ filename = "#{title}.#{ext}"
+ elsif "post" == status
+ parsed_date = Time.xmlschema(post['date']) rescue Time.parse(post['date'])
+ folder_post = '_posts'
+ filename = "#{parsed_date.strftime('%Y-%m-%d')}-#{title}.#{ext}"
end
- path = File.join(before || '.', '_posts', after || '.', "#{date}-#{title}.#{post['type'] || 'textile'}")
+ path = File.join(before, folder_post, after, filename)
matter_hash = {}
- %w(title layout tag tags category categories published author).each do |key|
+ %w(title layout tag tags category categories published author path date permalink).each do |key|
matter_hash[key] = post[key] if post[key]
end
matter = matter_hash.map { |k, v| "#{k}: #{v}\n" }.join.chomp
- content = post['content']
- if post['input'] && post['filter']
- content = "{{ #{post['input']} | #{post['filter']} }}"
+ content = if post['input'] && post['filter']
+ "{{ #{post['input']} | #{post['filter']} }}"
+ else
+ post['content']
end
File.open(path, 'w') do |f|
@@ -74,7 +94,6 @@ Given /^I have the following posts?(?: (.*) "(.*)")?:$/ do |direction, folder, t
---
#{content}
EOF
- f.close
end
end
end
@@ -82,7 +101,6 @@ end
Given /^I have a configuration file with "(.*)" set to "(.*)"$/ do |key, value|
File.open('_config.yml', 'w') do |f|
f.write("#{key}: #{value}\n")
- f.close
end
end
@@ -91,7 +109,6 @@ Given /^I have a configuration file with:$/ do |table|
table.hashes.each do |row|
f.write("#{row["key"]}: #{row["value"]}\n")
end
- f.close
end
end
@@ -101,7 +118,6 @@ Given /^I have a configuration file with "([^\"]*)" set to:$/ do |key, table|
table.hashes.each do |row|
f.write("- #{row["value"]}\n")
end
- f.close
end
end
@@ -110,6 +126,14 @@ When /^I run jekyll$/ do
run_jekyll
end
+When /^I run jekyll with drafts$/ do
+ run_jekyll(:drafts => true)
+end
+
+When /^I call jekyll new with test_blank --blank$/ do
+ call_jekyll_new(:path => "test_blank", :blank => true)
+end
+
When /^I debug jekyll$/ do
run_jekyll(:debug => true)
end
@@ -120,26 +144,46 @@ When /^I change "(.*)" to contain "(.*)"$/ do |file, text|
end
end
-Then /^the (.*) directory should exist$/ do |dir|
- assert File.directory?(dir)
+When /^I delete the file "(.*)"$/ do |file|
+ File.delete(file)
+end
+
+Then /^the (.*) directory should +exist$/ do |dir|
+ assert File.directory?(dir), "The directory \"#{dir}\" does not exist"
+end
+
+Then /^the (.*) directory should not exist$/ do |dir|
+ assert !File.directory?(dir), "The directory \"#{dir}\" exists"
end
Then /^I should see "(.*)" in "(.*)"$/ do |text, file|
- assert_match Regexp.new(text), File.open(file).readlines.join
+ assert_match Regexp.new(text), file_contents(file)
+end
+
+Then /^I should see exactly "(.*)" in "(.*)"$/ do |text, file|
+ assert_equal text, file_contents(file).strip
+end
+
+Then /^I should not see "(.*)" in "(.*)"$/ do |text, file|
+ assert_no_match Regexp.new(text), file_contents(file)
+end
+
+Then /^I should see escaped "(.*)" in "(.*)"$/ do |text, file|
+ assert_match Regexp.new(Regexp.escape(text)), file_contents(file)
end
-Then /^the "(.*)" file should exist$/ do |file|
- assert File.file?(file)
+Then /^the "(.*)" file should +exist$/ do |file|
+ assert File.file?(file), "The file \"#{file}\" does not exist"
end
Then /^the "(.*)" file should not exist$/ do |file|
- assert !File.exists?(file)
+ assert !File.exists?(file), "The file \"#{file}\" exists"
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
+ assert_match Regexp.new(seconds_agnostic_time(Time.now)), file_contents(file)
end
Then /^I should see today's date in "(.*)"$/ do |file|
- assert_match Regexp.new(Date.today.to_s), File.open(file).readlines.join
+ assert_match Regexp.new(Date.today.to_s), file_contents(file)
end
diff --git a/features/support/env.rb b/features/support/env.rb
index 3166ce9..0d207b4 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -1,19 +1,75 @@
+if RUBY_VERSION > '1.9'
+ require 'coveralls'
+ Coveralls.wear_merged!
+end
+
require 'fileutils'
require 'rr'
require 'test/unit'
-
-World do
- include Test::Unit::Assertions
-end
+require 'time'
TEST_DIR = File.join('/', 'tmp', 'jekyll')
-JEKYLL_PATH = File.join(ENV['PWD'], 'bin', 'jekyll')
+JEKYLL_PATH = File.join(File.dirname(__FILE__), '..', '..', 'bin', 'jekyll')
def run_jekyll(opts = {})
- command = JEKYLL_PATH
+ command = JEKYLL_PATH.clone
+ command << " build"
+ command << " --drafts" if opts[:drafts]
command << " >> /dev/null 2>&1" if opts[:debug].nil?
system command
end
+def call_jekyll_new(opts = {})
+ command = JEKYLL_PATH.clone
+ command << " new"
+ command << " #{opts[:path]}" if opts[:path]
+ command << " --blank" if opts[:blank]
+ command << " >> /dev/null 2>&1" if opts[:debug].nil?
+ system command
+end
+
+def slug(title)
+ title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
+end
+
+def location(folder, direction)
+ if folder
+ before = folder if direction == "in"
+ after = folder if direction == "under"
+ end
+ [before || '.', after || '.']
+end
+
+def file_contents(path)
+ File.open(path) do |file|
+ file.readlines.join # avoid differences with \n and \r\n line endings
+ end
+end
+
+def seconds_agnostic_datetime(datetime = Time.now)
+ pieces = datetime.to_s.split(" ")
+ if pieces.size == 6 # Ruby 1.8.7
+ date = pieces[0..2].join(" ")
+ time = seconds_agnostic_time(pieces[3])
+ zone = pieces[4..5].join(" ")
+ else # Ruby 1.9.1 or greater
+ date, time, zone = pieces
+ time = seconds_agnostic_time(time)
+ end
+ [
+ Regexp.escape(date),
+ "#{time}:\\d{2}",
+ Regexp.escape(zone)
+ ].join("\\ ")
+end
+
+def seconds_agnostic_time(time)
+ if time.is_a? Time
+ time = time.strftime("%H:%M:%S")
+ end
+ hour, minutes, _ = time.split(":")
+ "#{hour}:#{minutes}"
+end
+
# work around "invalid option: --format" cucumber bug (see #296)
Test::Unit.run = true if RUBY_VERSION < '1.9'
diff --git a/jekyll.gemspec b/jekyll.gemspec
index def6b56..1306fed 100644
--- a/jekyll.gemspec
+++ b/jekyll.gemspec
@@ -4,8 +4,9 @@ Gem::Specification.new do |s|
s.rubygems_version = '1.3.5'
s.name = 'jekyll'
- s.version = '0.11.2'
- s.date = '2011-12-27'
+ s.version = '1.4.2'
+ s.license = 'MIT'
+ s.date = '2013-12-16'
s.rubyforge_project = 'jekyll'
s.summary = "A simple, blog aware, static site generator."
@@ -20,81 +21,209 @@ Gem::Specification.new do |s|
s.executables = ["jekyll"]
s.rdoc_options = ["--charset=UTF-8"]
- s.extra_rdoc_files = %w[README.textile LICENSE]
+ s.extra_rdoc_files = %w[README.markdown LICENSE]
- s.add_runtime_dependency('liquid', "~> 2.3")
+ s.add_runtime_dependency('liquid', "~> 2.5.2")
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_runtime_dependency('listen', "~> 1.3")
+ s.add_runtime_dependency('maruku', "~> 0.7.0")
+ s.add_runtime_dependency('pygments.rb', "~> 0.5.0")
+ s.add_runtime_dependency('commander', "~> 4.1.3")
+ s.add_runtime_dependency('safe_yaml', "~> 0.9.7")
+ s.add_runtime_dependency('colorator', "~> 0.1")
+ s.add_runtime_dependency('redcarpet', "~> 2.3.0")
+ s.add_runtime_dependency('toml', '~> 0.1.0')
- s.add_development_dependency('rake', "~> 0.9")
+ s.add_development_dependency('rake', "~> 10.1")
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('shoulda', "~> 3.3.2")
+ s.add_development_dependency('rr', "~> 1.1")
+ s.add_development_dependency('cucumber', "~> 1.3")
s.add_development_dependency('RedCloth', "~> 4.2")
+ s.add_development_dependency('kramdown', "~> 1.2")
s.add_development_dependency('rdiscount', "~> 1.6")
- s.add_development_dependency('redcarpet', "~> 1.9")
-
+ s.add_development_dependency('launchy', "~> 2.3")
+ s.add_development_dependency('simplecov', "~> 0.7")
+ s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1")
+ s.add_development_dependency('coveralls', "~> 0.7.0")
+ s.add_development_dependency('mime-types', "~> 1.5")
+ s.add_development_dependency('activesupport', '~> 3.2.13')
+ s.add_development_dependency('jekyll_test_plugin')
+
# = MANIFEST =
s.files = %w[
+ CONTRIBUTING.markdown
Gemfile
- History.txt
+ History.markdown
LICENSE
- README.textile
+ README.markdown
Rakefile
bin/jekyll
cucumber.yml
features/create_sites.feature
+ features/data.feature
+ features/drafts.feature
features/embed_filters.feature
+ features/include_tag.feature
features/markdown.feature
features/pagination.feature
features/permalinks.feature
features/post_data.feature
+ features/post_excerpts.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/cleaner.rb
+ lib/jekyll/command.rb
+ lib/jekyll/commands/build.rb
+ lib/jekyll/commands/doctor.rb
+ lib/jekyll/commands/new.rb
+ lib/jekyll/commands/serve.rb
+ lib/jekyll/configuration.rb
lib/jekyll/converter.rb
lib/jekyll/converters/identity.rb
lib/jekyll/converters/markdown.rb
+ lib/jekyll/converters/markdown/kramdown_parser.rb
+ lib/jekyll/converters/markdown/maruku_parser.rb
+ lib/jekyll/converters/markdown/rdiscount_parser.rb
+ lib/jekyll/converters/markdown/redcarpet_parser.rb
lib/jekyll/converters/textile.rb
lib/jekyll/convertible.rb
lib/jekyll/core_ext.rb
+ lib/jekyll/deprecator.rb
+ lib/jekyll/draft.rb
+ lib/jekyll/entry_filter.rb
lib/jekyll/errors.rb
+ lib/jekyll/excerpt.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/mime.types
lib/jekyll/page.rb
lib/jekyll/plugin.rb
lib/jekyll/post.rb
+ lib/jekyll/related_posts.rb
lib/jekyll/site.rb
lib/jekyll/static_file.rb
+ lib/jekyll/stevenson.rb
+ lib/jekyll/tags/gist.rb
lib/jekyll/tags/highlight.rb
lib/jekyll/tags/include.rb
+ lib/jekyll/tags/post_url.rb
+ lib/jekyll/url.rb
+ lib/site_template/.gitignore
+ lib/site_template/_config.yml
+ lib/site_template/_layouts/default.html
+ lib/site_template/_layouts/post.html
+ lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb
+ lib/site_template/css/main.css
+ lib/site_template/css/syntax.css
+ lib/site_template/index.html
+ script/bootstrap
+ site/.gitignore
+ site/CNAME
+ site/README
+ site/_config.yml
+ site/_includes/analytics.html
+ site/_includes/docs_contents.html
+ site/_includes/docs_contents_mobile.html
+ site/_includes/docs_option.html
+ site/_includes/docs_ul.html
+ site/_includes/footer.html
+ site/_includes/header.html
+ site/_includes/news_contents.html
+ site/_includes/news_contents_mobile.html
+ site/_includes/news_item.html
+ site/_includes/primary-nav-items.html
+ site/_includes/section_nav.html
+ site/_includes/top.html
+ site/_layouts/default.html
+ site/_layouts/docs.html
+ site/_layouts/news.html
+ site/_layouts/news_item.html
+ site/_posts/2013-05-06-jekyll-1-0-0-released.markdown
+ site/_posts/2013-05-08-jekyll-1-0-1-released.markdown
+ site/_posts/2013-05-12-jekyll-1-0-2-released.markdown
+ site/_posts/2013-06-07-jekyll-1-0-3-released.markdown
+ site/_posts/2013-07-14-jekyll-1-1-0-released.markdown
+ site/_posts/2013-07-24-jekyll-1-1-1-released.markdown
+ site/_posts/2013-07-25-jekyll-1-0-4-released.markdown
+ site/_posts/2013-07-25-jekyll-1-1-2-released.markdown
+ site/_posts/2013-09-06-jekyll-1-2-0-released.markdown
+ site/_posts/2013-09-14-jekyll-1-2-1-released.markdown
+ site/_posts/2013-10-28-jekyll-1-3-0-rc1-released.markdown
+ site/_posts/2013-11-04-jekyll-1-3-0-released.markdown
+ site/_posts/2013-11-26-jekyll-1-3-1-released.markdown
+ site/_posts/2013-12-07-jekyll-1-4-0-released.markdown
+ site/_posts/2013-12-16-jekyll-1-4-2-released.markdown
+ site/css/gridism.css
+ site/css/normalize.css
+ site/css/pygments.css
+ site/css/style.css
+ site/docs/configuration.md
+ site/docs/contributing.md
+ site/docs/datafiles.md
+ site/docs/deployment-methods.md
+ site/docs/drafts.md
+ site/docs/extras.md
+ site/docs/frontmatter.md
+ site/docs/github-pages.md
+ site/docs/heroku.md
+ site/docs/history.md
+ site/docs/index.md
+ site/docs/installation.md
+ site/docs/migrations.md
+ site/docs/pages.md
+ site/docs/pagination.md
+ site/docs/permalinks.md
+ site/docs/plugins.md
+ site/docs/posts.md
+ site/docs/quickstart.md
+ site/docs/resources.md
+ site/docs/sites.md
+ site/docs/structure.md
+ site/docs/templates.md
+ site/docs/troubleshooting.md
+ site/docs/upgrading.md
+ site/docs/usage.md
+ site/docs/variables.md
+ site/favicon.png
+ site/feed.xml
+ site/freenode.txt
+ site/img/article-footer.png
+ site/img/footer-arrow.png
+ site/img/footer-logo.png
+ site/img/logo-2x.png
+ site/img/octojekyll.png
+ site/img/tube.png
+ site/img/tube1x.png
+ site/index.html
+ site/js/modernizr-2.5.3.min.js
+ site/news/index.html
+ site/news/releases/index.html
+ test/fixtures/broken_front_matter1.erb
+ test/fixtures/broken_front_matter2.erb
+ test/fixtures/broken_front_matter3.erb
+ test/fixtures/exploit_front_matter.erb
+ test/fixtures/front_matter.erb
test/helper.rb
+ test/source/+/foo.md
test/source/.htaccess
+ test/source/_config.dev.toml
+ test/source/_data/languages.yml
+ test/source/_data/members.yaml
+ test/source/_data/products.yml
+ test/source/_includes/params.html
test/source/_includes/sig.markdown
test/source/_layouts/default.html
+ test/source/_layouts/post/simple.html
test/source/_layouts/simple.html
+ test/source/_plugins/dummy.rb
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
@@ -120,29 +249,52 @@ Gem::Specification.new do |s|
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/_posts/2013-01-02-post-excerpt.markdown
+ test/source/_posts/2013-01-12-nil-layout.textile
+ test/source/_posts/2013-01-12-no-layout.textile
+ test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep
+ test/source/_posts/2013-04-11-custom-excerpt.markdown
+ test/source/_posts/2013-05-10-number-category.textile
+ test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown
+ test/source/_posts/2013-08-01-mkdn-extension.mkdn
+ test/source/_posts/es/2008-11-21-nested.textile
test/source/about.html
test/source/category/_posts/2008-9-23-categories.textile
test/source/contacts.html
+ test/source/contacts/bar.html
+ test/source/contacts/index.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/products.yml
test/source/sitemap.xml
+ test/source/symlink-test/_data
+ test/source/symlink-test/symlinked-dir
+ test/source/symlink-test/symlinked-file
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_command.rb
test/test_configuration.rb
+ test/test_convertible.rb
test/test_core_ext.rb
+ test/test_entry_filter.rb
+ test/test_excerpt.rb
test/test_filters.rb
test/test_generated_site.rb
test/test_kramdown.rb
+ test/test_new_command.rb
test/test_page.rb
test/test_pager.rb
test/test_post.rb
test/test_rdiscount.rb
test/test_redcarpet.rb
+ test/test_redcloth.rb
+ test/test_related_posts.rb
test/test_site.rb
test/test_tags.rb
+ test/test_url.rb
]
# = MANIFEST =
diff --git a/lib/jekyll.rb b/lib/jekyll.rb
index 859060c..4d6af06 100644
--- a/lib/jekyll.rb
+++ b/lib/jekyll.rb
@@ -18,115 +18,83 @@ require 'rubygems'
# stdlib
require 'fileutils'
require 'time'
-require 'yaml'
+require 'safe_yaml'
require 'English'
+require 'pathname'
# 3rd party
require 'liquid'
require 'maruku'
-require 'albino'
+require 'colorator'
+require 'toml'
# internal requires
require 'jekyll/core_ext'
+require 'jekyll/stevenson'
+require 'jekyll/deprecator'
+require 'jekyll/configuration'
require 'jekyll/site'
require 'jekyll/convertible'
+require 'jekyll/url'
require 'jekyll/layout'
require 'jekyll/page'
require 'jekyll/post'
+require 'jekyll/excerpt'
+require 'jekyll/draft'
require 'jekyll/filters'
require 'jekyll/static_file'
require 'jekyll/errors'
+require 'jekyll/related_posts'
+require 'jekyll/cleaner'
+require 'jekyll/entry_filter'
# extensions
require 'jekyll/plugin'
require 'jekyll/converter'
require 'jekyll/generator'
+require 'jekyll/command'
+
+require_all 'jekyll/commands'
require_all 'jekyll/converters'
+require_all 'jekyll/converters/markdown'
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'),
+SafeYAML::OPTIONS[:suppress_warnings] = true
- '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'
- }
- }
- }
+module Jekyll
+ VERSION = '1.4.2'
# 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
+ # the defaults and the config file. See Jekyll::Configuration::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 <source>/_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
+ config = Configuration[Configuration::DEFAULTS]
+ override = Configuration[override].stringify_keys
+ config = config.read_config_files(config.config_files(override))
# Merge DEFAULTS < _config.yml < override
- Jekyll::DEFAULTS.deep_merge(config).deep_merge(override)
+ config = config.deep_merge(override).stringify_keys
+ set_timezone(config['timezone']) if config['timezone']
+
+ config
+ end
+
+ # Static: Set the TZ environment variable to use the timezone specified
+ #
+ # timezone - the IANA Time Zone
+ #
+ # Returns nothing
+ def self.set_timezone(timezone)
+ ENV['TZ'] = timezone
+ end
+
+ def self.logger
+ @logger ||= Stevenson.new
end
end
diff --git a/lib/jekyll/cleaner.rb b/lib/jekyll/cleaner.rb
new file mode 100644
index 0000000..e3a89b4
--- /dev/null
+++ b/lib/jekyll/cleaner.rb
@@ -0,0 +1,73 @@
+require 'set'
+
+module Jekyll
+ class Site
+ # Handles the cleanup of a site's destination before it is built.
+ class Cleaner
+ def initialize(site)
+ @site = site
+ end
+
+ # Cleans up the site's destination directory
+ def cleanup!
+ FileUtils.rm_rf(obsolete_files)
+ end
+
+ private
+
+ # Private: The list of files and directories to be deleted during cleanup process
+ #
+ # Returns an Array of the file and directory paths
+ def obsolete_files
+ (existing_files - new_files - new_dirs + replaced_files).to_a
+ end
+
+ # Private: The list of existing files, apart from those included in keep_files and hidden files.
+ #
+ # Returns a Set with the file paths
+ def existing_files
+ files = Set.new
+ Dir.glob(File.join(@site.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
+ files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
+ end
+ files
+ end
+
+ # Private: The list of files to be created when site is built.
+ #
+ # Returns a Set with the file paths
+ def new_files
+ files = Set.new
+ @site.each_site_file { |item| files << item.destination(@site.dest) }
+ files
+ end
+
+ # Private: The list of directories to be created when site is built.
+ # These are the parent directories of the files in #new_files.
+ #
+ # Returns a Set with the directory paths
+ def new_dirs
+ new_files.map { |file| File.dirname(file) }.to_set
+ end
+
+ # Private: The list of existing files that will be replaced by a directory during build
+ #
+ # Returns a Set with the file paths
+ def replaced_files
+ new_dirs.select { |dir| File.file?(dir) }.to_set
+ end
+
+ # Private: Creates a regular expression from the config's keep_files array
+ #
+ # Examples
+ # ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
+ #
+ # Returns the regular expression
+ def keep_file_regex
+ or_list = @site.keep_files.join("|")
+ pattern = "\/(#{or_list.gsub(".", "\.")})"
+ Regexp.new pattern
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/command.rb b/lib/jekyll/command.rb
new file mode 100644
index 0000000..911d85b
--- /dev/null
+++ b/lib/jekyll/command.rb
@@ -0,0 +1,27 @@
+module Jekyll
+ class Command
+ def self.globs(source, destination)
+ Dir.chdir(source) do
+ dirs = Dir['*'].select { |x| File.directory?(x) }
+ dirs -= [destination, File.expand_path(destination), File.basename(destination)]
+ dirs = dirs.map { |x| "#{x}/**/*" }
+ dirs += ['*']
+ end
+ end
+
+ # Static: Run Site#process and catch errors
+ #
+ # site - the Jekyll::Site object
+ #
+ # Returns nothing
+ def self.process_site(site)
+ site.process
+ rescue Jekyll::FatalException => e
+ puts
+ Jekyll.logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:"
+ Jekyll.logger.error "", "------------------------------------"
+ Jekyll.logger.error "", e.message
+ exit(1)
+ end
+ end
+end
diff --git a/lib/jekyll/commands/build.rb b/lib/jekyll/commands/build.rb
new file mode 100644
index 0000000..bfc69aa
--- /dev/null
+++ b/lib/jekyll/commands/build.rb
@@ -0,0 +1,70 @@
+module Jekyll
+ module Commands
+ class Build < Command
+ def self.process(options)
+ site = Jekyll::Site.new(options)
+
+ self.build(site, options)
+ self.watch(site, options) if options['watch']
+ end
+
+ # Private: Build the site from source into destination.
+ #
+ # site - A Jekyll::Site instance
+ # options - A Hash of options passed to the command
+ #
+ # Returns nothing.
+ def self.build(site, options)
+ source = options['source']
+ destination = options['destination']
+ Jekyll.logger.info "Source:", source
+ Jekyll.logger.info "Destination:", destination
+ print Jekyll.logger.formatted_topic "Generating..."
+ self.process_site(site)
+ puts "done."
+ end
+
+ # Private: Watch for file changes and rebuild the site.
+ #
+ # site - A Jekyll::Site instance
+ # options - A Hash of options passed to the command
+ #
+ # Returns nothing.
+ def self.watch(site, options)
+ require 'listen'
+
+ source = options['source']
+ destination = options['destination']
+
+ begin
+ dest = Pathname.new(destination).relative_path_from(Pathname.new(source)).to_s
+ ignored = Regexp.new(Regexp.escape(dest))
+ rescue ArgumentError
+ # Destination is outside the source, no need to ignore it.
+ ignored = nil
+ end
+
+ Jekyll.logger.info "Auto-regeneration:", "enabled"
+
+ listener = Listen::Listener.new(source, :ignore => ignored) do |modified, added, removed|
+ t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
+ n = modified.length + added.length + removed.length
+ print Jekyll.logger.formatted_topic("Regenerating:") + "#{n} files at #{t} "
+ self.process_site(site)
+ puts "...done."
+ end
+ listener.start
+
+ unless options['serving']
+ trap("INT") do
+ listener.stop
+ puts " Halting auto-regeneration."
+ exit 0
+ end
+
+ loop { sleep 1000 }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/commands/doctor.rb b/lib/jekyll/commands/doctor.rb
new file mode 100644
index 0000000..7ebab90
--- /dev/null
+++ b/lib/jekyll/commands/doctor.rb
@@ -0,0 +1,67 @@
+module Jekyll
+ module Commands
+ class Doctor < Command
+ class << self
+ def process(options)
+ site = Jekyll::Site.new(options)
+ site.read
+
+ if healthy?(site)
+ Jekyll.logger.info "Your test results", "are in. Everything looks fine."
+ else
+ abort
+ end
+ end
+
+ def healthy?(site)
+ [
+ !deprecated_relative_permalinks(site),
+ !conflicting_urls(site)
+ ].all?
+ end
+
+ def deprecated_relative_permalinks(site)
+ contains_deprecated_pages = false
+ site.pages.each do |page|
+ if page.uses_relative_permalinks
+ Jekyll.logger.warn "Deprecation:", "'#{page.path}' uses relative" +
+ " permalinks which will be deprecated in" +
+ " Jekyll v1.2 and beyond."
+ contains_deprecated_pages = true
+ end
+ end
+ contains_deprecated_pages
+ end
+
+ def conflicting_urls(site)
+ conflicting_urls = false
+ urls = {}
+ urls = collect_urls(urls, site.pages, site.dest)
+ urls = collect_urls(urls, site.posts, site.dest)
+ urls.each do |url, paths|
+ if paths.size > 1
+ conflicting_urls = true
+ Jekyll.logger.warn "Conflict:", "The URL '#{url}' is the destination" +
+ " for the following pages: #{paths.join(", ")}"
+ end
+ end
+ conflicting_urls
+ end
+
+ private
+
+ def collect_urls(urls, things, destination)
+ things.each do |thing|
+ dest = thing.destination(destination)
+ if urls[dest]
+ urls[dest] << thing.path
+ else
+ urls[dest] = [thing.path]
+ end
+ end
+ urls
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/commands/new.rb b/lib/jekyll/commands/new.rb
new file mode 100644
index 0000000..00b08c2
--- /dev/null
+++ b/lib/jekyll/commands/new.rb
@@ -0,0 +1,67 @@
+require 'erb'
+
+module Jekyll
+ module Commands
+ class New < Command
+ def self.process(args, options = {})
+ raise ArgumentError.new('You must specify a path.') if args.empty?
+
+ new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
+ FileUtils.mkdir_p new_blog_path
+ if preserve_source_location?(new_blog_path, options)
+ Jekyll.logger.error "Conflict:", "#{new_blog_path} exists and is not empty."
+ exit(1)
+ end
+
+ if options[:blank]
+ create_blank_site new_blog_path
+ else
+ create_sample_files new_blog_path
+
+ File.open(File.expand_path(self.initialized_post_name, new_blog_path), "w") do |f|
+ f.write(self.scaffold_post_content)
+ end
+ end
+
+ puts "New jekyll site installed in #{new_blog_path}."
+ end
+
+ def self.create_blank_site(path)
+ Dir.chdir(path) do
+ FileUtils.mkdir(%w(_layouts _posts _drafts))
+ FileUtils.touch("index.html")
+ end
+ end
+
+ def self.scaffold_post_content
+ ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
+ end
+
+ # Internal: Gets the filename of the sample post to be created
+ #
+ # Returns the filename of the sample post, as a String
+ def self.initialized_post_name
+ "_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
+ end
+
+ private
+
+ def self.preserve_source_location?(path, options)
+ !options[:force] && !Dir["#{path}/**/*"].empty?
+ end
+
+ def self.create_sample_files(path)
+ FileUtils.cp_r site_template + '/.', path
+ FileUtils.rm File.expand_path(scaffold_path, path)
+ end
+
+ def self.site_template
+ File.expand_path("../../site_template", File.dirname(__FILE__))
+ end
+
+ def self.scaffold_path
+ "_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/commands/serve.rb b/lib/jekyll/commands/serve.rb
new file mode 100644
index 0000000..8e8d00b
--- /dev/null
+++ b/lib/jekyll/commands/serve.rb
@@ -0,0 +1,65 @@
+# -*- encoding: utf-8 -*-
+module Jekyll
+ module Commands
+ class Serve < Command
+ def self.process(options)
+ require 'webrick'
+ include WEBrick
+
+ destination = options['destination']
+
+ FileUtils.mkdir_p(destination)
+
+ # recreate NondisclosureName under utf-8 circumstance
+ fh_option = WEBrick::Config::FileHandler
+ fh_option[:NondisclosureName] = ['.ht*','~*']
+
+ s = HTTPServer.new(webrick_options(options))
+
+ s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
+
+ Jekyll.logger.info "Server address:", "http://#{s.config[:BindAddress]}:#{s.config[:Port]}"
+
+ if options['detach'] # detach the server
+ pid = Process.fork { s.start }
+ Process.detach(pid)
+ Jekyll.logger.info "Server detatched with pid '#{pid}'.", "Run `kill -9 #{pid}' to stop the server."
+ else # create a new server thread, then join it with current terminal
+ t = Thread.new { s.start }
+ trap("INT") { s.shutdown }
+ t.join()
+ end
+ end
+
+ def self.webrick_options(config)
+ opts = {
+ :Port => config['port'],
+ :BindAddress => config['host'],
+ :MimeTypes => self.mime_types,
+ :DoNotReverseLookup => true,
+ :StartCallback => start_callback(config['detach'])
+ }
+
+ if !config['verbose']
+ opts.merge!({
+ :AccessLog => [],
+ :Logger => Log::new([], Log::WARN)
+ })
+ end
+
+ opts
+ end
+
+ def self.start_callback(detached)
+ unless detached
+ Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
+ end
+ end
+
+ def self.mime_types
+ mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
+ WEBrick::HTTPUtils::load_mime_types(mime_types_file)
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/configuration.rb b/lib/jekyll/configuration.rb
new file mode 100644
index 0000000..86aca28
--- /dev/null
+++ b/lib/jekyll/configuration.rb
@@ -0,0 +1,238 @@
+# encoding: UTF-8
+
+module Jekyll
+ class Configuration < Hash
+
+ # Default options. Overridden by values in _config.yml.
+ # Strings rather than symbols are used for compatibility with YAML.
+ DEFAULTS = {
+ 'source' => Dir.pwd,
+ 'destination' => File.join(Dir.pwd, '_site'),
+ 'plugins' => '_plugins',
+ 'layouts' => '_layouts',
+ 'data_source' => '_data',
+ 'keep_files' => ['.git','.svn'],
+ 'gems' => [],
+
+ 'timezone' => nil, # use the local timezone
+
+ 'encoding' => nil, # use the system encoding
+
+ 'safe' => false,
+ 'detach' => false, # default to not detaching the server
+ 'show_drafts' => nil,
+ 'limit_posts' => 0,
+ 'lsi' => false,
+ 'future' => true, # remove and make true just default
+ 'pygments' => true,
+
+ 'relative_permalinks' => true, # backwards-compatibility with < 1.0
+ # will be set to false once 2.0 hits
+
+ 'markdown' => 'maruku',
+ 'permalink' => 'date',
+ 'baseurl' => '/',
+ 'include' => ['.htaccess'],
+ 'exclude' => [],
+ 'paginate_path' => '/page:num',
+
+ 'markdown_ext' => 'markdown,mkd,mkdn,md',
+ 'textile_ext' => 'textile',
+
+ 'port' => '4000',
+ 'host' => '0.0.0.0',
+
+ 'excerpt_separator' => "\n\n",
+
+ 'maruku' => {
+ 'fenced_code_blocks' => true,
+ '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',
+ 'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
+ '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'
+ }
+ },
+
+ 'redcloth' => {
+ 'hard_breaks' => true
+ }
+ }
+
+ # Public: Turn all keys into string
+ #
+ # Return a copy of the hash where all its keys are strings
+ def stringify_keys
+ reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) }
+ end
+
+ # Public: Directory of the Jekyll source folder
+ #
+ # override - the command-line options hash
+ #
+ # Returns the path to the Jekyll source directory
+ def source(override)
+ override['source'] || self['source'] || DEFAULTS['source']
+ end
+
+ def safe_load_file(filename)
+ case File.extname(filename)
+ when '.toml'
+ TOML.load_file(filename)
+ when /\.y(a)?ml/
+ YAML.safe_load_file(filename)
+ else
+ raise ArgumentError, "No parser for '#{filename}' is available. Use a .toml or .y(a)ml file instead."
+ end
+ end
+
+ # Public: Generate list of configuration files from the override
+ #
+ # override - the command-line options hash
+ #
+ # Returns an Array of config files
+ def config_files(override)
+ # Get configuration from <source>/_config.yml or <source>/<config_file>
+ config_files = override.delete('config')
+ if config_files.to_s.empty?
+ config_files = File.join(source(override), "_config.yml")
+ @default_config_file = true
+ end
+ config_files = [config_files] unless config_files.is_a? Array
+ config_files
+ end
+
+ # Public: Read configuration and return merged Hash
+ #
+ # file - the path to the YAML file to be read in
+ #
+ # Returns this configuration, overridden by the values in the file
+ def read_config_file(file)
+ next_config = safe_load_file(file)
+ raise ArgumentError.new("Configuration file: (INVALID) #{file}".yellow) unless next_config.is_a?(Hash)
+ Jekyll.logger.info "Configuration file:", file
+ next_config
+ rescue SystemCallError
+ if @default_config_file
+ Jekyll.logger.warn "Configuration file:", "none"
+ {}
+ else
+ Jekyll.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
+ raise LoadError, "The Configuration file '#{file}' could not be found."
+ end
+ end
+
+ # Public: Read in a list of configuration files and merge with this hash
+ #
+ # files - the list of configuration file paths
+ #
+ # Returns the full configuration, with the defaults overridden by the values in the
+ # configuration files
+ def read_config_files(files)
+ configuration = clone
+
+ begin
+ files.each do |config_file|
+ new_config = read_config_file(config_file)
+ configuration = configuration.deep_merge(new_config)
+ end
+ rescue ArgumentError => err
+ Jekyll.logger.warn "WARNING:", "Error reading configuration. " +
+ "Using defaults (and options)."
+ $stderr.puts "#{err}"
+ end
+
+ configuration.fix_common_issues.backwards_compatibilize
+ end
+
+ # Public: Split a CSV string into an array containing its values
+ #
+ # csv - the string of comma-separated values
+ #
+ # Returns an array of the values contained in the CSV
+ def csv_to_array(csv)
+ csv.split(",").map(&:strip)
+ end
+
+ # Public: Ensure the proper options are set in the configuration to allow for
+ # backwards-compatibility with Jekyll pre-1.0
+ #
+ # Returns the backwards-compatible configuration
+ def backwards_compatibilize
+ config = clone
+ # Provide backwards-compatibility
+ if config.has_key?('auto') || config.has_key?('watch')
+ Jekyll.logger.warn "Deprecation:", "Auto-regeneration can no longer" +
+ " be set from your configuration file(s). Use the"+
+ " --watch/-w command-line option instead."
+ config.delete('auto')
+ config.delete('watch')
+ end
+
+ if config.has_key? 'server'
+ Jekyll.logger.warn "Deprecation:", "The 'server' configuration option" +
+ " is no longer accepted. Use the 'jekyll serve'" +
+ " subcommand to serve your site with WEBrick."
+ config.delete('server')
+ end
+
+ if config.has_key? 'server_port'
+ Jekyll.logger.warn "Deprecation:", "The 'server_port' configuration option" +
+ " has been renamed to 'port'. Please update your config" +
+ " file accordingly."
+ # copy but don't overwrite:
+ config['port'] = config['server_port'] unless config.has_key?('port')
+ config.delete('server_port')
+ end
+
+ %w[include exclude].each do |option|
+ if config.fetch(option, []).is_a?(String)
+ Jekyll.logger.warn "Deprecation:", "The '#{option}' configuration option" +
+ " must now be specified as an array, but you specified" +
+ " a string. For now, we've treated the string you provided" +
+ " as a list of comma-separated values."
+ config[option] = csv_to_array(config[option])
+ end
+ end
+ config
+ end
+
+ def fix_common_issues
+ config = clone
+
+ if config.has_key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
+ Jekyll.logger.warn "Config Warning:", "The `paginate` key must be a" +
+ " positive integer or nil. It's currently set to '#{config['paginate'].inspect}'."
+ config['paginate'] = nil
+ end
+
+ config
+ end
+
+ end
+end
diff --git a/lib/jekyll/converter.rb b/lib/jekyll/converter.rb
index c2528d1..e2dc279 100644
--- a/lib/jekyll/converter.rb
+++ b/lib/jekyll/converter.rb
@@ -1,5 +1,4 @@
module 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
@@ -46,5 +45,4 @@ module Jekyll
self.class.pygments_suffix
end
end
-
-end
\ No newline at end of file
+end
diff --git a/lib/jekyll/converters/identity.rb b/lib/jekyll/converters/identity.rb
index 7d9628c..69171b0 100644
--- a/lib/jekyll/converters/identity.rb
+++ b/lib/jekyll/converters/identity.rb
@@ -1,22 +1,21 @@
module Jekyll
+ module Converters
+ class Identity < Converter
+ safe true
- class IdentityConverter < Converter
- safe true
+ priority :lowest
- priority :lowest
+ def matches(ext)
+ true
+ end
- def matches(ext)
- true
- end
-
- def output_ext(ext)
- ext
- end
+ def output_ext(ext)
+ ext
+ end
- def convert(content)
- content
+ def convert(content)
+ content
+ end
end
-
end
-
end
diff --git a/lib/jekyll/converters/markdown.rb b/lib/jekyll/converters/markdown.rb
index b565547..485cac8 100644
--- a/lib/jekyll/converters/markdown.rb
+++ b/lib/jekyll/converters/markdown.rb
@@ -1,125 +1,43 @@
module 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']}")
+ module Converters
+ class Markdown < Converter
+ safe true
+
+ pygments_prefix "\n"
+ pygments_suffix "\n"
+
+ def setup
+ return if @setup
+ @parser = case @config['markdown']
+ when 'redcarpet'
+ RedcarpetParser.new @config
+ when 'kramdown'
+ KramdownParser.new @config
+ when 'rdiscount'
+ RDiscountParser.new @config
+ when 'maruku'
+ MarukuParser.new @config
+ else
+ STDERR.puts "Invalid Markdown processor: #{@config['markdown']}"
+ STDERR.puts " Valid options are [ maruku | rdiscount | kramdown | redcarpet ]"
+ raise FatalException.new("Invalid Markdown process: #{@config['markdown']}")
+ end
+ @setup = true
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 matches(ext)
+ rgx = '^\.(' + @config['markdown_ext'].gsub(',','|') +')$'
+ ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
+ 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'],
+ def output_ext(ext)
+ ".html"
+ end
- :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
+ def convert(content)
+ setup
+ @parser.convert(content)
end
end
end
-
end
diff --git a/lib/jekyll/converters/markdown/kramdown_parser.rb b/lib/jekyll/converters/markdown/kramdown_parser.rb
new file mode 100644
index 0000000..caeb5b6
--- /dev/null
+++ b/lib/jekyll/converters/markdown/kramdown_parser.rb
@@ -0,0 +1,29 @@
+module Jekyll
+ module Converters
+ class Markdown
+ class KramdownParser
+ def initialize(config)
+ require 'kramdown'
+ @config = config
+ 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
+
+ def convert(content)
+ # Check for use of coderay
+ if @config['kramdown']['use_coderay']
+ %w[wrap line_numbers line_numbers_start tab_width bold_every css default_lang].each do |opt|
+ key = "coderay_#{opt}"
+ @config['kramdown'][key] = @config['kramdown']['coderay'][key] unless @config['kramdown'].has_key?(key)
+ end
+ end
+
+ Kramdown::Document.new(content, @config["kramdown"].symbolize_keys).to_html
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/converters/markdown/maruku_parser.rb b/lib/jekyll/converters/markdown/maruku_parser.rb
new file mode 100644
index 0000000..1e27e47
--- /dev/null
+++ b/lib/jekyll/converters/markdown/maruku_parser.rb
@@ -0,0 +1,56 @@
+module Jekyll
+ module Converters
+ class Markdown
+ class MarukuParser
+ def initialize(config)
+ require 'maruku'
+ @config = config
+ @errors = []
+ load_divs_library if @config['maruku']['use_divs']
+ load_blahtext_library if @config['maruku']['use_tex']
+ enable_fenced_code_blocks if @config['maruku']['fenced_code_blocks']
+ 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
+
+ def load_divs_library
+ require 'maruku/ext/div'
+ STDERR.puts 'Maruku: Using extended syntax for div elements.'
+ end
+
+ def load_blahtext_library
+ 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
+
+ def enable_fenced_code_blocks
+ MaRuKu::Globals[:fenced_code_blocks] = true
+ end
+
+ def print_errors_and_fail
+ print @errors.join
+ raise MaRuKu::Exception, "MaRuKu encountered problem(s) while converting your markup."
+ end
+
+ def convert(content)
+ converted = Maruku.new(content, :error_stream => @errors).to_html.strip
+ print_errors_and_fail unless @errors.empty?
+ converted
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/converters/markdown/rdiscount_parser.rb b/lib/jekyll/converters/markdown/rdiscount_parser.rb
new file mode 100644
index 0000000..bfe1a7c
--- /dev/null
+++ b/lib/jekyll/converters/markdown/rdiscount_parser.rb
@@ -0,0 +1,37 @@
+module Jekyll
+ module Converters
+ class Markdown
+ class RDiscountParser
+ def initialize(config)
+ require 'rdiscount'
+ @config = config
+ @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
+
+ def convert(content)
+ rd = RDiscount.new(content, *@rdiscount_extensions)
+ html = rd.to_html
+ if @config['rdiscount']['toc_token']
+ html = replace_generated_toc(rd, html, @config['rdiscount']['toc_token'])
+ end
+ html
+ end
+
+ private
+ def replace_generated_toc(rd, html, toc_token)
+ if rd.generate_toc && html.include?(toc_token)
+ utf8_toc = rd.toc_content
+ utf8_toc.force_encoding('utf-8') if utf8_toc.respond_to?(:force_encoding)
+ html.gsub(toc_token, utf8_toc)
+ else
+ html
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/converters/markdown/redcarpet_parser.rb b/lib/jekyll/converters/markdown/redcarpet_parser.rb
new file mode 100644
index 0000000..9af8057
--- /dev/null
+++ b/lib/jekyll/converters/markdown/redcarpet_parser.rb
@@ -0,0 +1,70 @@
+module Jekyll
+ module Converters
+ class Markdown
+ class RedcarpetParser
+
+ module CommonMethods
+ def add_code_tags(code, lang)
+ code = code.sub(/<pre>/, "<pre><code class=\"#{lang} language-#{lang}\" data-lang=\"#{lang}\">")
+ code = code.sub(/<\/pre>/,"</code></pre>")
+ end
+ end
+
+ module WithPygments
+ include CommonMethods
+ def block_code(code, lang)
+ require 'pygments'
+ lang = lang && lang.split.first || "text"
+ output = add_code_tags(
+ Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }),
+ lang
+ )
+ end
+ end
+
+ module WithoutPygments
+ require 'cgi'
+
+ include CommonMethods
+
+ def code_wrap(code)
+ "<div class=\"highlight\"><pre>#{CGI::escapeHTML(code)}</pre></div>"
+ end
+
+ def block_code(code, lang)
+ lang = lang && lang.split.first || "text"
+ output = add_code_tags(code_wrap(code), lang)
+ end
+ end
+
+ def initialize(config)
+ require 'redcarpet'
+ @config = config
+ @redcarpet_extensions = {}
+ @config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true }
+
+ @renderer ||= if @config['pygments']
+ Class.new(Redcarpet::Render::HTML) do
+ include WithPygments
+ end
+ else
+ Class.new(Redcarpet::Render::HTML) do
+ include WithoutPygments
+ end
+ end
+ 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
+
+ def convert(content)
+ @redcarpet_extensions[:fenced_code_blocks] = !@redcarpet_extensions[:no_fenced_code_blocks]
+ @renderer.send :include, Redcarpet::Render::SmartyPants if @redcarpet_extensions[:smart]
+ markdown = Redcarpet::Markdown.new(@renderer.new(@redcarpet_extensions), @redcarpet_extensions)
+ markdown.render(content)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/converters/textile.rb b/lib/jekyll/converters/textile.rb
index da823d3..54e9374 100644
--- a/lib/jekyll/converters/textile.rb
+++ b/lib/jekyll/converters/textile.rb
@@ -1,34 +1,50 @@
module Jekyll
+ module Converters
+ class Textile < Converter
+ safe true
- class TextileConverter < Converter
- safe true
+ pygments_prefix '<notextile>'
+ pygments_suffix '</notextile>'
- pygments_prefix '<notextile>'
- pygments_suffix '</notextile>'
+ 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 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 matches(ext)
- rgx = '(' + @config['textile_ext'].gsub(',','|') +')'
- ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
- end
+ def output_ext(ext)
+ ".html"
+ end
- def output_ext(ext)
- ".html"
- end
+ def convert(content)
+ setup
+
+ # Shortcut if config doesn't contain RedCloth section
+ return RedCloth.new(content).to_html if @config['redcloth'].nil?
- def convert(content)
- setup
- RedCloth.new(content).to_html
+ # List of attributes defined on RedCloth
+ # (from http://redcloth.rubyforge.org/classes/RedCloth/TextileDoc.html)
+ attrs = ['filter_classes', 'filter_html', 'filter_ids', 'filter_styles',
+ 'hard_breaks', 'lite_mode', 'no_span_caps', 'sanitize_html']
+
+ r = RedCloth.new(content)
+
+ # Set attributes in r if they are NOT nil in the config
+ attrs.each do |attr|
+ r.instance_variable_set("@#{attr}".to_sym, @config['redcloth'][attr]) unless @config['redcloth'][attr].nil?
+ end
+
+ r.to_html
+ end
end
end
-
end
diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb
index d33abc5..723b0da 100644
--- a/lib/jekyll/convertible.rb
+++ b/lib/jekyll/convertible.rb
@@ -1,3 +1,5 @@
+# encoding: UTF-8
+
require 'set'
# Convertible provides methods for converting a pagelike item
@@ -10,6 +12,7 @@ require 'set'
# self.data=
# self.ext=
# self.output=
+# self.name
module Jekyll
module Convertible
# Returns the contents as a String.
@@ -17,23 +20,31 @@ module Jekyll
self.content || ''
end
+ # Returns merged optin hash for File.read of self.site (if exists)
+ # and a given param
+ def merged_file_read_opts(opts)
+ (self.site ? self.site.file_read_opts : {}).merge(opts)
+ end
+
# Read the YAML frontmatter.
#
# base - The String path to the dir containing the file.
# name - The String filename of the file.
+ # opts - optional parameter to File.read, default at site configs
#
# 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}"
+ def read_yaml(base, name, opts = {})
+ begin
+ self.content = File.read_with_options(File.join(base, name),
+ merged_file_read_opts(opts))
+ if self.content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
+ self.content = $POSTMATCH
+ self.data = YAML.safe_load($1)
end
+ rescue SyntaxError => e
+ puts "YAML Exception reading #{File.join(base, name)}: #{e.message}"
+ rescue Exception => e
+ puts "Error reading file #{File.join(base, name)}: #{e.message}"
end
self.data ||= {}
@@ -44,6 +55,10 @@ module Jekyll
# Returns nothing.
def transform
self.content = converter.convert(self.content)
+ rescue => e
+ Jekyll.logger.error "Conversion error:", "There was an error converting" +
+ " '#{self.path}'."
+ raise e
end
# Determine the extension depending on content_type.
@@ -62,30 +77,41 @@ module Jekyll
@converter ||= self.site.converters.find { |c| c.matches(self.ext) }
end
- # Add any necessary layouts to this convertible document.
+ # Render Liquid in the content
#
- # payload - The site payload Hash.
- # layouts - A Hash of {"name" => "layout"}.
+ # content - the raw Liquid content to render
+ # payload - the payload for Liquid
+ # info - the info for Liquid
#
- # 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
+ # Returns the converted content
+ def render_liquid(content, payload, info, path = nil)
+ Liquid::Template.parse(content).render!(payload, info)
+ rescue Tags::IncludeTagError => e
+ Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{e.path}, included in #{path || self.path}"
+ raise e
+ rescue Exception => e
+ Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{path || self.path}"
+ raise e
+ end
- # output keeps track of what will finally be written
- self.output = self.content
+ # Convert this Convertible's data to a Hash suitable for use by Liquid.
+ #
+ # Returns the Hash representation of this Convertible.
+ def to_liquid(attrs = nil)
+ further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map { |attribute|
+ [attribute, send(attribute)]
+ }]
+ data.deep_merge(further_data)
+ end
+ # Recursively render layouts
+ #
+ # layouts - a list of the layouts
+ # payload - the payload for Liquid
+ # info - the info for Liquid
+ #
+ # Returns nothing
+ def render_all_layouts(layouts, payload, info)
# recursively render layouts
layout = layouts[self.data["layout"]]
used = Set.new([layout])
@@ -93,11 +119,10 @@ module Jekyll
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
+ self.output = self.render_liquid(layout.content,
+ payload,
+ info,
+ File.join(self.site.config['layouts'], layout.name))
if layout = layouts[layout.data["layout"]]
if used.include?(layout)
@@ -108,5 +133,42 @@ module Jekyll
end
end
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, :page => payload['page'] } }
+
+ # render and transform content (this becomes the final content of the object)
+ payload["pygments_prefix"] = converter.pygments_prefix
+ payload["pygments_suffix"] = converter.pygments_suffix
+
+ self.content = self.render_liquid(self.content,
+ payload,
+ info)
+ self.transform
+
+ # output keeps track of what will finally be written
+ self.output = self.content
+
+ self.render_all_layouts(layouts, payload, info)
+ 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, 'wb') do |f|
+ f.write(self.output)
+ end
+ end
end
end
diff --git a/lib/jekyll/core_ext.rb b/lib/jekyll/core_ext.rb
index fc40cb3..54f7c9d 100644
--- a/lib/jekyll/core_ext.rb
+++ b/lib/jekyll/core_ext.rb
@@ -24,7 +24,7 @@ class Hash
# 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
+ # +plural_key+ the plural key
#
# Returns an array
def pluralized_array(singular_key, plural_key)
@@ -41,6 +41,17 @@ class Hash
end
array || []
end
+
+ def symbolize_keys!
+ keys.each do |key|
+ self[(key.to_sym rescue key) || key] = delete(key)
+ end
+ self
+ end
+
+ def symbolize_keys
+ dup.symbolize_keys!
+ end
end
# Thanks, ActiveSupport!
@@ -50,3 +61,26 @@ class Date
strftime("%Y-%m-%dT%H:%M:%S%Z")
end if RUBY_VERSION < '1.9'
end
+
+module Enumerable
+ # Returns true if path matches against any glob pattern.
+ # Look for more detail about glob pattern in method File::fnmatch.
+ def glob_include?(e)
+ any? { |exp| File.fnmatch?(exp, e) }
+ end
+end
+
+# Ruby 1.8's File.read don't support option.
+# read_with_options ignore optional parameter for 1.8,
+# and act as alias for 1.9 or later.
+class File
+ if RUBY_VERSION < '1.9'
+ def self.read_with_options(path, opts = {})
+ self.read(path)
+ end
+ else
+ def self.read_with_options(path, opts = {})
+ self.read(path, opts)
+ end
+ end
+end
diff --git a/lib/jekyll/deprecator.rb b/lib/jekyll/deprecator.rb
new file mode 100644
index 0000000..23af739
--- /dev/null
+++ b/lib/jekyll/deprecator.rb
@@ -0,0 +1,36 @@
+module Jekyll
+ class Deprecator
+ def self.process(args)
+ no_subcommand(args)
+ arg_is_present? args, "--server", "The --server command has been replaced by the \
+ 'serve' subcommand."
+ arg_is_present? args, "--no-server", "To build Jekyll without launching a server, \
+ use the 'build' subcommand."
+ arg_is_present? args, "--auto", "The switch '--auto' has been replaced with '--watch'."
+ arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \
+ the '--watch' switch."
+ arg_is_present? args, "--pygments", "The 'pygments' setting can only be set in \
+ your config files."
+ arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in your \
+ config files."
+ arg_is_present? args, "--url", "The 'url' setting can only be set in your config files."
+ end
+
+ def self.no_subcommand(args)
+ if args.size > 0 && args.first =~ /^--/ && !%w[--help --version].include?(args.first)
+ Jekyll.logger.error "Deprecation:", "Jekyll now uses subcommands instead of just \
+ switches. Run `jekyll help' to find out more."
+ end
+ end
+
+ def self.arg_is_present?(args, deprecated_argument, message)
+ if args.include?(deprecated_argument)
+ deprecation_message(message)
+ end
+ end
+
+ def self.deprecation_message(message)
+ Jekyll.logger.error "Deprecation:", message
+ end
+ end
+end
diff --git a/lib/jekyll/draft.rb b/lib/jekyll/draft.rb
new file mode 100644
index 0000000..321a6e5
--- /dev/null
+++ b/lib/jekyll/draft.rb
@@ -0,0 +1,35 @@
+module Jekyll
+
+ class Draft < Post
+
+ # Valid post name regex (no date)
+ MATCHER = /^(.*)(\.[^.]+)$/
+
+ # Draft name validator. Draft filenames must be like:
+ # my-awesome-post.textile
+ #
+ # Returns true if valid, false if not.
+ def self.valid?(name)
+ name =~ MATCHER
+ end
+
+ # Get the full path to the directory containing the draft files
+ def containing_dir(source, dir)
+ File.join(source, dir, '_drafts')
+ end
+
+ # Extract information from the post filename.
+ #
+ # name - The String filename of the post file.
+ #
+ # Returns nothing.
+ def process(name)
+ m, slug, ext = *name.match(MATCHER)
+ self.date = File.mtime(File.join(@base, name))
+ self.slug = slug
+ self.ext = ext
+ end
+
+ end
+
+end
diff --git a/lib/jekyll/entry_filter.rb b/lib/jekyll/entry_filter.rb
new file mode 100644
index 0000000..56f3cfc
--- /dev/null
+++ b/lib/jekyll/entry_filter.rb
@@ -0,0 +1,35 @@
+class EntryFilter
+ attr_reader :site
+ def initialize(site)
+ @site = site
+ end
+
+ def filter(entries)
+ entries.reject do |e|
+ unless included?(e)
+ special?(e) || backup?(e) || excluded?(e) || symlink?(e)
+ end
+ end
+ end
+
+ def included?(entry)
+ site.include.glob_include?(entry)
+ end
+
+ def special?(entry)
+ ['.', '_', '#'].include?(entry[0..0])
+ end
+
+ def backup?(entry)
+ entry[-1..-1] == '~'
+ end
+
+ def excluded?(entry)
+ site.exclude.glob_include?(entry)
+ end
+
+ def symlink?(entry)
+ File.symlink?(entry) && site.safe
+ end
+
+end
diff --git a/lib/jekyll/errors.rb b/lib/jekyll/errors.rb
index 296d837..af03ad8 100644
--- a/lib/jekyll/errors.rb
+++ b/lib/jekyll/errors.rb
@@ -1,6 +1,4 @@
module Jekyll
-
class FatalException < StandardError
end
-
-end
\ No newline at end of file
+end
diff --git a/lib/jekyll/excerpt.rb b/lib/jekyll/excerpt.rb
new file mode 100644
index 0000000..a02272b
--- /dev/null
+++ b/lib/jekyll/excerpt.rb
@@ -0,0 +1,113 @@
+module Jekyll
+ class Excerpt
+ include Convertible
+
+ attr_accessor :post
+ attr_accessor :content, :output, :ext
+
+ # Initialize this Post instance.
+ #
+ # site - The Site.
+ # base - The String path to the dir containing the post file.
+ # name - The String filename of the post file.
+ #
+ # Returns the new Post.
+ def initialize(post)
+ self.post = post
+ self.content = extract_excerpt(post.content)
+ end
+
+ %w[site name ext].each do |meth|
+ define_method(meth) do
+ post.send(meth)
+ end
+ end
+
+ def to_liquid
+ post.to_liquid(Post::EXCERPT_ATTRIBUTES_FOR_LIQUID)
+ end
+
+ # Fetch YAML front-matter data from related post, without layout key
+ #
+ # Returns Hash of post data
+ def data
+ @data ||= post.data.dup
+ @data.delete("layout")
+ @data
+ end
+
+ # 'Path' of the excerpt.
+ #
+ # Returns the path for the post this excerpt belongs to with #excerpt appended
+ def path
+ File.join(post.path, "#excerpt")
+ end
+
+ # Check if excerpt includes a string
+ #
+ # Returns true if the string passed in
+ def include?(something)
+ (self.output && self.output.include?(something)) || self.content.include?(something)
+ end
+
+ # The UID for this post (useful in feeds).
+ # e.g. /2008/11/05/my-awesome-post
+ #
+ # Returns the String UID.
+ def id
+ File.join(post.dir, post.slug, "#excerpt")
+ end
+
+ def to_s
+ self.output || self.content
+ end
+
+ # Returns the shorthand String identifier of this Post.
+ def inspect
+ "<Excerpt: #{self.id}>"
+ end
+
+ protected
+
+ # Internal: Extract excerpt from the content
+ #
+ # By default excerpt is your first paragraph of a post: everything before
+ # the first two new lines:
+ #
+ # ---
+ # title: Example
+ # ---
+ #
+ # First paragraph with [link][1].
+ #
+ # Second paragraph.
+ #
+ # [1]: http://example.com/
+ #
+ # This is fairly good option for Markdown and Textile files. But might cause
+ # problems for HTML posts (which is quite unusual for Jekyll). If default
+ # excerpt delimiter is not good for you, you might want to set your own via
+ # configuration option `excerpt_separator`. For example, following is a good
+ # alternative for HTML posts:
+ #
+ # # file: _config.yml
+ # excerpt_separator: "<!-- more -->"
+ #
+ # Notice that all markdown-style link references will be appended to the
+ # excerpt. So the example post above will have this excerpt source:
+ #
+ # First paragraph with [link][1].
+ #
+ # [1]: http://example.com/
+ #
+ # Excerpts are rendered same time as content is rendered.
+ #
+ # Returns excerpt String
+ def extract_excerpt(post_content)
+ separator = site.config['excerpt_separator']
+ head, _, tail = post_content.partition(separator)
+
+ "" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
+ end
+ end
+end
diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb
index eb61d84..95ada0b 100644
--- a/lib/jekyll/filters.rb
+++ b/lib/jekyll/filters.rb
@@ -1,7 +1,7 @@
require 'uri'
+require 'json'
module Jekyll
-
module Filters
# Convert a Textile string into HTML output.
#
@@ -10,7 +10,7 @@ module Jekyll
# Returns the HTML formatted String.
def textilize(input)
site = @context.registers[:site]
- converter = site.getConverterImpl(Jekyll::TextileConverter)
+ converter = site.getConverterImpl(Jekyll::Converters::Textile)
converter.convert(input)
end
@@ -21,7 +21,7 @@ module Jekyll
# Returns the HTML formatted String.
def markdownify(input)
site = @context.registers[:site]
- converter = site.getConverterImpl(Jekyll::MarkdownConverter)
+ converter = site.getConverterImpl(Jekyll::Converters::Markdown)
converter.convert(input)
end
@@ -31,7 +31,7 @@ module Jekyll
#
# Returns the formatting String.
def date_to_string(date)
- date.strftime("%d %b %Y")
+ time(date).strftime("%d %b %Y")
end
# Format a date in long format e.g. "27 January 2011".
@@ -40,7 +40,7 @@ module Jekyll
#
# Returns the formatted String.
def date_to_long_string(date)
- date.strftime("%d %B %Y")
+ time(date).strftime("%d %B %Y")
end
# Format a date for use in XML.
@@ -54,9 +54,34 @@ module Jekyll
#
# Returns the formatted String.
def date_to_xmlschema(date)
- date.xmlschema
+ time(date).xmlschema
+ end
+
+ # Format a date according to RFC-822
+ #
+ # date - The Time to format.
+ #
+ # Examples
+ #
+ # date_to_rfc822(Time.now)
+ # # => "Sun, 24 Apr 2011 12:34:46 +0000"
+ #
+ # Returns the formatted String.
+ def date_to_rfc822(date)
+ time(date).rfc822
end
+ # XML escape a string for use. Replaces any special characters with
+ # appropriate HTML entity replacements.
+ #
+ # input - The String to escape.
+ #
+ # Examples
+ #
+ # xml_escape('foo "bar" <baz>')
+ # # => "foo "bar" <baz>"
+ #
+ # Returns the escaped String.
def xml_escape(input)
CGI.escapeHTML(input)
end
@@ -75,7 +100,17 @@ module Jekyll
def cgi_escape(input)
CGI::escape(input)
end
-
+
+ # URI escape a string.
+ #
+ # input - The String to escape.
+ #
+ # Examples
+ #
+ # uri_escape('foo, bar \\baz?')
+ # # => "foo,%20bar%20%5Cbaz?"
+ #
+ # Returns the escaped String.
def uri_escape(input)
URI.escape(input)
end
@@ -114,5 +149,26 @@ module Jekyll
end
end
+ # Convert the input into json string
+ #
+ # input - The Array or Hash to be converted
+ #
+ # Returns the converted json string
+ def jsonify(input)
+ input.to_json
+ end
+
+ private
+ def time(input)
+ case input
+ when Time
+ input
+ when String
+ Time.parse(input)
+ else
+ Jekyll.logger.error "Invalid Date:", "'#{input}' is not a valid datetime."
+ exit(1)
+ end
+ end
end
end
diff --git a/lib/jekyll/generator.rb b/lib/jekyll/generator.rb
index f1cd1a5..57973a7 100644
--- a/lib/jekyll/generator.rb
+++ b/lib/jekyll/generator.rb
@@ -1,7 +1,4 @@
module Jekyll
-
class Generator < Plugin
-
end
-
-end
\ No newline at end of file
+end
diff --git a/lib/jekyll/generators/pagination.rb b/lib/jekyll/generators/pagination.rb
index 847de4f..72dc529 100644
--- a/lib/jekyll/generators/pagination.rb
+++ b/lib/jekyll/generators/pagination.rb
@@ -1,53 +1,90 @@
module Jekyll
+ module Generators
+ class Pagination < Generator
+ # This generator is safe from arbitrary code execution.
+ safe true
- class Pagination < Generator
- # This generator is safe from arbitrary code execution.
- safe true
+ # This generator should be passive with regard to its execution
+ priority :lowest
- # 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)
+ # Generate paginated pages if necessary.
+ #
+ # site - The Site.
+ #
+ # Returns nothing.
+ def generate(site)
+ if Pager.pagination_enabled?(site)
+ if template = template_page(site)
+ paginate(site, template)
+ else
+ Jekyll.logger.warn "Pagination:", "Pagination is enabled, but I couldn't find " +
+ "an index.html page to use as the pagination template. Skipping pagination."
+ end
+ end
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" => <Number>,
- # "per_page" => <Number>,
- # "posts" => [<Post>],
- # "total_posts" => <Number>,
- # "total_pages" => <Number>,
- # "previous_page" => <Number>,
- # "next_page" => <Number> }}
- 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
+ # 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" => <Number>,
+ # "per_page" => <Number>,
+ # "posts" => [<Post>],
+ # "total_posts" => <Number>,
+ # "total_pages" => <Number>,
+ # "previous_page" => <Number>,
+ # "next_page" => <Number> }}
+ 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, num_page, all_posts, pages)
+ if num_page > 1
+ newpage = Page.new(site, site.source, page.dir, page.name)
+ newpage.pager = pager
+ newpage.dir = Pager.paginate_path(site, num_page)
+ site.pages << newpage
+ else
+ page.pager = pager
+ end
+ end
+ end
+
+ # Static: Fetch the URL of the template page. Used to determine the
+ # path to the first pager in the series.
+ #
+ # site - the Jekyll::Site object
+ #
+ # Returns the url of the template page
+ def self.first_page_url(site)
+ if page = Pagination.new.template_page(site)
+ page.url
else
- page.pager = pager
+ nil
end
end
+
+ # Public: Find the Jekyll::Page which will act as the pager template
+ #
+ # site - the Jekyll::Site object
+ #
+ # Returns the Jekyll::Page which will act as the pager template
+ def template_page(site)
+ site.pages.dup.select do |page|
+ Pager.pagination_candidate?(site.config, page)
+ end.sort do |one, two|
+ two.path.size <=> one.path.size
+ end.first
+ end
end
end
class Pager
- attr_reader :page, :per_page, :posts, :total_posts, :total_pages, :previous_page, :next_page
+ attr_reader :page, :per_page, :posts, :total_posts, :total_pages,
+ :previous_page, :previous_page_path, :next_page, :next_page_path
# Calculate the number of pages.
#
@@ -59,26 +96,90 @@ module Jekyll
(all_posts.size.to_f / per_page.to_i).ceil
end
- # Determine if pagination is enabled for a given file.
+ # Determine if pagination is enabled the site.
#
- # config - The configuration Hash.
- # file - The String filename of the file.
+ # site - the Jekyll::Site object
#
# Returns true if pagination is enabled, false otherwise.
- def self.pagination_enabled?(config, file)
- file == 'index.html' && !config['paginate'].nil?
+ def self.pagination_enabled?(site)
+ !site.config['paginate'].nil? &&
+ site.pages.size > 0
+ end
+
+ # Static: Determine if a page is a possible candidate to be a template page.
+ # Page's name must be `index.html` and exist in any of the directories
+ # between the site source and `paginate_path`.
+ #
+ # config - the site configuration hash
+ # page - the Jekyll::Page about which we're inquiring
+ #
+ # Returns true if the
+ def self.pagination_candidate?(config, page)
+ page_dir = File.dirname(File.expand_path(remove_leading_slash(page.path), config['source']))
+ paginate_path = remove_leading_slash(config['paginate_path'])
+ paginate_path = File.expand_path(paginate_path, config['source'])
+ page.name == 'index.html' &&
+ in_hierarchy(config['source'], page_dir, File.dirname(paginate_path))
+ end
+
+ # Determine if the subdirectories of the two paths are the same relative to source
+ #
+ # source - the site source
+ # page_dir - the directory of the Jekyll::Page
+ # paginate_path - the absolute paginate path (from root of FS)
+ #
+ # Returns whether the subdirectories are the same relative to source
+ def self.in_hierarchy(source, page_dir, paginate_path)
+ return false if paginate_path == File.dirname(paginate_path)
+ return false if paginate_path == Pathname.new(source).parent
+ page_dir == paginate_path ||
+ in_hierarchy(source, page_dir, File.dirname(paginate_path))
+ end
+
+ # Static: Return the pagination path of the page
+ #
+ # site - the Jekyll::Site object
+ # num_page - the pagination page number
+ #
+ # Returns the pagination path as a string
+ def self.paginate_path(site, num_page)
+ return nil if num_page.nil?
+ return Generators::Pagination.first_page_url(site) if num_page <= 1
+ format = site.config['paginate_path']
+ format = format.sub(':num', num_page.to_s)
+ ensure_leading_slash(format)
+ end
+
+ # Static: Return a String version of the input which has a leading slash.
+ # If the input already has a forward slash in position zero, it will be
+ # returned unchanged.
+ #
+ # path - a String path
+ #
+ # Returns the path with a leading slash
+ def self.ensure_leading_slash(path)
+ path[0..0] == "/" ? path : "/#{path}"
+ end
+
+ # Static: Return a String version of the input without a leading slash.
+ #
+ # path - a String path
+ #
+ # Returns the input without the leading slash
+ def self.remove_leading_slash(path)
+ ensure_leading_slash(path)[1..-1]
end
# Initialize a new Pager.
#
- # config - The Hash configuration of the site.
+ # site - the Jekyll::Site object
# 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)
+ def initialize(site, page, all_posts, num_pages = nil)
@page = page
- @per_page = config['paginate'].to_i
+ @per_page = site.config['paginate'].to_i
@total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page)
if @page > @total_pages
@@ -91,7 +192,9 @@ module Jekyll
@total_posts = all_posts.size
@posts = all_posts[init..offset]
@previous_page = @page != 1 ? @page - 1 : nil
+ @previous_page_path = Pager.paginate_path(site, @previous_page)
@next_page = @page != @total_pages ? @page + 1 : nil
+ @next_page_path = Pager.paginate_path(site, @next_page)
end
# Convert this Pager's data to a Hash suitable for use by Liquid.
@@ -105,9 +208,10 @@ module Jekyll
'total_posts' => total_posts,
'total_pages' => total_pages,
'previous_page' => previous_page,
- 'next_page' => next_page
+ 'previous_page_path' => previous_page_path,
+ 'next_page' => next_page,
+ 'next_page_path' => next_page_path
}
end
end
-
end
diff --git a/lib/jekyll/layout.rb b/lib/jekyll/layout.rb
index 1584573..f75a478 100644
--- a/lib/jekyll/layout.rb
+++ b/lib/jekyll/layout.rb
@@ -1,11 +1,13 @@
module Jekyll
-
class Layout
include Convertible
# Gets the Site object.
attr_reader :site
+ # Gets the name of this layout.
+ attr_reader :name
+
# Gets/Sets the extension of this layout.
attr_accessor :ext
@@ -40,5 +42,4 @@ module Jekyll
self.ext = File.extname(name)
end
end
-
end
diff --git a/lib/jekyll/migrators/csv.rb b/lib/jekyll/migrators/csv.rb
deleted file mode 100644
index ce5203b..0000000
--- a/lib/jekyll/migrators/csv.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-module 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
diff --git a/lib/jekyll/migrators/drupal.rb b/lib/jekyll/migrators/drupal.rb
deleted file mode 100644
index 32e335c..0000000
--- a/lib/jekyll/migrators/drupal.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-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 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
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-<meta http-equiv="refresh" content="0;url={{ page.refresh_to_post_id }}.html" />
-</head>
-</html>
-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
diff --git a/lib/jekyll/migrators/enki.rb b/lib/jekyll/migrators/enki.rb
deleted file mode 100644
index 61cb256..0000000
--- a/lib/jekyll/migrators/enki.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# Adapted by Rodrigo Pinto <rodrigopqn at gmail.com>
-# 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
diff --git a/lib/jekyll/migrators/marley.rb b/lib/jekyll/migrators/marley.rb
deleted file mode 100644
index 21bcead..0000000
--- a/lib/jekyll/migrators/marley.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-require '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
diff --git a/lib/jekyll/migrators/mephisto.rb b/lib/jekyll/migrators/mephisto.rb
deleted file mode 100644
index 7622c72..0000000
--- a/lib/jekyll/migrators/mephisto.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-# 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
diff --git a/lib/jekyll/migrators/mt.rb b/lib/jekyll/migrators/mt.rb
deleted file mode 100644
index 048c84d..0000000
--- a/lib/jekyll/migrators/mt.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# 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
diff --git a/lib/jekyll/migrators/posterous.rb b/lib/jekyll/migrators/posterous.rb
deleted file mode 100644
index 6cfc243..0000000
--- a/lib/jekyll/migrators/posterous.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-require '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
diff --git a/lib/jekyll/migrators/textpattern.rb b/lib/jekyll/migrators/textpattern.rb
deleted file mode 100644
index 58634c4..0000000
--- a/lib/jekyll/migrators/textpattern.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-require '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
diff --git a/lib/jekyll/migrators/tumblr.rb b/lib/jekyll/migrators/tumblr.rb
deleted file mode 100644
index d7cb396..0000000
--- a/lib/jekyll/migrators/tumblr.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-require '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 = "<a href=\"#{post.at("link-url").inner_html}\">#{post.at("link-text").inner_html}</a>"
- else
- content = "<a href=\"#{post.at("link-url").inner_html}\">#{post.at("link-url").inner_html}</a>"
- end
-
- content << "<br/>" + 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 = "<a href=\"#{post.at("photo-link-url").inner_html}\"><img src=\"#{save_file((post/"photo-url")[1].inner_html, grab_images)}\"/></a>"
- else
- content = "<img src=\"#{save_file((post/"photo-url")[1].inner_html, grab_images)}\"/>"
- end
-
- if post.at("photo-caption") != nil
- content << "<br/>" 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 = "<blockquote>" + CGI::unescapeHTML(post.at("quote-text").inner_html) + "</blockquote>"
- 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 = "<section><dialog>"
-
- (post/:conversation/:line).each do |line|
- content << "<dt>" + line['label'] + "</dt><dd>" + line.inner_html + "</dd>" unless line['label'] == nil || line == nil
- end
-
- content << "</section></dialog>"
- 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
diff --git a/lib/jekyll/migrators/typo.rb b/lib/jekyll/migrators/typo.rb
deleted file mode 100644
index adb8be9..0000000
--- a/lib/jekyll/migrators/typo.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# Author: Toby DiPasquale <toby at cbcg.net>
-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
diff --git a/lib/jekyll/migrators/wordpress.rb b/lib/jekyll/migrators/wordpress.rb
deleted file mode 100644
index 535859c..0000000
--- a/lib/jekyll/migrators/wordpress.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-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 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
diff --git a/lib/jekyll/migrators/wordpressdotcom.rb b/lib/jekyll/migrators/wordpressdotcom.rb
deleted file mode 100644
index 701c2af..0000000
--- a/lib/jekyll/migrators/wordpressdotcom.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-# 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
diff --git a/lib/jekyll/mime.types b/lib/jekyll/mime.types
new file mode 100644
index 0000000..b926a00
--- /dev/null
+++ b/lib/jekyll/mime.types
@@ -0,0 +1,85 @@
+# These are the same MIME types that GitHub Pages uses as of 17 Mar 2013.
+
+text/html html htm shtml
+text/css css
+text/xml xml rss xsl
+image/gif gif
+image/jpeg jpeg jpg
+application/x-javascript js
+application/atom+xml atom
+
+text/mathml mml
+text/plain txt
+text/vnd.sun.j2me.app-descriptor jad
+text/vnd.wap.wml wml
+text/x-component htc
+text/cache-manifest manifest appcache
+text/coffeescript coffee
+text/plain pde
+text/plain md markdown
+
+image/png png
+image/svg+xml svg
+image/tiff tif tiff
+image/vnd.wap.wbmp wbmp
+image/x-icon ico
+image/x-jng jng
+image/x-ms-bmp bmp
+
+application/json json
+application/java-archive jar ear
+application/mac-binhex40 hqx
+application/msword doc
+application/pdf pdf
+application/postscript ps eps ai
+application/rdf+xml rdf
+application/rtf rtf
+text/vcard vcf vcard
+application/vnd.apple.pkpass pkpass
+application/vnd.ms-excel xls
+application/vnd.ms-powerpoint ppt
+application/vnd.wap.wmlc wmlc
+application/xhtml+xml xhtml
+application/x-chrome-extension crx
+application/x-cocoa cco
+application/x-font-ttf ttf
+application/x-java-archive-diff jardiff
+application/x-java-jnlp-file jnlp
+application/x-makeself run
+application/x-ns-proxy-autoconfig pac
+application/x-perl pl pm
+application/x-pilot prc pdb
+application/x-rar-compressed rar
+application/x-redhat-package-manager rpm
+application/x-sea sea
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-tcl tcl tk
+application/x-web-app-manifest+json webapp
+application/x-x509-ca-cert der pem crt
+application/x-xpinstall xpi
+application/x-zip war
+application/zip zip
+
+application/octet-stream bin exe dll
+application/octet-stream deb
+application/octet-stream dmg
+application/octet-stream eot
+application/octet-stream iso img
+application/octet-stream msi msp msm
+
+audio/midi mid midi kar
+audio/mpeg mp3
+audio/x-realaudio ra
+audio/ogg ogg
+
+video/3gpp 3gpp 3gp
+video/mpeg mpeg mpg
+video/quicktime mov
+video/x-flv flv
+video/x-mng mng
+video/x-ms-asf asx asf
+video/x-ms-wmv wmv
+video/x-msvideo avi
+video/ogg ogv
+video/webm webm
diff --git a/lib/jekyll/page.rb b/lib/jekyll/page.rb
index 82b8204..dd602a0 100644
--- a/lib/jekyll/page.rb
+++ b/lib/jekyll/page.rb
@@ -1,5 +1,4 @@
module Jekyll
-
class Page
include Convertible
@@ -8,6 +7,13 @@ module Jekyll
attr_accessor :name, :ext, :basename
attr_accessor :data, :content, :output
+ # Attributes for Liquid templates
+ ATTRIBUTES_FOR_LIQUID = %w[
+ url
+ content
+ path
+ ]
+
# Initialize a new Page.
#
# site - The Site object.
@@ -38,17 +44,28 @@ module Jekyll
#
# Returns the String permalink or nil if none has been set.
def permalink
- self.data && self.data['permalink']
+ return nil if self.data.nil? || self.data['permalink'].nil?
+ if site.config['relative_permalinks']
+ File.join(@dir, self.data['permalink'])
+ else
+ self.data['permalink']
+ end
end
# The template of the permalink.
#
# Returns the template String.
def template
- if self.site.permalink_style == :pretty && !index? && html?
- "/:basename/"
+ if self.site.permalink_style == :pretty
+ if index? && html?
+ "/:path/"
+ elsif html?
+ "/:path/:basename/"
+ else
+ "/:path/:basename:output_ext"
+ end
else
- "/:basename:output_ext"
+ "/:path/:basename:output_ext"
end
end
@@ -56,23 +73,21 @@ module Jekyll
#
# 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
+ @url ||= URL.new({
+ :template => template,
+ :placeholders => url_placeholders,
+ :permalink => permalink
+ }).to_s
+ end
- # sanitize url
- @url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
- @url += "/" if url =~ /\/$/
- @url
+ # Returns a hash of URL placeholder names (as symbols) mapping to the
+ # desired placeholder replacements. For details see "url.rb"
+ def url_placeholders
+ {
+ :path => @dir,
+ :basename => self.basename,
+ :output_ext => self.output_ext
+ }
end
# Extract information from the page filename.
@@ -100,13 +115,16 @@ module Jekyll
do_layout(payload, layouts)
end
- # Convert this Page's data to a Hash suitable for use by Liquid.
+ # The path to the source file
#
- # Returns the Hash representation of this Page.
- def to_liquid
- self.data.deep_merge({
- "url" => File.join(@dir, self.url),
- "content" => self.content })
+ # Returns the path to the source file
+ def path
+ self.data.fetch('path', self.relative_path.sub(/\A\//, ''))
+ end
+
+ # The path to the page source file, relative to the site source
+ def relative_path
+ File.join(@dir, @name)
end
# Obtain destination path.
@@ -115,26 +133,11 @@ module Jekyll
#
# 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(dest, 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
"#<Jekyll:Page @name=#{self.name.inspect}>"
@@ -150,6 +153,8 @@ module Jekyll
basename == 'index'
end
+ def uses_relative_permalinks
+ permalink && @dir != "" && site.config['relative_permalinks']
+ end
end
-
end
diff --git a/lib/jekyll/plugin.rb b/lib/jekyll/plugin.rb
index 600f326..2613f70 100644
--- a/lib/jekyll/plugin.rb
+++ b/lib/jekyll/plugin.rb
@@ -1,5 +1,4 @@
module Jekyll
-
class Plugin
PRIORITIES = { :lowest => -100,
:low => -10,
@@ -73,5 +72,4 @@ module Jekyll
# no-op for default
end
end
-
end
diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb
index 5502994..da64af9 100644
--- a/lib/jekyll/post.rb
+++ b/lib/jekyll/post.rb
@@ -1,64 +1,144 @@
module Jekyll
-
class Post
include Comparable
include Convertible
- class << self
- attr_accessor :lsi
- end
-
+ # Valid post name regex.
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
+ EXCERPT_ATTRIBUTES_FOR_LIQUID = %w[
+ title
+ url
+ date
+ id
+ categories
+ next
+ previous
+ tags
+ path
+ ]
+
+ # Attributes for Liquid templates
+ ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID + %w[
+ content
+ excerpt
+ ]
+
# Post name validator. Post filenames must be like:
- # 2008-11-05-my-awesome-post.textile
+ # 2008-11-05-my-awesome-post.textile
#
- # Returns <Bool>
+ # Returns true if valid, false if not.
def self.valid?(name)
name =~ MATCHER
end
attr_accessor :site
- attr_accessor :data, :content, :output, :ext
+ attr_accessor :data, :extracted_excerpt, :content, :output, :ext
attr_accessor :date, :slug, :published, :tags, :categories
+ attr_reader :name
+
# 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 <Post>
+ # site - The Site.
+ # base - The String path to the dir containing the post file.
+ # name - The String filename of the post file.
+ #
+ # Returns the new Post.
def initialize(site, source, dir, name)
@site = site
- @base = File.join(source, dir, '_posts')
+ @dir = dir
+ @base = self.containing_dir(source, dir)
@name = name
- self.categories = dir.split('/').reject { |x| x.empty? }
+ self.categories = dir.downcase.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
+ self.published = self.published?
+
+ self.populate_categories
+ self.populate_tags
+ end
+
+ def published?
if self.data.has_key?('published') && self.data['published'] == false
- self.published = false
+ false
else
- self.published = true
+ true
end
+ end
- self.tags = self.data.pluralized_array("tag", "tags")
-
+ def populate_categories
if self.categories.empty?
- self.categories = self.data.pluralized_array('category', 'categories')
+ self.categories = self.data.pluralized_array('category', 'categories').map {|c| c.to_s.downcase}
end
+ self.categories.flatten!
+ end
+
+ def populate_tags
+ self.tags = self.data.pluralized_array("tag", "tags").flatten
+ end
+
+ # Get the full path to the directory containing the post files
+ def containing_dir(source, dir)
+ return File.join(source, dir, '_posts')
+ 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)
+ super(base, name)
+ self.extracted_excerpt = self.extract_excerpt
+ end
+
+ # The post excerpt. This is either a custom excerpt
+ # set in YAML front matter or the result of extract_excerpt.
+ #
+ # Returns excerpt string.
+ def excerpt
+ self.data.fetch('excerpt', self.extracted_excerpt.to_s)
+ end
+
+ # Public: the Post title, from the YAML Front-Matter or from the slug
+ #
+ # Returns the post title
+ def title
+ self.data.fetch("title", self.titleized_slug)
+ end
+
+ # Turns the post slug into a suitable title
+ def titleized_slug
+ self.slug.split('-').select {|w| w.capitalize! || w }.join(' ')
+ end
+
+ # Public: the path to the post relative to the site source,
+ # from the YAML Front-Matter or from a combination of
+ # the directory it's in, "_posts", and the name of the
+ # post file
+ #
+ # Returns the path to the file relative to the site source
+ def path
+ self.data.fetch('path', self.relative_path.sub(/\A\//, ''))
+ end
+
+ # The path to the post source file, relative to the site source
+ def relative_path
+ File.join(@dir, '_posts', @name)
end
- # Spaceship is based on Post#date, slug
+ # Compares Post objects. First compares the Post date. If the dates are
+ # equal, it compares the Post slugs.
+ #
+ # other - The other Post we are comparing to.
#
# Returns -1, 0, 1
def <=>(other)
@@ -69,10 +149,11 @@ module Jekyll
return cmp
end
- # Extract information from the post filename
- # +name+ is the String filename of the post file
+ # Extract information from the post filename.
#
- # Returns nothing
+ # name - 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)
@@ -85,18 +166,17 @@ module Jekyll
# 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
+ # e.g. "/2008/11/05/" if the permalink style is :date, otherwise nothing.
#
- # Returns <String>
+ # Returns the String directory.
def dir
File.dirname(url)
end
- # The full path and filename of the post.
- # Defined in the YAML of the post body
- # (Optional)
+ # The full path and filename of the post. Defined in the YAML of the post
+ # body (optional).
#
- # Returns <String>
+ # Returns the String permalink.
def permalink
self.data && self.data['permalink']
end
@@ -109,125 +189,89 @@ module Jekyll
"/:categories/:title.html"
when :date
"/:categories/:year/:month/:day/:title.html"
+ when :ordinal
+ "/:categories/:year/:y_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
+ # The generated relative url of this post.
#
- # Returns <String>
+ # Returns the String url.
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
+ @url ||= URL.new({
+ :template => template,
+ :placeholders => url_placeholders,
+ :permalink => permalink
+ }).to_s
+ end
- # sanitize url
- @url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
- @url += "/" if url =~ /\/$/
- @url
+ # Returns a hash of URL placeholder names (as symbols) mapping to the
+ # desired placeholder replacements. For details see "url.rb"
+ def url_placeholders
+ {
+ :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 || []).map { |c| URI.escape(c.to_s) }.join('/'),
+ :short_month => date.strftime("%b"),
+ :y_day => date.strftime("%j"),
+ :output_ext => self.output_ext
+ }
end
- # The UID for this post (useful in feeds)
+ # The UID for this post (useful in feeds).
# e.g. /2008/11/05/my-awesome-post
#
- # Returns <String>
+ # Returns the String UID.
def id
File.join(self.dir, self.slug)
end
# Calculate related posts.
#
- # Returns [<Post>]
+ # Returns an Array of related Posts.
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
+ Jekyll::RelatedPosts.new(self).build
end
- # Add any necessary layouts to this post
- # +layouts+ is a Hash of {"name" => "layout"}
- # +site_payload+ is the site payload hash
+ # Add any necessary layouts to this post.
+ #
+ # layouts - A Hash of {"name" => "layout"}.
+ # site_payload - The site payload hash.
#
- # Returns nothing
+ # Returns nothing.
def render(layouts, site_payload)
# construct payload
payload = {
"site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
- "page" => self.to_liquid
+ "page" => self.to_liquid(EXCERPT_ATTRIBUTES_FOR_LIQUID)
}.deep_merge(site_payload)
- do_layout(payload, layouts)
+ if generate_excerpt?
+ self.extracted_excerpt.do_layout(payload, {})
+ end
+
+ do_layout(payload.merge({"page" => self.to_liquid}), layouts)
end
-
+
# Obtain destination path.
- # +dest+ is the String path to the destination dir
#
- # Returns destination file path.
+ # dest - The String path to the destination dir.
+ #
+ # Returns destination file path String.
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 = File.join(path, "index.html") if path[/\.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 <Hash>
- 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
-
+ # Returns the shorthand String identifier of this Post.
def inspect
"<Post: #{self.id}>"
end
@@ -250,6 +294,19 @@ module Jekyll
nil
end
end
- end
+ protected
+
+ def extract_excerpt
+ if generate_excerpt?
+ Jekyll::Excerpt.new(self)
+ else
+ ""
+ end
+ end
+
+ def generate_excerpt?
+ !(site.config['excerpt_separator'].to_s.empty?)
+ end
+ end
end
diff --git a/lib/jekyll/related_posts.rb b/lib/jekyll/related_posts.rb
new file mode 100644
index 0000000..f3040c1
--- /dev/null
+++ b/lib/jekyll/related_posts.rb
@@ -0,0 +1,59 @@
+module Jekyll
+ class RelatedPosts
+
+ class << self
+ attr_accessor :lsi
+ end
+
+ attr_reader :post, :site
+
+ def initialize(post)
+ @post = post
+ @site = post.site
+ require 'classifier' if site.lsi
+ end
+
+ def build
+ return [] unless self.site.posts.size > 1
+
+ if self.site.lsi
+ build_index
+ lsi_related_posts
+ else
+ most_recent_posts
+ end
+ end
+
+
+ def build_index
+ self.class.lsi ||= begin
+ lsi = Classifier::LSI.new(:auto_rebuild => false)
+ display("Populating LSI...")
+
+ self.site.posts.each do |x|
+ lsi.add_item(x)
+ end
+
+ display("Rebuilding index...")
+ lsi.build_index
+ display("")
+ lsi
+ end
+ end
+
+ def lsi_related_posts
+ self.class.lsi.find_related(post.content, 11) - [self.post]
+ end
+
+ def most_recent_posts
+ recent_posts = self.site.posts.reverse - [self.post]
+ recent_posts.first(10)
+ end
+
+ def display(output)
+ $stdout.print("\n")
+ $stdout.print(Jekyll.logger.formatted_topic(output))
+ $stdout.flush
+ end
+ end
+end
diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb
index 9c24f8e..2ce1c02 100644
--- a/lib/jekyll/site.rb
+++ b/lib/jekyll/site.rb
@@ -1,11 +1,9 @@
-require '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
+ :categories, :exclude, :include, :source, :dest, :lsi, :pygments,
+ :permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts,
+ :show_drafts, :keep_files, :baseurl, :data, :file_read_opts, :gems
attr_accessor :converters, :generators
@@ -15,16 +13,17 @@ module Jekyll
def initialize(config)
self.config = config.clone
- self.safe = config['safe']
+ %w[safe lsi pygments baseurl exclude include future show_drafts limit_posts keep_files gems].each do |opt|
+ self.send("#{opt}=", config[opt])
+ end
+
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.plugins = plugins_path
self.permalink_style = config['permalink'].to_sym
- self.exclude = config['exclude'] || []
- self.future = config['future']
- self.limit_posts = config['limit_posts'] || nil
+
+ self.file_read_opts = {}
+ self.file_read_opts[:encoding] = config['encoding'] if config['encoding']
self.reset
self.setup
@@ -57,9 +56,10 @@ module Jekyll
self.static_files = []
self.categories = Hash.new { |hash, key| hash[key] = [] }
self.tags = Hash.new { |hash, key| hash[key] = [] }
+ self.data = {}
- if !self.limit_posts.nil? && self.limit_posts < 1
- raise ArgumentError, "Limit posts must be nil or >= 1"
+ if self.limit_posts < 0
+ raise ArgumentError, "limit_posts must be a non-negative number"
end
end
@@ -67,26 +67,44 @@ module Jekyll
#
# Returns nothing.
def setup
- require 'classifier' if self.lsi
+ ensure_not_in_dest
# 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
+ self.plugins.each do |plugins|
+ Dir[File.join(plugins, "**/*.rb")].sort.each do |f|
+ require f
+ end
+ end
+ self.gems.each do |gem|
+ require gem
end
end
- self.converters = Jekyll::Converter.subclasses.select do |c|
- !self.safe || c.safe
- end.map do |c|
- c.new(self.config)
+ self.converters = instantiate_subclasses(Jekyll::Converter)
+ self.generators = instantiate_subclasses(Jekyll::Generator)
+ end
+
+ # Check that the destination dir isn't the source dir or a directory
+ # parent to the source dir.
+ def ensure_not_in_dest
+ dest = Pathname.new(self.dest)
+ Pathname.new(self.source).ascend do |path|
+ if path == dest
+ raise FatalException.new "Destination directory cannot be or contain the Source directory."
+ end
end
+ end
- self.generators = Jekyll::Generator.subclasses.select do |c|
- !self.safe || c.safe
- end.map do |c|
- c.new(self.config)
+ # Internal: Setup the plugin search path
+ #
+ # Returns an Array of plugin search paths
+ def plugins_path
+ if (config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
+ [File.join(self.source, config['plugins'])]
+ else
+ Array(config['plugins']).map { |d| File.expand_path(d) }
end
end
@@ -96,17 +114,18 @@ module Jekyll
def read
self.read_layouts
self.read_directories
+ self.read_data(config['data_source'])
end
- # Read all the files in <source>/<dir>/_layouts and create a new Layout
- # object with each one.
+ # Read all the files in <source>/<layouts> and create a new Layout object
+ # with each one.
#
# Returns nothing.
- def read_layouts(dir = '')
- base = File.join(self.source, dir, "_layouts")
+ def read_layouts
+ base = File.join(self.source, self.config['layouts'])
return unless File.exists?(base)
entries = []
- Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }
+ Dir.chdir(base) { entries = filter_entries(Dir['**/*.*']) }
entries.each do |f|
name = f.split(".")[0..-2].join(".")
@@ -118,30 +137,27 @@ module Jekyll
# that will become part of the site according to the rules in
# filter_entries.
#
- # dir - The String relative path of the directory to read.
+ # dir - The String relative path of the directory to read. Default: ''.
#
# Returns nothing.
def read_directories(dir = '')
base = File.join(self.source, dir)
- entries = Dir.chdir(base) { filter_entries(Dir['*']) }
+ entries = Dir.chdir(base) { filter_entries(Dir.entries('.')) }
self.read_posts(dir)
+ self.read_drafts(dir) if self.show_drafts
+ self.posts.sort!
+ limit_posts! if limit_posts > 0 # limit the posts if :limit_posts option is set
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
+ f_rel = File.join(dir, f)
+ read_directories(f_rel) unless self.dest.sub(/\/$/, '') == f_abs
+ elsif has_yaml_header?(f_abs)
+ pages << Page.new(self, self.source, dir, f)
+ else
+ static_files << StaticFile.new(self, self.source, dir, f)
end
end
end
@@ -153,27 +169,54 @@ module Jekyll
#
# 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['**/*']) }
+ posts = read_things(dir, '_posts', Post)
- # 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
+ posts.each do |post|
+ if post.published && (self.future || post.date <= self.time)
+ aggregate_post_info(post)
end
end
+ end
- self.posts.sort!
+ # Read all the files in <source>/<dir>/_drafts and create a new Post
+ # object with each one.
+ #
+ # dir - The String relative path of the directory to read.
+ #
+ # Returns nothing.
+ def read_drafts(dir)
+ drafts = read_things(dir, '_drafts', Draft)
+
+ drafts.each do |draft|
+ aggregate_post_info(draft)
+ end
+ end
- # limit the posts if :limit_posts option is set
- self.posts = self.posts[-limit_posts, limit_posts] if limit_posts
+ def read_things(dir, magic_dir, klass)
+ get_entries(dir, magic_dir).map do |entry|
+ klass.new(self, self.source, dir, entry) if klass.valid?(entry)
+ end.reject do |entry|
+ entry.nil?
+ end
+ end
+
+ # Read and parse all yaml files under <source>/<dir>
+ #
+ # Returns nothing
+ def read_data(dir)
+ base = File.join(self.source, dir)
+ return unless File.directory?(base) && (!self.safe || !File.symlink?(base))
+
+ entries = Dir.chdir(base) { Dir['*.{yaml,yml}'] }
+ entries.delete_if { |e| File.directory?(File.join(base, e)) }
+
+ entries.each do |entry|
+ path = File.join(self.source, dir, entry)
+ next if File.symlink?(path) && self.safe
+
+ key = sanitize_filename(File.basename(entry, '.*'))
+ self.data[key] = YAML.safe_load_file(path)
+ end
end
# Run each of the Generators.
@@ -189,12 +232,11 @@ module Jekyll
#
# Returns nothing.
def render
- self.posts.each do |post|
- post.render(self.layouts, site_payload)
- end
+ relative_permalinks_deprecation_method
- self.pages.each do |page|
- page.render(self.layouts, site_payload)
+ payload = site_payload
+ [self.posts, self.pages].flatten.each do |page_or_post|
+ page_or_post.render(self.layouts, payload)
end
self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a } }
@@ -207,50 +249,17 @@ module Jekyll
#
# 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)
+ site_cleaner.cleanup!
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
+ each_site_file { |item| item.write(self.dest) }
end
- # Constructs a Hash of Posts indexed by the specified Post attribute.
+ # Construct a Hash of Posts indexed by the specified Post attribute.
#
# post_attr - The String name of the Post attribute.
#
@@ -272,6 +281,14 @@ module Jekyll
hash
end
+ # Prepare site data for site payload. The method maintains backward compatibility
+ # if the key 'data' is already used in _config.yml.
+ #
+ # Returns the Hash to be hooked to site.data.
+ def site_data
+ self.config['data'] || self.data
+ end
+
# The Hash payload containing site-wide data.
#
# Returns the Hash: { "site" => data } where data is a Hash with keys:
@@ -286,13 +303,15 @@ module Jekyll
# "tags" - The Hash of tag values and Posts.
# See Site#post_attr_hash for type info.
def site_payload
- {"site" => self.config.merge({
+ {"jekyll" => { "version" => Jekyll::VERSION },
+ "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')})}
+ "tags" => post_attr_hash('tags'),
+ "data" => site_data})}
end
# Filter out any files/directories that are hidden or backup files (start
@@ -300,18 +319,11 @@ module Jekyll
# 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.
+ # entries - The Array of String 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
+ EntryFilter.new(self).filter(entries)
end
# Get the implementation class for the given Converter.
@@ -327,5 +339,89 @@ module Jekyll
raise "Converter implementation not found for #{klass}"
end
end
+
+ # Create array of instances of the subclasses of the class or module
+ # passed in as argument.
+ #
+ # klass - class or module containing the subclasses which should be
+ # instantiated
+ #
+ # Returns array of instances of subclasses of parameter
+ def instantiate_subclasses(klass)
+ klass.subclasses.select do |c|
+ !self.safe || c.safe
+ end.sort.map do |c|
+ c.new(self.config)
+ end
+ end
+
+ # Read the entries from a particular directory for processing
+ #
+ # dir - The String relative path of the directory to read
+ # subfolder - The String directory to read
+ #
+ # Returns the list of entries to process
+ def get_entries(dir, subfolder)
+ base = File.join(self.source, dir, subfolder)
+ return [] unless File.exists?(base)
+ entries = Dir.chdir(base) { filter_entries(Dir['**/*']) }
+ entries.delete_if { |e| File.directory?(File.join(base, e)) }
+ end
+
+ # Aggregate post information
+ #
+ # post - The Post object to aggregate information for
+ #
+ # Returns nothing
+ def aggregate_post_info(post)
+ self.posts << post
+ post.categories.each { |c| self.categories[c] << post }
+ post.tags.each { |c| self.tags[c] << post }
+ end
+
+ def relative_permalinks_deprecation_method
+ if config['relative_permalinks'] && has_relative_page?
+ $stderr.puts # Places newline after "Generating..."
+ Jekyll.logger.warn "Deprecation:", "Starting in 2.0, permalinks for pages" +
+ " in subfolders must be relative to the" +
+ " site source directory, not the parent" +
+ " directory. Check http://jekyllrb.com/docs/upgrading/"+
+ " for more info."
+ $stderr.print Jekyll.logger.formatted_topic("") + "..." # for "done."
+ end
+ end
+
+ def each_site_file
+ %w(posts pages static_files).each do |type|
+ self.send(type).each do |item|
+ yield item
+ end
+ end
+ end
+
+ private
+
+ def has_relative_page?
+ self.pages.any? { |page| page.uses_relative_permalinks }
+ end
+
+ def has_yaml_header?(file)
+ "---" == File.open(file) { |fd| fd.read(3) }
+ end
+
+ def limit_posts!
+ limit = self.posts.length < limit_posts ? self.posts.length : limit_posts
+ self.posts = self.posts[-limit, limit]
+ end
+
+ def site_cleaner
+ @site_cleaner ||= Cleaner.new(self)
+ end
+
+ def sanitize_filename(name)
+ name = name.gsub(/[^\w\s_-]+/, '')
+ name = name.gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
+ name = name.gsub(/\s+/, '_')
+ end
end
end
diff --git a/lib/jekyll/static_file.rb b/lib/jekyll/static_file.rb
index 318177c..3d863ca 100644
--- a/lib/jekyll/static_file.rb
+++ b/lib/jekyll/static_file.rb
@@ -1,5 +1,4 @@
module Jekyll
-
class StaticFile
# The cache of last modification times [path] -> mtime.
@@mtimes = Hash.new
@@ -68,5 +67,4 @@ module Jekyll
nil
end
end
-
end
diff --git a/lib/jekyll/stevenson.rb b/lib/jekyll/stevenson.rb
new file mode 100644
index 0000000..8765220
--- /dev/null
+++ b/lib/jekyll/stevenson.rb
@@ -0,0 +1,89 @@
+module Jekyll
+ class Stevenson
+ attr_accessor :log_level
+
+ DEBUG = 0
+ INFO = 1
+ WARN = 2
+ ERROR = 3
+
+ # Public: Create a new instance of Stevenson, Jekyll's logger
+ #
+ # level - (optional, integer) the log level
+ #
+ # Returns nothing
+ def initialize(level = INFO)
+ @log_level = level
+ end
+
+ # Public: Print a jekyll debug message to stdout
+ #
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
+ # message - the message detail
+ #
+ # Returns nothing
+ def debug(topic, message = nil)
+ $stdout.puts(message(topic, message)) if log_level <= DEBUG
+ end
+
+ # Public: Print a jekyll message to stdout
+ #
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
+ # message - the message detail
+ #
+ # Returns nothing
+ def info(topic, message = nil)
+ $stdout.puts(message(topic, message)) if log_level <= INFO
+ end
+
+ # Public: Print a jekyll message to stderr
+ #
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
+ # message - the message detail
+ #
+ # Returns nothing
+ def warn(topic, message = nil)
+ $stderr.puts(message(topic, message).yellow) if log_level <= WARN
+ end
+
+ # Public: Print a jekyll error message to stderr
+ #
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
+ # message - the message detail
+ #
+ # Returns nothing
+ def error(topic, message = nil)
+ $stderr.puts(message(topic, message).red) if log_level <= ERROR
+ end
+
+ # Public: Print a Jekyll error message to stderr and immediately abort the process
+ #
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
+ # message - the message detail (can be omitted)
+ #
+ # Returns nothing
+ def abort_with(topic, message = nil)
+ error(topic, message)
+ abort
+ end
+
+ # Public: Build a Jekyll topic method
+ #
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
+ # message - the message detail
+ #
+ # Returns the formatted message
+ def message(topic, message)
+ formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ')
+ end
+
+ # Public: Format the topic
+ #
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
+ #
+ # Returns the formatted topic statement
+ def formatted_topic(topic)
+ "#{topic} ".rjust(20)
+ end
+ end
+end
diff --git a/lib/jekyll/tags/gist.rb b/lib/jekyll/tags/gist.rb
new file mode 100644
index 0000000..f4f3288
--- /dev/null
+++ b/lib/jekyll/tags/gist.rb
@@ -0,0 +1,48 @@
+# Gist Liquid Tag
+#
+# Example:
+# {% gist 1234567 %}
+# {% gist 1234567 file.rb %}
+
+module Jekyll
+ class GistTag < Liquid::Tag
+
+ def render(context)
+ if tag_contents = determine_arguments(@markup.strip)
+ gist_id, filename = tag_contents[0], tag_contents[1]
+ gist_script_tag(gist_id, filename)
+ else
+ raise ArgumentError.new <<-eos
+Syntax error in tag 'gist' while parsing the following markup:
+
+ #{@markup}
+
+Valid syntax:
+ for public gists: {% gist 1234567 %}
+ for private gists: {% gist user/1234567 %}
+eos
+ end
+ end
+
+ private
+
+ def determine_arguments(input)
+ matched = if input.include?("/")
+ input.match(/\A([a-zA-Z0-9\/\-_]+) ?(\S*)\Z/)
+ else
+ input.match(/\A(\d+) ?(\S*)\Z/)
+ end
+ [matched[1].strip, matched[2].strip] if matched && matched.length >= 3
+ end
+
+ def gist_script_tag(gist_id, filename = nil)
+ if filename.empty?
+ "<script src=\"https://gist.github.com/#{gist_id}.js\"> </script>"
+ else
+ "<script src=\"https://gist.github.com/#{gist_id}.js?file=#{filename}\"> </script>"
+ end
+ end
+ end
+end
+
+Liquid::Template.register_tag('gist', Jekyll::GistTag)
diff --git a/lib/jekyll/tags/highlight.rb b/lib/jekyll/tags/highlight.rb
index 8642c36..2ea144d 100644
--- a/lib/jekyll/tags/highlight.rb
+++ b/lib/jekyll/tags/highlight.rb
@@ -1,71 +1,85 @@
module Jekyll
+ module Tags
+ class HighlightBlock < Liquid::Block
+ include Liquid::StandardFilters
- class HighlightBlock < Liquid::Block
- include Liquid::StandardFilters
+ # The regular expression syntax checker. Start with the language specifier.
+ # Follow that by zero or more space separated options that take one of two
+ # forms:
+ #
+ # 1. name
+ # 2. name=value
+ SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/
- # 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
+ def initialize(tag_name, markup, tokens)
+ super
+ if markup.strip =~ SYNTAX
+ @lang = $1.downcase
+ @options = {}
+ if defined?($2) && $2 != ''
+ $2.split.each do |opt|
+ key, value = opt.split('=')
+ if value.nil?
+ if key == 'linenos'
+ value = 'inline'
+ else
+ value = true
+ end
end
+ @options[key] = value
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 = {}
+ raise SyntaxError.new <<-eos
+Syntax Error in tag 'highlight' while parsing the following markup:
+
+ #{markup}
+
+Valid syntax: highlight <lang> [linenos]
+eos
end
- else
- raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight <lang> [linenos]")
end
- end
- def render(context)
- if context.registers[:site].pygments
- render_pygments(context, super)
- else
- render_codehighlighter(context, super)
+ def render(context)
+ if context.registers[:site].pygments
+ render_pygments(context, super)
+ else
+ render_codehighlighter(context, super)
+ end
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_pygments(context, code)
+ require 'pygments'
- def render_codehighlighter(context, code)
- #The div is required because RDiscount blows ass
- <<-HTML
-<div>
- <pre><code class='#{@lang}'>#{h(code).strip}</code></pre>
-</div>
- HTML
- end
+ @options[:encoding] = 'utf-8'
- def add_code_tags(code, lang)
- # Add nested <code> tags to code blocks
- code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
- code = code.sub(/<\/pre>/,"</code></pre>")
- end
+ output = add_code_tags(
+ Pygments.highlight(code, :lexer => @lang, :options => @options),
+ @lang
+ )
- end
+ 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
+ <div>
+ <pre><code class='#{@lang}'>#{h(code).strip}</code></pre>
+ </div>
+ HTML
+ end
+
+ def add_code_tags(code, lang)
+ # Add nested <code> tags to code blocks
+ code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
+ code = code.sub(/<\/pre>/,"</code></pre>")
+ end
+ end
+ end
end
-Liquid::Template.register_tag('highlight', Jekyll::HighlightBlock)
+Liquid::Template.register_tag('highlight', Jekyll::Tags::HighlightBlock)
diff --git a/lib/jekyll/tags/include.rb b/lib/jekyll/tags/include.rb
index e71d07f..a261e6f 100644
--- a/lib/jekyll/tags/include.rb
+++ b/lib/jekyll/tags/include.rb
@@ -1,37 +1,137 @@
module Jekyll
+ module Tags
+ class IncludeTagError < StandardError
+ attr_accessor :path
- class IncludeTag < Liquid::Tag
- def initialize(tag_name, file, tokens)
- super
- @file = file.strip
+ def initialize(msg, path)
+ super(msg)
+ @path = path
+ end
end
- def render(context)
- includes_dir = File.join(context.registers[:site].source, '_includes')
+ class IncludeTag < Liquid::Tag
+
+ SYNTAX_EXAMPLE = "{% include file.ext param='value' param2='value' %}"
+
+ VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
+
+ INCLUDES_DIR = '_includes'
+
+ def initialize(tag_name, markup, tokens)
+ super
+ @file, @params = markup.strip.split(' ', 2);
+ validate_params if @params
+ end
- if File.symlink?(includes_dir)
- return "Includes directory '#{includes_dir}' cannot be a symlink"
+ def parse_params(context)
+ params = {}
+ markup = @params
+
+ while match = VALID_SYNTAX.match(markup) do
+ markup = markup[match.end(0)..-1]
+
+ value = if match[2]
+ match[2].gsub(/\\"/, '"')
+ elsif match[3]
+ match[3].gsub(/\\'/, "'")
+ elsif match[4]
+ context[match[4]]
+ end
+
+ params[match[1]] = value
+ end
+ params
end
- if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
- return "Include file '#{@file}' contains invalid characters or sequences"
+ def validate_file_name(file)
+ if file !~ /^[a-zA-Z0-9_\/\.-]+$/ || file =~ /\.\// || file =~ /\/\./
+ raise ArgumentError.new <<-eos
+Invalid syntax for include tag. File contains invalid characters or sequences:
+
+ #{@file}
+
+Valid syntax:
+
+ #{SYNTAX_EXAMPLE}
+
+eos
+ end
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)
+ def validate_params
+ full_valid_syntax = Regexp.compile('\A\s*(?:' + VALID_SYNTAX.to_s + '(?=\s|\z)\s*)*\z')
+ unless @params =~ full_valid_syntax
+ raise ArgumentError.new <<-eos
+Invalid syntax for include tag:
+
+ #{@params}
+
+Valid syntax:
+
+ #{SYNTAX_EXAMPLE}
+
+eos
+ end
+ end
+
+ # Grab file read opts in the context
+ def file_read_opts(context)
+ context.registers[:site].file_read_opts
+ end
+
+ def retrieve_variable(context)
+ if /\{\{([\w\-\.]+)\}\}/ =~ @file
+ raise ArgumentError.new("No variable #{$1} was found in include tag") if context[$1].nil?
+ context[$1]
+ end
+ end
+
+ def render(context)
+ dir = File.join(context.registers[:site].source, INCLUDES_DIR)
+ validate_dir(dir, context.registers[:site].safe)
+
+ file = retrieve_variable(context) || @file
+ validate_file_name(file)
+
+ path = File.join(dir, file)
+ validate_file(path, context.registers[:site].safe)
+
+ begin
+ partial = Liquid::Template.parse(source(path, context))
+
context.stack do
- partial.render(context)
+ context['include'] = parse_params(context) if @params
+ partial.render!(context)
end
- else
- "Included file '#{@file}' not found in _includes directory"
+ rescue => e
+ raise IncludeTagError.new e.message, File.join(INCLUDES_DIR, @file)
end
end
+
+ def validate_dir(dir, safe)
+ if File.symlink?(dir) && safe
+ raise IOError.new "Includes directory '#{dir}' cannot be a symlink"
+ end
+ end
+
+ def validate_file(file, safe)
+ if !File.exists?(file)
+ raise IOError.new "Included file '#{@file}' not found in '#{INCLUDES_DIR}' directory"
+ elsif File.symlink?(file) && safe
+ raise IOError.new "The included file '#{INCLUDES_DIR}/#{@file}' should not be a symlink"
+ end
+ end
+
+ def blank?
+ false
+ end
+
+ # This method allows to modify the file content by inheriting from the class.
+ def source(file, context)
+ File.read_with_options(file, file_read_opts(context))
+ end
end
end
-
end
-Liquid::Template.register_tag('include', Jekyll::IncludeTag)
+Liquid::Template.register_tag('include', Jekyll::Tags::IncludeTag)
diff --git a/lib/jekyll/tags/post_url.rb b/lib/jekyll/tags/post_url.rb
new file mode 100644
index 0000000..063e22a
--- /dev/null
+++ b/lib/jekyll/tags/post_url.rb
@@ -0,0 +1,63 @@
+module Jekyll
+ module Tags
+ class PostComparer
+ MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)$/
+
+ attr_accessor :date, :slug
+
+ def initialize(name)
+ all, path, date, slug = *name.sub(/^\//, "").match(MATCHER)
+ @slug = path ? path + slug : slug
+ @date = Time.parse(date)
+ end
+
+ def ==(other)
+ slug == post_slug(other) &&
+ date.year == other.date.year &&
+ date.month == other.date.month &&
+ date.day == other.date.day
+ end
+
+ private
+ # Construct the directory-aware post slug for a Jekyll::Post
+ #
+ # other - the Jekyll::Post
+ #
+ # Returns the post slug with the subdirectory (relative to _posts)
+ def post_slug(other)
+ path = other.name.split("/")[0...-1].join("/")
+ if path.nil? || path == ""
+ other.slug
+ else
+ path + '/' + other.slug
+ end
+ end
+ end
+
+ class PostUrl < Liquid::Tag
+ def initialize(tag_name, post, tokens)
+ super
+ @orig_post = post.strip
+ @post = PostComparer.new(@orig_post)
+ end
+
+ def render(context)
+ site = context.registers[:site]
+
+ site.posts.each do |p|
+ if @post == p
+ return p.url
+ end
+ end
+
+ raise ArgumentError.new <<-eos
+Could not find post "#{@orig_post}" in tag 'post_url'.
+
+Make sure the post exists and the name is correct.
+eos
+ end
+ end
+ end
+end
+
+Liquid::Template.register_tag('post_url', Jekyll::Tags::PostUrl)
diff --git a/lib/jekyll/url.rb b/lib/jekyll/url.rb
new file mode 100644
index 0000000..10e1cb5
--- /dev/null
+++ b/lib/jekyll/url.rb
@@ -0,0 +1,67 @@
+# Public: Methods that generate a URL for a resource such as a Post or a Page.
+#
+# Examples
+#
+# URL.new({
+# :template => /:categories/:title.html",
+# :placeholders => {:categories => "ruby", :title => "something"}
+# }).to_s
+#
+module Jekyll
+ class URL
+
+ # options - One of :permalink or :template must be supplied.
+ # :template - The String used as template for URL generation,
+ # for example "/:path/:basename:output_ext", where
+ # a placeholder is prefixed with a colon.
+ # :placeholders - A hash containing the placeholders which will be
+ # replaced when used inside the template. E.g.
+ # { "year" => Time.now.strftime("%Y") } would replace
+ # the placeholder ":year" with the current year.
+ # :permalink - If supplied, no URL will be generated from the
+ # template. Instead, the given permalink will be
+ # used as URL.
+ def initialize(options)
+ @template = options[:template]
+ @placeholders = options[:placeholders] || {}
+ @permalink = options[:permalink]
+
+ if (@template || @permalink).nil?
+ raise ArgumentError, "One of :template or :permalink must be supplied."
+ end
+ end
+
+ # The generated relative URL of the resource
+ #
+ # Returns the String URL
+ def to_s
+ sanitize_url(@permalink || generate_url)
+ end
+
+ # Internal: Generate the URL by replacing all placeholders with their
+ # respective values
+ #
+ # Returns the _unsanitizied_ String URL
+ def generate_url
+ @placeholders.inject(@template) do |result, token|
+ result.gsub(/:#{token.first}/, token.last)
+ end
+ end
+
+ # Returns a sanitized String URL
+ def sanitize_url(in_url)
+ # Remove all double slashes
+ url = in_url.gsub(/\/\//, "/")
+
+ # Remove every URL segment that consists solely of dots
+ url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
+
+ # Append a trailing slash to the URL if the unsanitized URL had one
+ url += "/" if in_url =~ /\/$/
+
+ # Always add a leading slash
+ url.gsub!(/\A([^\/])/, '/\1')
+ url
+ end
+ end
+end
diff --git a/lib/site_template/.gitignore b/lib/site_template/.gitignore
new file mode 100644
index 0000000..c08f9ad
--- /dev/null
+++ b/lib/site_template/.gitignore
@@ -0,0 +1 @@
+_site
\ No newline at end of file
diff --git a/lib/site_template/_config.yml b/lib/site_template/_config.yml
new file mode 100644
index 0000000..85daa77
--- /dev/null
+++ b/lib/site_template/_config.yml
@@ -0,0 +1,3 @@
+name: Your New Jekyll Site
+markdown: redcarpet
+pygments: true
diff --git a/lib/site_template/_layouts/default.html b/lib/site_template/_layouts/default.html
new file mode 100644
index 0000000..22e7e3f
--- /dev/null
+++ b/lib/site_template/_layouts/default.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>{{ page.title }}</title>
+ <meta name="viewport" content="width=device-width">
+
+ <!-- syntax highlighting CSS -->
+ <link rel="stylesheet" href="/css/syntax.css">
+
+ <!-- Custom CSS -->
+ <link rel="stylesheet" href="/css/main.css">
+
+ </head>
+ <body>
+
+ <div class="site">
+ <div class="header">
+ <h1 class="title"><a href="/">{{ site.name }}</a></h1>
+ <a class="extra" href="/">home</a>
+ </div>
+
+ {{ content }}
+
+ <div class="footer">
+ <div class="contact">
+ <p>
+ Your Name<br />
+ What You Are<br />
+ you at example.com
+ </p>
+ </div>
+ <div class="contact">
+ <p>
+ <a href="https://github.com/yourusername">github.com/yourusername</a><br />
+ <a href="https://twitter.com/yourusername">twitter.com/yourusername</a><br />
+ </p>
+ </div>
+ </div>
+ </div>
+
+ </body>
+</html>
diff --git a/lib/site_template/_layouts/post.html b/lib/site_template/_layouts/post.html
new file mode 100644
index 0000000..04e3586
--- /dev/null
+++ b/lib/site_template/_layouts/post.html
@@ -0,0 +1,9 @@
+---
+layout: default
+---
+<h2>{{ page.title }}</h2>
+<p class="meta">{{ page.date | date_to_string }}</p>
+
+<div class="post">
+{{ content }}
+</div>
diff --git a/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb b/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb
new file mode 100644
index 0000000..c500b41
--- /dev/null
+++ b/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb
@@ -0,0 +1,24 @@
+---
+layout: post
+title: "Welcome to Jekyll!"
+date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S') %>
+categories: jekyll update
+---
+
+You'll find this post in your `_posts` directory - edit this post and re-build (or run with the `-w` switch) to see your changes!
+To add new posts, simply add a file in the `_posts` directory that follows the convention: YYYY-MM-DD-name-of-post.ext.
+
+Jekyll also offers powerful support for code snippets:
+
+{% highlight ruby %}
+def print_hi(name)
+ puts "Hi, #{name}"
+end
+print_hi('Tom')
+#=> prints 'Hi, Tom' to STDOUT.
+{% endhighlight %}
+
+Check out the [Jekyll docs][jekyll] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll's GitHub repo][jekyll-gh].
+
+[jekyll-gh]: https://github.com/mojombo/jekyll
+[jekyll]: http://jekyllrb.com
diff --git a/lib/site_template/css/main.css b/lib/site_template/css/main.css
new file mode 100755
index 0000000..1a2c013
--- /dev/null
+++ b/lib/site_template/css/main.css
@@ -0,0 +1,160 @@
+/*****************************************************************************/
+/*
+/* Common
+/*
+/*****************************************************************************/
+
+/* Global Reset */
+* {
+ margin: 0;
+ padding: 0;
+}
+
+html, body { height: 100%; }
+
+body {
+ background-color: #FFF;
+ font: 13.34px Helvetica, Arial, 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: #000; }
+a:visited { color: #a0a; }
+
+/*****************************************************************************/
+/*
+/* Home
+/*
+/*****************************************************************************/
+.posts {
+ list-style-type: none;
+ margin-bottom: 2em;
+}
+
+.posts li {
+ line-height: 1.75em;
+}
+
+.posts span {
+ color: #aaa;
+ font-family: Monaco, "Courier New", monospace;
+ font-size: 80%;
+}
+
+/*****************************************************************************/
+/*
+/* Site
+/*
+/*****************************************************************************/
+
+.site {
+ font-size: 115%;
+ text-align: justify;
+ width: 42em;
+ margin: 3em auto 2em;
+ line-height: 1.5em;
+}
+
+.header a {
+ font-weight: bold;
+ text-decoration: none;
+}
+
+.title {
+ display: inline-block;
+ margin-bottom: 2em;
+}
+
+.title a {
+ color: #a00;
+}
+
+.title a:hover {
+ color: #000;
+}
+
+.header a.extra {
+ color: #aaa;
+ margin-left: 1em;
+}
+
+.header a.extra:hover {
+ color: #000;
+}
+
+.meta {
+ color: #aaa;
+}
+
+.footer {
+ font-size: 80%;
+ color: #666;
+ border-top: 4px solid #eee;
+ margin-top: 2em;
+ overflow: hidden;
+}
+
+.footer .contact {
+ float: left;
+ margin-right: 3em;
+}
+
+.footer .contact a {
+ color: #8085C1;
+}
+
+.footer .rss {
+ margin-top: 1.1em;
+ margin-right: -.2em;
+ float: right;
+}
+
+.footer .rss img {
+ border: 0;
+}
+
+/*****************************************************************************/
+/*
+/* Posts
+/*
+/*****************************************************************************/
+
+/* standard */
+.post pre {
+ border: 1px solid #ddd;
+ background-color: #eef;
+ padding: 0 .4em;
+}
+
+.post ul, .post ol {
+ margin-left: 1.35em;
+}
+
+.post code {
+ border: 1px solid #ddd;
+ background-color: #eef;
+ padding: 0 .2em;
+}
+
+.post pre code {
+ border: none;
+}
+
+/* terminal */
+.post pre.terminal {
+ border: 1px solid #000;
+ background-color: #333;
+ color: #FFF;
+}
+
+.post pre.terminal code {
+ background-color: #333;
+}
diff --git a/lib/site_template/css/syntax.css b/lib/site_template/css/syntax.css
new file mode 100644
index 0000000..2774b76
--- /dev/null
+++ b/lib/site_template/css/syntax.css
@@ -0,0 +1,60 @@
+.highlight { background: #ffffff; }
+.highlight .c { color: #999988; font-style: italic } /* Comment */
+.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
+.highlight .k { font-weight: bold } /* Keyword */
+.highlight .o { font-weight: bold } /* Operator */
+.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
+.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
+.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #aa0000 } /* Generic.Error */
+.highlight .gh { color: #999999 } /* Generic.Heading */
+.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
+.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
+.highlight .go { color: #888888 } /* Generic.Output */
+.highlight .gp { color: #555555 } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
+.highlight .gt { color: #aa0000 } /* Generic.Traceback */
+.highlight .kc { font-weight: bold } /* Keyword.Constant */
+.highlight .kd { font-weight: bold } /* Keyword.Declaration */
+.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
+.highlight .kr { font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
+.highlight .m { color: #009999 } /* Literal.Number */
+.highlight .s { color: #d14 } /* Literal.String */
+.highlight .na { color: #008080 } /* Name.Attribute */
+.highlight .nb { color: #0086B3 } /* Name.Builtin */
+.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
+.highlight .no { color: #008080 } /* Name.Constant */
+.highlight .ni { color: #800080 } /* Name.Entity */
+.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
+.highlight .nn { color: #555555 } /* Name.Namespace */
+.highlight .nt { color: #000080 } /* Name.Tag */
+.highlight .nv { color: #008080 } /* Name.Variable */
+.highlight .ow { font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #009999 } /* Literal.Number.Float */
+.highlight .mh { color: #009999 } /* Literal.Number.Hex */
+.highlight .mi { color: #009999 } /* Literal.Number.Integer */
+.highlight .mo { color: #009999 } /* Literal.Number.Oct */
+.highlight .sb { color: #d14 } /* Literal.String.Backtick */
+.highlight .sc { color: #d14 } /* Literal.String.Char */
+.highlight .sd { color: #d14 } /* Literal.String.Doc */
+.highlight .s2 { color: #d14 } /* Literal.String.Double */
+.highlight .se { color: #d14 } /* Literal.String.Escape */
+.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
+.highlight .si { color: #d14 } /* Literal.String.Interpol */
+.highlight .sx { color: #d14 } /* Literal.String.Other */
+.highlight .sr { color: #009926 } /* Literal.String.Regex */
+.highlight .s1 { color: #d14 } /* Literal.String.Single */
+.highlight .ss { color: #990073 } /* Literal.String.Symbol */
+.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #008080 } /* Name.Variable.Class */
+.highlight .vg { color: #008080 } /* Name.Variable.Global */
+.highlight .vi { color: #008080 } /* Name.Variable.Instance */
+.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
diff --git a/lib/site_template/index.html b/lib/site_template/index.html
new file mode 100644
index 0000000..c726819
--- /dev/null
+++ b/lib/site_template/index.html
@@ -0,0 +1,13 @@
+---
+layout: default
+title: Your New Jekyll Site
+---
+
+<div id="home">
+ <h1>Blog Posts</h1>
+ <ul class="posts">
+ {% for post in site.posts %}
+ <li><span>{{ post.date | date_to_string }}</span> » <a href="{{ post.url }}">{{ post.title }}</a></li>
+ {% endfor %}
+ </ul>
+</div>
\ No newline at end of file
diff --git a/metadata.yml b/metadata.yml
index 11a02af..3413174 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,312 +1,559 @@
---- !ruby/object:Gem::Specification
+--- !ruby/object:Gem::Specification
name: jekyll
-version: !ruby/object:Gem::Version
- hash: 55
- prerelease:
- segments:
- - 0
- - 11
- - 2
- version: 0.11.2
+version: !ruby/object:Gem::Version
+ version: 1.4.2
platform: ruby
-authors:
+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
+date: 2013-12-16 00:00:00.000000000 Z
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: liquid
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 2.5.2
+ type: :runtime
prerelease: false
- requirement: &id001 !ruby/object:Gem::Requirement
- none: false
- requirements:
- - - ~>
- - !ruby/object:Gem::Version
- hash: 5
- segments:
- - 2
- - 3
- version: "2.3"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 2.5.2
+- !ruby/object:Gem::Dependency
+ name: classifier
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.3'
+- !ruby/object:Gem::Dependency
+ name: listen
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ 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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.3'
+- !ruby/object:Gem::Dependency
+ name: maruku
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.7.0
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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.7.0
+- !ruby/object:Gem::Dependency
+ name: pygments.rb
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.5.0
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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.5.0
+- !ruby/object:Gem::Dependency
+ name: commander
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 4.1.3
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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 4.1.3
+- !ruby/object:Gem::Dependency
+ name: safe_yaml
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.9.7
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
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.9.7
+- !ruby/object:Gem::Dependency
+ name: colorator
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '0.1'
+ type: :runtime
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '0.1'
+- !ruby/object:Gem::Dependency
+ name: redcarpet
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 2.3.0
+ type: :runtime
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 2.3.0
+- !ruby/object:Gem::Dependency
+ name: toml
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.1.0
+ type: :runtime
prerelease: false
- requirement: &id008 !ruby/object:Gem::Requirement
- none: false
- requirements:
- - - ~>
- - !ruby/object:Gem::Version
- hash: 17
- segments:
- - 3
- - 11
- version: "3.11"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.1.0
+- !ruby/object:Gem::Dependency
+ name: rake
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '10.1'
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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '10.1'
+- !ruby/object:Gem::Dependency
+ name: rdoc
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '3.11'
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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '3.11'
+- !ruby/object:Gem::Dependency
+ name: redgreen
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.2'
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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.2'
+- !ruby/object:Gem::Dependency
+ name: shoulda
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 3.3.2
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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 3.3.2
+- !ruby/object:Gem::Dependency
+ name: rr
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ 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"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.1'
+- !ruby/object:Gem::Dependency
+ name: cucumber
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.3'
type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.3'
+- !ruby/object:Gem::Dependency
name: RedCloth
- version_requirements: *id013
-- !ruby/object:Gem::Dependency
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '4.2'
+ type: :development
prerelease: false
- requirement: &id014 !ruby/object:Gem::Requirement
- none: false
- requirements:
- - - ~>
- - !ruby/object:Gem::Version
- hash: 3
- segments:
- - 1
- - 6
- version: "1.6"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '4.2'
+- !ruby/object:Gem::Dependency
+ name: kramdown
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.2'
type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.2'
+- !ruby/object:Gem::Dependency
name: rdiscount
- version_requirements: *id014
-- !ruby/object:Gem::Dependency
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.6'
+ type: :development
prerelease: false
- requirement: &id015 !ruby/object:Gem::Requirement
- none: false
- requirements:
- - - ~>
- - !ruby/object:Gem::Version
- hash: 29
- segments:
- - 1
- - 9
- version: "1.9"
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.6'
+- !ruby/object:Gem::Dependency
+ name: launchy
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '2.3'
type: :development
- name: redcarpet
- version_requirements: *id015
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '2.3'
+- !ruby/object:Gem::Dependency
+ name: simplecov
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '0.7'
+ type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '0.7'
+- !ruby/object:Gem::Dependency
+ name: simplecov-gem-adapter
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 1.0.1
+ type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 1.0.1
+- !ruby/object:Gem::Dependency
+ name: coveralls
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.7.0
+ type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 0.7.0
+- !ruby/object:Gem::Dependency
+ name: mime-types
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.5'
+ type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: '1.5'
+- !ruby/object:Gem::Dependency
+ name: activesupport
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 3.2.13
+ type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ~>
+ - !ruby/object:Gem::Version
+ version: 3.2.13
+- !ruby/object:Gem::Dependency
+ name: jekyll_test_plugin
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - '>='
+ - !ruby/object:Gem::Version
+ version: '0'
+ type: :development
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - '>='
+ - !ruby/object:Gem::Version
+ version: '0'
description: Jekyll is a simple, blog aware, static site generator.
email: tom at mojombo.com
-executables:
+executables:
- jekyll
extensions: []
-
-extra_rdoc_files:
-- README.textile
+extra_rdoc_files:
+- README.markdown
- LICENSE
-files:
+files:
+- CONTRIBUTING.markdown
- Gemfile
-- History.txt
+- History.markdown
- LICENSE
-- README.textile
+- README.markdown
- Rakefile
- bin/jekyll
- cucumber.yml
- features/create_sites.feature
+- features/data.feature
+- features/drafts.feature
- features/embed_filters.feature
+- features/include_tag.feature
- features/markdown.feature
- features/pagination.feature
- features/permalinks.feature
- features/post_data.feature
+- features/post_excerpts.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/cleaner.rb
+- lib/jekyll/command.rb
+- lib/jekyll/commands/build.rb
+- lib/jekyll/commands/doctor.rb
+- lib/jekyll/commands/new.rb
+- lib/jekyll/commands/serve.rb
+- lib/jekyll/configuration.rb
- lib/jekyll/converter.rb
- lib/jekyll/converters/identity.rb
- lib/jekyll/converters/markdown.rb
+- lib/jekyll/converters/markdown/kramdown_parser.rb
+- lib/jekyll/converters/markdown/maruku_parser.rb
+- lib/jekyll/converters/markdown/rdiscount_parser.rb
+- lib/jekyll/converters/markdown/redcarpet_parser.rb
- lib/jekyll/converters/textile.rb
- lib/jekyll/convertible.rb
- lib/jekyll/core_ext.rb
+- lib/jekyll/deprecator.rb
+- lib/jekyll/draft.rb
+- lib/jekyll/entry_filter.rb
- lib/jekyll/errors.rb
+- lib/jekyll/excerpt.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/mime.types
- lib/jekyll/page.rb
- lib/jekyll/plugin.rb
- lib/jekyll/post.rb
+- lib/jekyll/related_posts.rb
- lib/jekyll/site.rb
- lib/jekyll/static_file.rb
+- lib/jekyll/stevenson.rb
+- lib/jekyll/tags/gist.rb
- lib/jekyll/tags/highlight.rb
- lib/jekyll/tags/include.rb
+- lib/jekyll/tags/post_url.rb
+- lib/jekyll/url.rb
+- lib/site_template/.gitignore
+- lib/site_template/_config.yml
+- lib/site_template/_layouts/default.html
+- lib/site_template/_layouts/post.html
+- lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb
+- lib/site_template/css/main.css
+- lib/site_template/css/syntax.css
+- lib/site_template/index.html
+- script/bootstrap
+- site/.gitignore
+- site/CNAME
+- site/README
+- site/_config.yml
+- site/_includes/analytics.html
+- site/_includes/docs_contents.html
+- site/_includes/docs_contents_mobile.html
+- site/_includes/docs_option.html
+- site/_includes/docs_ul.html
+- site/_includes/footer.html
+- site/_includes/header.html
+- site/_includes/news_contents.html
+- site/_includes/news_contents_mobile.html
+- site/_includes/news_item.html
+- site/_includes/primary-nav-items.html
+- site/_includes/section_nav.html
+- site/_includes/top.html
+- site/_layouts/default.html
+- site/_layouts/docs.html
+- site/_layouts/news.html
+- site/_layouts/news_item.html
+- site/_posts/2013-05-06-jekyll-1-0-0-released.markdown
+- site/_posts/2013-05-08-jekyll-1-0-1-released.markdown
+- site/_posts/2013-05-12-jekyll-1-0-2-released.markdown
+- site/_posts/2013-06-07-jekyll-1-0-3-released.markdown
+- site/_posts/2013-07-14-jekyll-1-1-0-released.markdown
+- site/_posts/2013-07-24-jekyll-1-1-1-released.markdown
+- site/_posts/2013-07-25-jekyll-1-0-4-released.markdown
+- site/_posts/2013-07-25-jekyll-1-1-2-released.markdown
+- site/_posts/2013-09-06-jekyll-1-2-0-released.markdown
+- site/_posts/2013-09-14-jekyll-1-2-1-released.markdown
+- site/_posts/2013-10-28-jekyll-1-3-0-rc1-released.markdown
+- site/_posts/2013-11-04-jekyll-1-3-0-released.markdown
+- site/_posts/2013-11-26-jekyll-1-3-1-released.markdown
+- site/_posts/2013-12-07-jekyll-1-4-0-released.markdown
+- site/_posts/2013-12-16-jekyll-1-4-2-released.markdown
+- site/css/gridism.css
+- site/css/normalize.css
+- site/css/pygments.css
+- site/css/style.css
+- site/docs/configuration.md
+- site/docs/contributing.md
+- site/docs/datafiles.md
+- site/docs/deployment-methods.md
+- site/docs/drafts.md
+- site/docs/extras.md
+- site/docs/frontmatter.md
+- site/docs/github-pages.md
+- site/docs/heroku.md
+- site/docs/history.md
+- site/docs/index.md
+- site/docs/installation.md
+- site/docs/migrations.md
+- site/docs/pages.md
+- site/docs/pagination.md
+- site/docs/permalinks.md
+- site/docs/plugins.md
+- site/docs/posts.md
+- site/docs/quickstart.md
+- site/docs/resources.md
+- site/docs/sites.md
+- site/docs/structure.md
+- site/docs/templates.md
+- site/docs/troubleshooting.md
+- site/docs/upgrading.md
+- site/docs/usage.md
+- site/docs/variables.md
+- site/favicon.png
+- site/feed.xml
+- site/freenode.txt
+- site/img/article-footer.png
+- site/img/footer-arrow.png
+- site/img/footer-logo.png
+- site/img/logo-2x.png
+- site/img/octojekyll.png
+- site/img/tube.png
+- site/img/tube1x.png
+- site/index.html
+- site/js/modernizr-2.5.3.min.js
+- site/news/index.html
+- site/news/releases/index.html
+- test/fixtures/broken_front_matter1.erb
+- test/fixtures/broken_front_matter2.erb
+- test/fixtures/broken_front_matter3.erb
+- test/fixtures/exploit_front_matter.erb
+- test/fixtures/front_matter.erb
- test/helper.rb
+- test/source/+/foo.md
- test/source/.htaccess
+- test/source/_config.dev.toml
+- test/source/_data/languages.yml
+- test/source/_data/members.yaml
+- test/source/_data/products.yml
+- test/source/_includes/params.html
- test/source/_includes/sig.markdown
- test/source/_layouts/default.html
+- test/source/_layouts/post/simple.html
- test/source/_layouts/simple.html
+- test/source/_plugins/dummy.rb
- 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
@@ -332,73 +579,93 @@ files:
- 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/_posts/2013-01-02-post-excerpt.markdown
+- test/source/_posts/2013-01-12-nil-layout.textile
+- test/source/_posts/2013-01-12-no-layout.textile
+- test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep
+- test/source/_posts/2013-04-11-custom-excerpt.markdown
+- test/source/_posts/2013-05-10-number-category.textile
+- test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown
+- test/source/_posts/2013-08-01-mkdn-extension.mkdn
+- test/source/_posts/es/2008-11-21-nested.textile
- test/source/about.html
- test/source/category/_posts/2008-9-23-categories.textile
- test/source/contacts.html
+- test/source/contacts/bar.html
+- test/source/contacts/index.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/products.yml
- test/source/sitemap.xml
+- test/source/symlink-test/symlinked-file
- 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_command.rb
- test/test_configuration.rb
+- test/test_convertible.rb
- test/test_core_ext.rb
+- test/test_entry_filter.rb
+- test/test_excerpt.rb
- test/test_filters.rb
- test/test_generated_site.rb
- test/test_kramdown.rb
+- test/test_new_command.rb
- test/test_page.rb
- test/test_pager.rb
- test/test_post.rb
- test/test_rdiscount.rb
- test/test_redcarpet.rb
+- test/test_redcloth.rb
+- test/test_related_posts.rb
- test/test_site.rb
- test/test_tags.rb
-has_rdoc: true
+- test/test_url.rb
homepage: http://github.com/mojombo/jekyll
-licenses: []
-
+licenses:
+- MIT
+metadata: {}
post_install_message:
-rdoc_options:
+rdoc_options:
- --charset=UTF-8
-require_paths:
+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"
+required_ruby_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - '>='
+ - !ruby/object:Gem::Version
+ version: '0'
+required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - '>='
+ - !ruby/object:Gem::Version
+ version: '0'
requirements: []
-
rubyforge_project: jekyll
-rubygems_version: 1.6.2
+rubygems_version: 2.0.14
signing_key:
specification_version: 2
summary: A simple, blog aware, static site generator.
-test_files:
+test_files:
+- test/test_command.rb
- test/test_configuration.rb
+- test/test_convertible.rb
- test/test_core_ext.rb
+- test/test_entry_filter.rb
+- test/test_excerpt.rb
- test/test_filters.rb
- test/test_generated_site.rb
- test/test_kramdown.rb
+- test/test_new_command.rb
- test/test_page.rb
- test/test_pager.rb
- test/test_post.rb
- test/test_rdiscount.rb
- test/test_redcarpet.rb
+- test/test_redcloth.rb
+- test/test_related_posts.rb
- test/test_site.rb
- test/test_tags.rb
+- test/test_url.rb
diff --git a/script/bootstrap b/script/bootstrap
new file mode 100755
index 0000000..da4e3ef
--- /dev/null
+++ b/script/bootstrap
@@ -0,0 +1,2 @@
+#!/bin/sh
+bundle install
diff --git a/site/.gitignore b/site/.gitignore
new file mode 100644
index 0000000..79bd74f
--- /dev/null
+++ b/site/.gitignore
@@ -0,0 +1,4 @@
+_site/
+*.swp
+pkg/
+test/
diff --git a/site/CNAME b/site/CNAME
new file mode 100644
index 0000000..f501cde
--- /dev/null
+++ b/site/CNAME
@@ -0,0 +1 @@
+jekyllrb.com
diff --git a/site/README b/site/README
new file mode 100644
index 0000000..60b411c
--- /dev/null
+++ b/site/README
@@ -0,0 +1 @@
+Jekyll's awesome website.
diff --git a/site/_config.yml b/site/_config.yml
new file mode 100644
index 0000000..c71e4d3
--- /dev/null
+++ b/site/_config.yml
@@ -0,0 +1,6 @@
+pygments: true
+relative_permalinks: false
+gauges_id: 503c5af6613f5d0f19000027
+permalink: /news/:year/:month/:day/:title/
+excerpt_separator: noifniof3nioaniof3nioafafinoafnoif
+repository: https://github.com/mojombo/jekyll
diff --git a/site/_includes/analytics.html b/site/_includes/analytics.html
new file mode 100644
index 0000000..bbdc351
--- /dev/null
+++ b/site/_includes/analytics.html
@@ -0,0 +1,32 @@
+{% if site.gauges_id %}
+ <!-- Gauges (http://gaug.es/) -->
+ <script type="text/javascript">
+ var _gauges = _gauges || [];
+ (function() {
+ var t = document.createElement('script');
+ t.type = 'text/javascript';
+ t.async = true;
+ t.id = 'gauges-tracker';
+ t.setAttribute('data-site-id', '{{ site.gauges_id }}');
+ t.src = '//secure.gaug.es/track.js';
+ var s = document.getElementsByTagName('script')[0];
+ s.parentNode.insertBefore(t, s);
+ })();
+ </script>
+{% endif %}
+
+{% if site.google_analytics_id %}
+ <!-- Google Analytics (http://google.com/analytics) -->
+ <script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', '{{ site.google_analytics_id }}']);
+ _gaq.push(['_setDomainName', '{{ site.url }}']); // Multiple sub-domains
+ _gaq.push(['_setAllowLinker', true]); // Multiple TLDs
+ _gaq.push(['_trackPageview']);
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script>
+{% endif %}
diff --git a/site/_includes/docs_contents.html b/site/_includes/docs_contents.html
new file mode 100644
index 0000000..523b522
--- /dev/null
+++ b/site/_includes/docs_contents.html
@@ -0,0 +1,16 @@
+<div class="unit one-fifth hide-on-mobiles">
+ <aside>
+ <h4>Getting Started</h4>
+ {% include docs_ul.html items='home quickstart installation usage structure configuration' %}
+ <h4>Your Content</h4>
+ {% include docs_ul.html items='frontmatter posts drafts pages variables datafiles migrations' %}
+ <h4>Customization</h4>
+ {% include docs_ul.html items='templates permalinks pagination plugins extras' %}
+ <h4>Deployment</h4>
+ {% include docs_ul.html items='github-pages deployment-methods' %}
+ <h4>Miscellaneous</h4>
+ {% include docs_ul.html items='troubleshooting sites resources upgrading' %}
+ <h4>Meta</h4>
+ {% include docs_ul.html items='contributing history' %}
+ </aside>
+</div>
diff --git a/site/_includes/docs_contents_mobile.html b/site/_includes/docs_contents_mobile.html
new file mode 100644
index 0000000..bbc367d
--- /dev/null
+++ b/site/_includes/docs_contents_mobile.html
@@ -0,0 +1,23 @@
+<div class="docs-nav-mobile unit whole show-on-mobiles">
+ <select onchange="if (this.value) window.location.href=this.value">
+ <option value="">Navigate the docs…</option>
+ <optgroup label="Getting started">
+ {% include docs_option.html items='home quickstart installation usage structure configuration' %}
+ </optgroup>
+ <optgroup label="Your Content">
+ {% include docs_option.html items='frontmatter posts drafts pages variables datafiles migrations' %}
+ </optgroup>
+ <optgroup label="Customization">
+ {% include docs_option.html items='templates permalinks pagination plugins extras' %}
+ </optgroup>
+ <optgroup label="Deployment">
+ {% include docs_option.html items='github-pages deployment-methods' %}
+ </optgroup>
+ <optgroup label="Miscellaneous">
+ {% include docs_option.html items='troubleshooting sites resources upgrading' %}
+ </optgroup>
+ <optgroup label="Meta">
+ {% include docs_option.html items='contributing history' %}
+ </optgroup>
+ </select>
+</div>
diff --git a/site/_includes/docs_option.html b/site/_includes/docs_option.html
new file mode 100644
index 0000000..8284ed9
--- /dev/null
+++ b/site/_includes/docs_option.html
@@ -0,0 +1,11 @@
+{% assign items = include.items | split: ' ' %}
+
+{% for item in items %}
+ {% assign item_url = item | prepend:'/docs/' | append:'/' %}
+
+ {% for p in site.pages %}
+ {% if p.url == item_url %}
+ <option value="{{ site.url }}{{ p.url }}">{{ p.title }}</option>
+ {% endif %}
+ {% endfor %}
+{% endfor %}
diff --git a/site/_includes/docs_ul.html b/site/_includes/docs_ul.html
new file mode 100644
index 0000000..4ba8247
--- /dev/null
+++ b/site/_includes/docs_ul.html
@@ -0,0 +1,20 @@
+{% assign items = include.items | split: ' ' %}
+
+<ul>
+{% for item in items %}
+ {% assign item_url = item | prepend:'/docs/' | append:'/' %}
+
+ {% if item_url == page.url %}
+ {% assign c = 'current' %}
+ {% else %}
+ {% assign c = '' %}
+ {% endif %}
+
+ {% for p in site.pages %}
+ {% if p.url == item_url %}
+ <li class="{{ c }}"><a href="{{ site.url }}{{ p.url }}">{{ p.title }}</a></li>
+ {% endif %}
+ {% endfor %}
+
+{% endfor %}
+</ul>
diff --git a/site/_includes/footer.html b/site/_includes/footer.html
new file mode 100644
index 0000000..d73b10e
--- /dev/null
+++ b/site/_includes/footer.html
@@ -0,0 +1,15 @@
+<footer>
+ <div class="grid">
+ <div class="unit one-third center-on-mobiles">
+ <p>By <a href="http://tom.preston-werner.com">Tom Preston-Werner</a>, <a href="http://quaran.to/">Nick Quaranto</a>, and many more <a href="{{ site.repository }}/graphs/contributors">awesome contributors</a>.</p>
+ </div>
+ <div class="unit two-thirds align-right center-on-mobiles">
+ <p>
+ Proudly hosted by
+ <a href="https://github.com">
+ <img src="{{ site.url }}/img/footer-logo.png" alt="GitHub • Social coding">
+ </a>
+ </p>
+ </div>
+ </div>
+</footer>
diff --git a/site/_includes/header.html b/site/_includes/header.html
new file mode 100644
index 0000000..39de1bf
--- /dev/null
+++ b/site/_includes/header.html
@@ -0,0 +1,18 @@
+<header>
+ <nav class="mobile-nav show-on-mobiles">
+ {% include primary-nav-items.html %}
+ </nav>
+ <div class="grid">
+ <div class="unit one-third center-on-mobiles">
+ <h1>
+ <a href="{{ site.url }}/">
+ <span>Jekyll</span>
+ <img src="{{ site.url }}/img/logo-2x.png" width="249" height="115" alt="">
+ </a>
+ </h1>
+ </div>
+ <nav class="main-nav unit two-thirds hide-on-mobiles">
+ {% include primary-nav-items.html %}
+ </nav>
+ </div>
+</header>
diff --git a/site/_includes/news_contents.html b/site/_includes/news_contents.html
new file mode 100644
index 0000000..f22a1a1
--- /dev/null
+++ b/site/_includes/news_contents.html
@@ -0,0 +1,23 @@
+<div class="unit one-fifth hide-on-mobiles">
+ <aside>
+ <ul>
+ <li class="{% if page.title == 'News' %}current{% endif %}">
+ <a href="/news/">All News</a>
+ </li>
+ <li class="{% if page.title == 'Releases' %}current{% endif %}">
+ <a href="/news/releases/">Jekyll Releases</a>
+ </li>
+ </ul>
+ <h4>Recent Releases</h4>
+ <ul>
+ {% for post in site.posts limit:5 %}
+ <li class="{% if page.title == post.title %}current{% endif %}">
+ <a href="{{ post.url }}">Version {{ post.version }}</a>
+ </li>
+ {% endfor %}
+ <li>
+ <a href="/docs/history/">History »</a>
+ </li>
+ </ul>
+ </aside>
+</div>
diff --git a/site/_includes/news_contents_mobile.html b/site/_includes/news_contents_mobile.html
new file mode 100644
index 0000000..e8fb55e
--- /dev/null
+++ b/site/_includes/news_contents_mobile.html
@@ -0,0 +1,11 @@
+<div class="docs-nav-mobile unit whole show-on-mobiles">
+ <select onchange="if (this.value) window.location.href=this.value">
+ <option value="">Navigate the blog…</option>
+ <option value="/news/">Home</option>
+ <optgroup label="v1.x">
+ {% for post in site.posts %}
+ <option value="{{ post.url }}">{{ post.title }}</option>
+ {% endfor %}
+ </optgroup>
+ </select>
+</div>
diff --git a/site/_includes/news_item.html b/site/_includes/news_item.html
new file mode 100644
index 0000000..ec3d742
--- /dev/null
+++ b/site/_includes/news_item.html
@@ -0,0 +1,24 @@
+<article>
+ <h2>
+ <a href="{{ post.url }}">
+ {{ post.title }}
+ </a>
+ </h2>
+ <span class="post-category">
+ {% for category in post.categories %}
+ <span class="label">{{ category }}</span>
+ {% endfor %}
+ </span>
+ <div class="post-meta">
+ <span class="post-date">
+ {{ post.date | date_to_string }}
+ </span>
+ <a href="https://github.com/{{ post.author }}" class="post-author">
+ <img src="https://github.com/{{ post.author }}.png" class="avatar" alt="{{ post.author }}"/>
+ {{ post.author }}
+ </a>
+ </div>
+ <div class="post-content">
+ {{ post.content }}
+ </div>
+</article>
diff --git a/site/_includes/primary-nav-items.html b/site/_includes/primary-nav-items.html
new file mode 100644
index 0000000..54e6a59
--- /dev/null
+++ b/site/_includes/primary-nav-items.html
@@ -0,0 +1,14 @@
+<ul>
+ <li class="{% if page.overview %}current{% endif %}">
+ <a href="{{ site.url }}/">Overview</a>
+ </li>
+ <li class="{% if page.url contains '/docs/' %}current{% endif %}">
+ <a href="{{ site.url }}/docs/home/">Doc<span class="show-on-mobiles">s</span><span class="hide-on-mobiles">umentation</span></a>
+ </li>
+ <li class="{% if page.author %}current{% endif %}">
+ <a href="{{ site.url }}/news/">News</a>
+ </li>
+ <li class="">
+ <a href="{{ site.repository }}"><span class="hide-on-mobiles">View on </span>GitHub</a>
+ </li>
+</ul>
diff --git a/site/_includes/section_nav.html b/site/_includes/section_nav.html
new file mode 100644
index 0000000..beb65e7
--- /dev/null
+++ b/site/_includes/section_nav.html
@@ -0,0 +1,22 @@
+<div class="section-nav">
+ <div class="left align-right">
+ {% if page.prev_section != null %}
+ <a href="{{ site.url }}/docs/{{ page.prev_section }}/" class="prev">
+ Back
+ </a>
+ {% else %}
+ <span class="prev disabled">Back</span>
+ {% endif %}
+ </div>
+ <div class="right align-left">
+ {% if page.next_section != null %}
+ <a href="{{ site.url }}/docs/{{ page.next_section }}/" class="next">
+ Next
+ </a>
+ {% else %}
+ <span class="next disabled">Next</span>
+ {% endif %}
+ </div>
+ <div class="clear"></div>
+</div>
+
diff --git a/site/_includes/top.html b/site/_includes/top.html
new file mode 100644
index 0000000..e17496c
--- /dev/null
+++ b/site/_includes/top.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html lang="en-US">
+<head>
+ <meta charset="UTF-8">
+ <title>{{ page.title }}</title>
+ <meta name="viewport" content="width=device-width,initial-scale=1">
+ <link rel="alternate" type="application/rss+xml" title="Jekyll • Simple, blog-aware, static sites - Feed" href="/feed.xml" />
+ <link rel="alternate" type="application/atom+xml" title="Recent commits to Jekyll’s master branch" href="{{ site.repository }}/commits/master.atom" />
+ <link href='http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900,100italic,300italic,400italic,700italic,900italic' rel='stylesheet' type='text/css'>
+ <link href='http://fonts.googleapis.com/css?family=Arizonia' rel='stylesheet' type='text/css'>
+ <link rel="stylesheet" href="{{ site.url }}/css/normalize.css" />
+ <link rel="stylesheet" href="{{ site.url }}/css/gridism.css" />
+ <link rel="stylesheet" href="{{ site.url }}/css/style.css" />
+ <link rel="stylesheet" href="{{ site.url }}/css/pygments.css" />
+ <link rel="icon" type="image/png" href="{{ site.url }}/favicon.png" />
+ <script src="{{ site.url }}/js/modernizr-2.5.3.min.js"></script>
+</head>
diff --git a/site/_layouts/default.html b/site/_layouts/default.html
new file mode 100644
index 0000000..8919fca
--- /dev/null
+++ b/site/_layouts/default.html
@@ -0,0 +1,12 @@
+{% include top.html %}
+
+<body class="wrap">
+ {% include header.html %}
+
+ {{ content }}
+
+ {% include footer.html %}
+ {% include analytics.html %}
+
+</body>
+</html>
diff --git a/site/_layouts/docs.html b/site/_layouts/docs.html
new file mode 100644
index 0000000..a0a8a5c
--- /dev/null
+++ b/site/_layouts/docs.html
@@ -0,0 +1,23 @@
+---
+layout: default
+---
+
+ <section class="docs">
+ <div class="grid">
+
+ {% include docs_contents_mobile.html %}
+
+ <div class="unit four-fifths">
+ <article>
+ <h1>{{ page.title }}</h1>
+ {{ content }}
+ {% include section_nav.html %}
+ </article>
+ </div>
+
+ {% include docs_contents.html %}
+
+ <div class="clear"></div>
+
+ </div>
+ </section>
diff --git a/site/_layouts/news.html b/site/_layouts/news.html
new file mode 100644
index 0000000..8f7945f
--- /dev/null
+++ b/site/_layouts/news.html
@@ -0,0 +1,19 @@
+---
+layout: default
+---
+
+ <section class="news">
+ <div class="grid">
+
+ {% include news_contents_mobile.html %}
+
+ <div class="unit four-fifths">
+ {{ content }}
+ </div>
+
+ {% include news_contents.html %}
+
+ <div class="clear"></div>
+
+ </div>
+ </section>
diff --git a/site/_layouts/news_item.html b/site/_layouts/news_item.html
new file mode 100644
index 0000000..d395502
--- /dev/null
+++ b/site/_layouts/news_item.html
@@ -0,0 +1,27 @@
+---
+layout: news
+---
+
+<article>
+ <h2>
+ {{ page.title }}
+ <a href="{{ page.url }}" class="permalink" title="Permalink">∞</a>
+ </h2>
+ <span class="post-category">
+ {% for category in page.categories %}
+ <span class="label">{{ category }}</span>
+ {% endfor %}
+ </span>
+ <div class="post-meta">
+ <span class="post-date">
+ {{ page.date | date_to_string }}
+ </span>
+ <a href="https://github.com/{{ page.author }}" class="post-author">
+ <img src="https://github.com/{{ page.author }}.png" class="avatar" />
+ {{ page.author }}
+ </a>
+ </div>
+ <p class="post-content">
+ {{ content }}
+ </p>
+</article>
diff --git a/site/_posts/2013-05-06-jekyll-1-0-0-released.markdown b/site/_posts/2013-05-06-jekyll-1-0-0-released.markdown
new file mode 100644
index 0000000..34010e0
--- /dev/null
+++ b/site/_posts/2013-05-06-jekyll-1-0-0-released.markdown
@@ -0,0 +1,23 @@
+---
+layout: news_item
+title: "Jekyll 1.0.0 Released"
+date: "2013-05-06 02:12:52 +0200"
+author: parkr
+version: 1.0.0
+categories: [release]
+---
+
+Hey! After many months of hard work by Jekyll's contributors, we're excited
+to announce the first major release of the project in a long while. v1.0.0 is
+finally here! While the list of improvements and bug fixes is [quite lengthy][history],
+here are the highlights (thanks to [@benbalter](http://twitter.com/BenBalter) for the
+examples and for compiling this list):
+
+- Support for the Gist tag for easily embedding Gists ([example](https://gist.github.com/benbalter/5555251))
+- Automatically generated post excerpts ([example](https://gist.github.com/benbalter/5555369))
+- Save and preview drafts before publishing ([example](https://gist.github.com/benbalter/5555992))
+
+Take a look at the [Upgrading][] page in the docs for more detailed information.
+
+[history]: /docs/history/#100__20130506
+[Upgrading]: /docs/upgrading/
diff --git a/site/_posts/2013-05-08-jekyll-1-0-1-released.markdown b/site/_posts/2013-05-08-jekyll-1-0-1-released.markdown
new file mode 100644
index 0000000..0a505ac
--- /dev/null
+++ b/site/_posts/2013-05-08-jekyll-1-0-1-released.markdown
@@ -0,0 +1,27 @@
+---
+layout: news_item
+title: "Jekyll 1.0.1 Released"
+date: "2013-05-08 23:46:11 +0200"
+author: parkr
+version: 1.0.1
+categories: [release]
+---
+
+Hot on the trails of v1.0, v1.0.1 is out! Here are the highlights:
+
+* Add newer `language-` class name prefix to code blocks ([#1037][])
+* Commander error message now preferred over process abort with incorrect args ([#1040][])
+* Do not force use of toc_token when using generate_toc in RDiscount ([#1048][])
+* Make Redcarpet respect the pygments configuration option ([#1053][])
+* Fix the index build with LSI ([#1045][])
+* Don't print deprecation warning when no arguments are specified. ([#1041][])
+* Add missing `</div>` to site template used by `new` subcommand, fixed typos in code ([#1032][])
+
+See the [History][] page for more information on this release.
+
+{% assign issue_numbers = "1037|1040|1048|1053|1045|1041|1032" | split: "|" %}
+{% for issue in issue_numbers %}
+[#{{ issue }}]: {{ site.repository }}/issues/{{ issue }}
+{% endfor %}
+
+[History]: /docs/history/#101__20130508
diff --git a/site/_posts/2013-05-12-jekyll-1-0-2-released.markdown b/site/_posts/2013-05-12-jekyll-1-0-2-released.markdown
new file mode 100644
index 0000000..8993a6b
--- /dev/null
+++ b/site/_posts/2013-05-12-jekyll-1-0-2-released.markdown
@@ -0,0 +1,28 @@
+---
+layout: news_item
+title: "Jekyll 1.0.2 Released"
+date: "2013-05-12 14:45:00 +0200"
+author: parkr
+version: 1.0.2
+categories: [release]
+---
+
+v1.0.2 has some key bugfixes that optionally restore some behaviour from pre-1.0
+releases, and fix some other annoying bugs:
+
+* Backwards-compatibilize relative permalinks ([#1081][])
+* Add `jekyll doctor` command to check site for any known compatibility problems ([#1081][])
+* Deprecate old config `server_port`, match to `port` if `port` isn't set ([#1084][])
+* Update pygments.rb and kramdon versions to 0.5.0 and 1.0.2, respectively ([#1061][], [#1067][])
+* Fix issue when post categories are numbers ([#1078][])
+* Add a `data-lang="<lang>"` attribute to Redcarpet code blocks ([#1066][])
+* Catching that Redcarpet gem isn't installed ([#1059][])
+
+See the [History][] page for more information on this release.
+
+{% assign issue_numbers = "1059|1061|1066|1067|1078|1081|1084" | split: "|" %}
+{% for issue in issue_numbers %}
+[#{{ issue }}]: {{ site.repository }}/issues/{{ issue }}
+{% endfor %}
+
+[History]: /docs/history/#102__20130512
diff --git a/site/_posts/2013-06-07-jekyll-1-0-3-released.markdown b/site/_posts/2013-06-07-jekyll-1-0-3-released.markdown
new file mode 100644
index 0000000..0a04da1
--- /dev/null
+++ b/site/_posts/2013-06-07-jekyll-1-0-3-released.markdown
@@ -0,0 +1,25 @@
+---
+layout: news_item
+title: "Jekyll 1.0.3 Released"
+date: "2013-06-07 21:02:13 +0200"
+author: parkr
+version: 1.0.3
+categories: [release]
+---
+
+v1.0.3 contains some key enhancements and bug fixes:
+
+- Fail with non-zero exit code when MaRuKu errors ([#1190][]) or Liquid errors ([#1121][])
+- Add support for private gists to `gist` tag ([#1189][])
+- Add `--force` option to `jekyll new` ([#1115][])
+- Fix compatibility with `exclude` and `include` with pre-1.0 Jekyll ([#1114][])
+- Fix pagination issue regarding `File.basename` and `page:num` ([#1063][])
+
+See the [History][] page for more information on this release.
+
+{% assign issue_numbers = "1190|1121|1189|1115|1114|1063" | split: "|" %}
+{% for issue in issue_numbers %}
+[#{{ issue }}]: {{ site.repository }}/issues/{{ issue }}
+{% endfor %}
+
+[History]: /docs/history/#103__20130607
diff --git a/site/_posts/2013-07-14-jekyll-1-1-0-released.markdown b/site/_posts/2013-07-14-jekyll-1-1-0-released.markdown
new file mode 100644
index 0000000..12b3d92
--- /dev/null
+++ b/site/_posts/2013-07-14-jekyll-1-1-0-released.markdown
@@ -0,0 +1,27 @@
+---
+layout: news_item
+title: "Jekyll 1.1.0 Released"
+date: "2013-07-14 19:38:02 +0200"
+author: parkr
+version: 1.1.0
+categories: [release]
+---
+
+After a month of hard work, the Jekyll core team is excited to announce the release of
+Jekyll v1.1.0! This latest release of Jekyll brings some really exciting new additions:
+
+- Add `docs` subcommand to read Jekyll's docs when offline. ([#1046][])
+- Support passing parameters to templates in `include` tag ([#1204][])
+- Add support for Liquid tags to post excerpts ([#1302][])
+- Fix pagination for subdirectories ([#1198][])
+- Provide better error reporting when generating sites ([#1253][])
+- Latest posts first in non-LSI `related_posts` ([#1271][])
+
+See the [GitHub Release][] page for more a more detailed changelog for this release.
+
+{% assign issue_numbers = "1046|1204|1302|1198|1171|1118|1098|1215|1253|1271" | split: "|" %}
+{% for issue in issue_numbers %}
+[#{{ issue }}]: {{ site.repository }}/issues/{{ issue }}
+{% endfor %}
+
+[GitHub Release]: {{ site.repository }}/releases/tag/v1.1.0
diff --git a/site/_posts/2013-07-24-jekyll-1-1-1-released.markdown b/site/_posts/2013-07-24-jekyll-1-1-1-released.markdown
new file mode 100644
index 0000000..23f8351
--- /dev/null
+++ b/site/_posts/2013-07-24-jekyll-1-1-1-released.markdown
@@ -0,0 +1,31 @@
+---
+layout: news_item
+title: "Jekyll 1.1.1 Released"
+date: "2013-07-24 22:24:14 +0200"
+author: parkr
+version: 1.1.1
+categories: [release]
+---
+
+
+Coming just 10 days after the release of v1.1.0, v1.1.1 is out with a patch for the nasty
+excerpt inception bug ([#1339][]) and non-zero exit codes for invalid commands
+([#1338][]).
+
+To all those affected by the [strange excerpt bug in v1.1.0][#1321], I'm sorry. I think we
+have it all patched up and it should be deployed to [GitHub Pages][gh_pages] in the next
+couple weeks. Thank you for your patience!
+
+If you're checking out v1.1.x for the first time, definitely check out [what shipped with
+v1.1.0!][v1_1_0]
+
+See the [GitHub Release][] page for more a more detailed changelog for this release.
+
+{% assign issue_numbers = "1339|1338|1321" | split: "|" %}
+{% for issue in issue_numbers %}
+[{{ issue }}]: {{ site.repository }}/issues/{{ issue }}
+{% endfor %}
+
+[GitHub Release]: {{ site.repository }}/releases/tag/v1.1.1
+[gh_pages]: http://pages.github.com
+[v1_1_0]: {{ site.repository }}/releases/tag/v1.1.0
diff --git a/site/_posts/2013-07-25-jekyll-1-0-4-released.markdown b/site/_posts/2013-07-25-jekyll-1-0-4-released.markdown
new file mode 100644
index 0000000..faf81dd
--- /dev/null
+++ b/site/_posts/2013-07-25-jekyll-1-0-4-released.markdown
@@ -0,0 +1,20 @@
+---
+layout: news_item
+title: "Jekyll 1.0.4 Released"
+date: "2013-07-25 09:08:38 +0200"
+author: mattr-
+version: 1.0.4
+categories: [release]
+---
+
+Version 1.0.4 fixes a minor, but nonetheless important security vulnerability affecting several third-party Jekyll plugins. If your Jekyll site does not use plugins, you may, but are not required to upgrade at this time.
+
+Community and custom plugins extending the `Liquid::Drop` class may inadvertently disclose some system information such as directory structure or software configuration to users with access to the Liquid templating system.
+
+We recommend you upgrade to Jekyll v1.0.4 immediately if you use `Liquid::Drop` plugins on your Jekyll site.
+
+Many thanks for [Ben Balter](http://github.com/benbalter) for alerting us to the problem
+and [submitting a patch][1349] so quickly.
+
+[230]: https://github.com/Shopify/liquid/pull/230
+[1349]: {{ site.repository }}/issues/1349
diff --git a/site/_posts/2013-07-25-jekyll-1-1-2-released.markdown b/site/_posts/2013-07-25-jekyll-1-1-2-released.markdown
new file mode 100644
index 0000000..54a8c87
--- /dev/null
+++ b/site/_posts/2013-07-25-jekyll-1-1-2-released.markdown
@@ -0,0 +1,20 @@
+---
+layout: news_item
+title: "Jekyll 1.1.2 Released"
+date: "2013-07-25 09:08:38 +0200"
+author: parkr
+version: 1.1.2
+categories: [release]
+---
+
+Version 1.1.2 fixes a minor, but nonetheless important security vulnerability affecting several third-party Jekyll plugins. If your Jekyll site does not use plugins, you may, but are not required to upgrade at this time.
+
+Community and custom plugins extending the `Liquid::Drop` class may inadvertently disclose some system information such as directory structure or software configuration to users with access to the Liquid templating system.
+
+We recommend you upgrade to Jekyll v1.1.2 immediately if you use `Liquid::Drop` plugins on your Jekyll site.
+
+Many thanks for [Ben Balter](http://github.com/benbalter) for alerting us to the problem
+and [submitting a patch][1349] so quickly.
+
+[230]: https://github.com/Shopify/liquid/pull/230
+[1349]: {{ site.repository }}/issues/1349
diff --git a/site/_posts/2013-09-06-jekyll-1-2-0-released.markdown b/site/_posts/2013-09-06-jekyll-1-2-0-released.markdown
new file mode 100644
index 0000000..ae5448c
--- /dev/null
+++ b/site/_posts/2013-09-06-jekyll-1-2-0-released.markdown
@@ -0,0 +1,23 @@
+---
+layout: news_item
+title: "Jekyll 1.2.0 Released"
+date: "2013-09-06 22:02:41 -0400"
+author: parkr
+version: 1.2.0
+categories: [release]
+---
+
+After nearly a month and a half of hard work, the Jekyll team is happy to
+announce the release of v1.2.0. It's chock full of bug fixes and some
+enhancements that we think you'll love.
+
+Here are a few things we think you'll want to know about this release:
+
+* Run `jekyll serve --detach` to boot up a WEBrick server in the background. **Note:** you'll need to run `kill [server_pid]` to shut the server down.
+* You can now **disable automatically-generated excerpts** if you set `excerpt_separator` to `""`.
+* If you're moving around pages and post, you can now check for **URL conflicts** by running `jekyll doctor`.
+* If you're a fan of the drafts feature, you'll be happy to know we've added `-D`, a shortened version of `--drafts`.
+* Permalinks with special characters should now generate without errors.
+* Expose the current Jekyll version as the `jekyll.version` Liquid variable.
+
+For a full run-down, visit our [change log](/docs/history/)!
diff --git a/site/_posts/2013-09-14-jekyll-1-2-1-released.markdown b/site/_posts/2013-09-14-jekyll-1-2-1-released.markdown
new file mode 100644
index 0000000..26a6ca1
--- /dev/null
+++ b/site/_posts/2013-09-14-jekyll-1-2-1-released.markdown
@@ -0,0 +1,19 @@
+---
+layout: news_item
+title: 'Jekyll 1.2.1 Released'
+date: 2013-09-14 20:46:50 -0400
+author: parkr
+version: 1.2.1
+categories: [release]
+---
+
+Quick turnover, anyone? A [recent incompatibility with Liquid
+v2.5.2](https://github.com/mojombo/jekyll/pull/1525) produced a nasty bug in
+which `include` tags were not rendered properly within `if` blocks.
+
+This release also includes a better handling of detached servers (prints pid and
+the command for killing the process). **Note**: the `--detach` flag and
+`--watch` flags are presently incompatible in 1.2.x. Fix for that coming soon!
+
+For a full list of the fixes in this release, check out [the change
+log](/docs/history/)!
diff --git a/site/_posts/2013-10-28-jekyll-1-3-0-rc1-released.markdown b/site/_posts/2013-10-28-jekyll-1-3-0-rc1-released.markdown
new file mode 100644
index 0000000..f4f4852
--- /dev/null
+++ b/site/_posts/2013-10-28-jekyll-1-3-0-rc1-released.markdown
@@ -0,0 +1,19 @@
+---
+layout: news_item
+title: 'Jekyll 1.3.0.rc1 Released'
+date: 2013-10-28 20:14:39 -0500
+author: mattr-
+version: 1.3.0.rc1
+categories: [release]
+---
+
+Jekyll 1.3.0 is going to be a big release! In order to make sure we
+didn't screw anything up too badly, we're making a release candidate
+available for any early adopters who want to give the latest and
+greatest code a spin without having to clone a repository from git.
+
+Please take this prerelease for a spin and [let us
+know](https://github.com/mojombo/jekyll/issues/new) if you run into any
+issues!
+
+
diff --git a/site/_posts/2013-11-04-jekyll-1-3-0-released.markdown b/site/_posts/2013-11-04-jekyll-1-3-0-released.markdown
new file mode 100644
index 0000000..1e32511
--- /dev/null
+++ b/site/_posts/2013-11-04-jekyll-1-3-0-released.markdown
@@ -0,0 +1,43 @@
+---
+layout: news_item
+title: 'Jekyll 1.3.0 Released'
+date: 2013-11-04 21:46:02 -0600
+author: mattr-
+version: 1.3.0
+categories: [release]
+---
+
+It's been about six weeks since v1.2.0 and the Jekyll team is happy to
+announce the arrival of v1.3.0. This is a **huge** release full of all
+sorts of new features, bug fixes, and other things that you're sure to
+love.
+
+Here are a few things we think you'll want to know about this release:
+
+* You can add [arbitrary data][] to the site by adding YAML files under a
+ site's `_data` directory. This will allow you to avoid
+ repetition in your templates and to set site specific options without
+ changing `_config.yml`.
+
+* You can now run `jekyll serve --detach` to boot up a WEBrick server in the
+ background. **Note:** you'll need to run `kill [server_pid]` to shut
+ the server down. When ran, you'll get a process id that you can use in
+ place of `[server_pid]`
+
+* You can now **disable automatically-generated excerpts** if you set
+ `excerpt_separator` to `""`.
+
+* If you're moving pages and posts, you can now check for **URL
+ conflicts** by running `jekyll doctor`.
+
+* If you're a fan of the drafts feature, you'll be happy to know we've
+ added `-D`, a shortened version of `--drafts`.
+
+* Permalinks with special characters should now generate without errors.
+
+* Expose the current Jekyll version as the `jekyll.version` Liquid
+ variable.
+
+For a full run-down, visit our [change log](/docs/history/)!
+
+[arbitrary data]: /docs/datafiles/
diff --git a/site/_posts/2013-11-26-jekyll-1-3-1-released.markdown b/site/_posts/2013-11-26-jekyll-1-3-1-released.markdown
new file mode 100644
index 0000000..4b4c37d
--- /dev/null
+++ b/site/_posts/2013-11-26-jekyll-1-3-1-released.markdown
@@ -0,0 +1,21 @@
+---
+layout: news_item
+title: 'Jekyll 1.3.1 Released'
+date: 2013-11-26 19:52:20 -0600
+author: mattr-
+version: 1.3.1
+categories: [release]
+---
+
+Just in time for the US holiday Thanksgiving, we're releasing version
+1.3.1 of Jekyll to address some of the issues seen since the
+release of 1.3.0.
+
+In addition to a couple of other smaller bug fixes, the biggest thing
+we've fixed is an issue with the `--watch` option with Ruby 1.8.7. For a
+full run-down, visit our [change log](/docs/history/)!
+
+Thanks to all the people who have contributed to this release! They are
+(in alphabetical order): Abhi Yerra, Anatol Broder, Andreas Möller, Greg
+Karékinian, Sam Rayner, Santeri Paavolainen, Shigeya Suzuki, Yihang Ho,
+albertogg, andrewhavens, maul.esel, and thomasdao
diff --git a/site/_posts/2013-12-07-jekyll-1-4-0-released.markdown b/site/_posts/2013-12-07-jekyll-1-4-0-released.markdown
new file mode 100644
index 0000000..d7a0c14
--- /dev/null
+++ b/site/_posts/2013-12-07-jekyll-1-4-0-released.markdown
@@ -0,0 +1,30 @@
+---
+layout: news_item
+title: 'Jekyll 1.4.0 Released'
+date: 2013-12-07 13:55:28 -0600
+author: mattr-
+version: 1.4.0
+categories: [release]
+---
+
+About a month after the release of Jekyll v1.3.0, we are releasing
+Jekyll v1.4.0. This release will be the last non-patch release to support Ruby
+1.8.7 and our next release will be Jekyll 2.0.0.
+
+Here are a few things we think you'll want to know about this release:
+
+* TOML is now a supported markup language for config files.
+
+* Maruku has been updated to 0.7.0 which provides some new features and
+ a ton of bugfixes over the previous 0.6.x releases.
+
+* Non-`gem` Plugins are now sorted alphabetically by filename before they're
+ processed, which can provide a rudimentary way to establish a load order for
+ plugins.
+
+For a full run-down, visit our [change log](/docs/history/)!
+
+As always, Jekyll wouldn't be possible without the contributions from
+others in the Jekyll community. We'd like to thank the following people
+for contributing to this release: Anatol Broder, David Sawyer, Greg
+Karékinian, Jordon Bedwell, Matthew Iversen, Persa Zula, and Yi Zeng.
diff --git a/site/_posts/2013-12-16-jekyll-1-4-2-released.markdown b/site/_posts/2013-12-16-jekyll-1-4-2-released.markdown
new file mode 100644
index 0000000..6bc6471
--- /dev/null
+++ b/site/_posts/2013-12-16-jekyll-1-4-2-released.markdown
@@ -0,0 +1,16 @@
+---
+layout: news_item
+title: 'Jekyll 1.4.2 Released'
+date: 2013-12-16 19:48:13 -0500
+author: parkr
+version: 1.4.2
+categories: [release]
+---
+
+This release fixes [a regression][] where Maruku fenced code blocks were turned
+off, instead of the previous default to on. We've added a new default
+configuration to our `maruku` config key: `fenced_code_blocks` and set it to
+default to `true`.
+
+If you do not wish to use Maruku fenced code blocks, you may turn this option
+off in your site's configuration file.
diff --git a/site/css/gridism.css b/site/css/gridism.css
new file mode 100644
index 0000000..cc7a43c
--- /dev/null
+++ b/site/css/gridism.css
@@ -0,0 +1,110 @@
+/*
+ * Gridism
+ * A simple, responsive, and handy CSS grid by @cobyism
+ * https://github.com/cobyism/gridism
+ */
+
+/* Preserve some sanity */
+.grid,
+.unit {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+/* Set up some rules to govern the grid */
+.grid {
+ display: block;
+ clear: both;
+}
+.grid .unit {
+ float: left;
+ width: 100%;
+ padding: 10px;
+}
+
+/* This ensures the outer gutters are equal to the (doubled) inner gutters. */
+.grid .unit:first-child { padding-left: 20px; }
+.grid .unit:last-child { padding-right: 20px; }
+
+/* Nested grids already have padding though, so let’s nuke it */
+.unit .unit:first-child { padding-left: 0; }
+.unit .unit:last-child { padding-right: 0; }
+.unit .grid:first-child > .unit { padding-top: 0; }
+.unit .grid:last-child > .unit { padding-bottom: 0; }
+
+/* Let people nuke the gutters/padding completely in a couple of ways */
+.no-gutters .unit,
+.unit.no-gutters {
+ padding: 0 !important;
+}
+
+/* Wrapping at a maximum width is optional */
+.wrap .grid,
+.grid.wrap {
+ max-width: 978px;
+ margin: 0 auto;
+}
+
+/* Width classes also have shorthand versions numbered as fractions
+ * For example: for a grid unit 1/3 (one third) of the parent width,
+ * simply apply class="w-1-3" to the element. */
+.grid .whole, .grid .w-1-1 { width: 100%; }
+.grid .half, .grid .w-1-2 { width: 50%; }
+.grid .one-third, .grid .w-1-3 { width: 33.3332%; }
+.grid .two-thirds, .grid .w-2-3 { width: 66.6665%; }
+.grid .one-quarter, .grid .w-1-4 { width: 25%; }
+.grid .three-quarters, .grid .w-3-4 { width: 75%; }
+.grid .one-fifth, .grid .w-1-5 { width: 20%; }
+.grid .two-fifths, .grid .w-2-5 { width: 40%; }
+.grid .three-fifths, .grid .w-3-5 { width: 60%; }
+.grid .four-fifths, .grid .w-4-5 { width: 80%; }
+.grid .golden-small, .grid .w-g-s { width: 38.2716%; } /* Golden section: smaller piece */
+.grid .golden-large, .grid .w-g-l { width: 61.7283%; } /* Golden section: larger piece */
+
+/* Utility classes */
+.align-center { text-align: center; }
+.align-left { text-align: left; }
+.align-right { text-align: right; }
+.pull-left { float: left; }
+.pull-right { float: right; }
+
+.show-on-mobiles {
+ display: none;
+}
+
+/* Responsive Stuff */
+ at media screen and (max-width: 568px) {
+ /* Stack anything that isn’t full-width on smaller screens */
+ .grid .unit {
+ width: 100% !important;
+ padding-left: 20px;
+ padding-right: 20px;
+ }
+ .unit .grid .unit {
+ padding-left: 0px;
+ padding-right: 0px;
+ }
+
+ /* Sometimes, you just want to be different on small screens */
+ .center-on-mobiles {
+ text-align: center !important;
+ }
+ .hide-on-mobiles {
+ display: none !important;
+ }
+ .show-on-mobiles {
+ display: block !important;
+ }
+ a .show-on-mobiles {
+ display: inline !important;
+ }
+}
+
+/* Expand the wrap a bit further on larger screens */
+/*@media screen and (min-width: 1180px) {
+ .wrap .grid {
+ max-width: 1180px;
+ margin: 0 auto;
+ }
+}*/
diff --git a/site/css/normalize.css b/site/css/normalize.css
new file mode 100644
index 0000000..f0629e6
--- /dev/null
+++ b/site/css/normalize.css
@@ -0,0 +1 @@
+/* normalize.css v2.1.2 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:0.67em 0}abbr[title]{border-bottom:1px dotted}b,st [...]
diff --git a/site/css/pygments.css b/site/css/pygments.css
new file mode 100644
index 0000000..408a44f
--- /dev/null
+++ b/site/css/pygments.css
@@ -0,0 +1,70 @@
+/*.highlight { background: #333333; color: #ffffff}*/
+.highlight .hll { background-color: #ffffcc }
+.highlight .c { color: #87ceeb} /* Comment */
+.highlight .err { color: #ffffff} /* Error */
+.highlight .g { color: #ffffff} /* Generic */
+.highlight .k { color: #f0e68c} /* Keyword */
+.highlight .l { color: #ffffff} /* Literal */
+.highlight .n { color: #ffffff} /* Name */
+.highlight .o { color: #ffffff} /* Operator */
+.highlight .x { color: #ffffff} /* Other */
+.highlight .p { color: #ffffff} /* Punctuation */
+.highlight .cm { color: #87ceeb} /* Comment.Multiline */
+.highlight .cp { color: #cd5c5c} /* Comment.Preproc */
+.highlight .c1 { color: #87ceeb} /* Comment.Single */
+.highlight .cs { color: #87ceeb} /* Comment.Special */
+.highlight .gd { color: #0000c0; font-weight: bold; background-color: #008080 } /* Generic.Deleted */
+.highlight .ge { color: #c000c0; text-decoration: underline} /* Generic.Emph */
+.highlight .gr { color: #c0c0c0; font-weight: bold; background-color: #c00000 } /* Generic.Error */
+.highlight .gh { color: #cd5c5c} /* Generic.Heading */
+.highlight .gi { color: #ffffff; background-color: #0000c0 } /* Generic.Inserted */
+.highlight span.go { color: #add8e6; font-weight: bold; background-color: #4d4d4d } /* Generic.Output, qualified with span to prevent applying this style to the Go language, see #1153. */
+.highlight .gp { color: #ffffff} /* Generic.Prompt */
+.highlight .gs { color: #ffffff} /* Generic.Strong */
+.highlight .gu { color: #cd5c5c} /* Generic.Subheading */
+.highlight .gt { color: #c0c0c0; font-weight: bold; background-color: #c00000 } /* Generic.Traceback */
+.highlight .kc { color: #f0e68c} /* Keyword.Constant */
+.highlight .kd { color: #f0e68c} /* Keyword.Declaration */
+.highlight .kn { color: #f0e68c} /* Keyword.Namespace */
+.highlight .kp { color: #f0e68c} /* Keyword.Pseudo */
+.highlight .kr { color: #f0e68c} /* Keyword.Reserved */
+.highlight .kt { color: #bdb76b} /* Keyword.Type */
+.highlight .ld { color: #ffffff} /* Literal.Date */
+.highlight .m { color: #ffffff} /* Literal.Number */
+.highlight .s { color: #ffffff} /* Literal.String */
+.highlight .na { color: #ffffff} /* Name.Attribute */
+.highlight .nb { color: #ffffff} /* Name.Builtin */
+.highlight .nc { color: #ffffff} /* Name.Class */
+.highlight .no { color: #ffa0a0} /* Name.Constant */
+.highlight .nd { color: #ffffff} /* Name.Decorator */
+.highlight .ni { color: #ffdead} /* Name.Entity */
+.highlight .ne { color: #ffffff} /* Name.Exception */
+.highlight .nf { color: #ffffff} /* Name.Function */
+.highlight .nl { color: #ffffff} /* Name.Label */
+.highlight .nn { color: #ffffff} /* Name.Namespace */
+.highlight .nx { color: #ffffff} /* Name.Other */
+.highlight .py { color: #ffffff} /* Name.Property */
+.highlight .nt { color: #f0e68c} /* Name.Tag */
+.highlight .nv { color: #98fb98} /* Name.Variable */
+.highlight .ow { color: #ffffff} /* Operator.Word */
+.highlight .w { color: #ffffff} /* Text.Whitespace */
+.highlight .mf { color: #ffffff} /* Literal.Number.Float */
+.highlight .mh { color: #ffffff} /* Literal.Number.Hex */
+.highlight .mi { color: #ffffff} /* Literal.Number.Integer */
+.highlight .mo { color: #ffffff} /* Literal.Number.Oct */
+.highlight .sb { color: #ffffff} /* Literal.String.Backtick */
+.highlight .sc { color: #ffffff} /* Literal.String.Char */
+.highlight .sd { color: #ffffff} /* Literal.String.Doc */
+.highlight .s2 { color: #ffffff} /* Literal.String.Double */
+.highlight .se { color: #ffffff} /* Literal.String.Escape */
+.highlight .sh { color: #ffffff} /* Literal.String.Heredoc */
+.highlight .si { color: #ffffff} /* Literal.String.Interpol */
+.highlight .sx { color: #ffffff} /* Literal.String.Other */
+.highlight .sr { color: #ffffff} /* Literal.String.Regex */
+.highlight .s1 { color: #ffffff} /* Literal.String.Single */
+.highlight .ss { color: #ffffff} /* Literal.String.Symbol */
+.highlight .bp { color: #ffffff} /* Name.Builtin.Pseudo */
+.highlight .vc { color: #98fb98} /* Name.Variable.Class */
+.highlight .vg { color: #98fb98} /* Name.Variable.Global */
+.highlight .vi { color: #98fb98} /* Name.Variable.Instance */
+.highlight .il { color: #ffffff} /* Literal.Number.Integer.Long */
diff --git a/site/css/style.css b/site/css/style.css
new file mode 100644
index 0000000..049ee11
--- /dev/null
+++ b/site/css/style.css
@@ -0,0 +1,946 @@
+/* Base */
+
+* {
+ box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+}
+
+body {
+ font-family: Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ font-size: 21px;
+ font-weight: 300;
+ color: #ddd;
+ background: #333;
+ border-top: 5px solid #fc0;
+ box-shadow: inset 0 3px 30px rgba(0,0,0,.3);
+ text-shadow: 0 1px 3px rgba(0,0,0,.5);
+}
+
+.clear {
+ display: block;
+}
+
+.clear:after {
+ content: " ";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+
+/* Sections */
+
+body > header, body > section, body > footer {
+ float: left;
+ width: 100%;
+ clear: both;
+}
+
+/* Header */
+
+body > header h1, body > header nav {
+ display: inline-block;
+}
+
+body > header h1 span {
+ display: none;
+}
+
+nav ul {
+ padding: 0;
+ margin: 0;
+}
+
+nav li {
+ display: inline-block;
+}
+
+.main-nav {
+ margin-top: 52px;
+}
+
+.main-nav li {
+ margin-right: 10px;
+}
+
+.main-nav li a {
+ border-radius: 5px;
+ font-weight: 800;
+ font-size: 14px;
+ padding: 0.5em 1em;
+ text-shadow: none;
+ text-transform: uppercase;
+ transition: all .25s;
+ -moz-transition: all .25s;
+ -webkit-transition: all .25s;
+}
+
+.main-nav li a:hover {
+ background: #252525;
+ box-shadow: inset 0 1px 3px rgba(0,0,0,.5), 0 1px 0 rgba(255,255,255,.1);
+ text-shadow: 0 1px 3px rgba(0,0,0,.5);
+}
+
+.main-nav li.current a {
+ background: #fc0;
+ color: #222;
+ box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 1px 5px rgba(0,0,0,.5);
+ text-shadow: 0 1px 0 rgba(255,255,255,.3);
+}
+
+.mobile-nav ul {
+ overflow: hidden;
+ width: 100%;
+ display: table;
+}
+
+.mobile-nav a {
+ float: left;
+ width: 100%;
+ background: #333;
+ color: #fc0;
+ text-align: center;
+ text-transform: uppercase;
+ font-size: 14px;
+ font-weight: 800;
+ padding: 5px;
+ border-radius: 5px;
+}
+
+.mobile-nav .current a {
+ background: #fc0;
+ color: #222;
+ box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 1px 5px rgba(0,0,0,.5);
+ text-shadow: 0 1px 0 rgba(255,255,255,.3);
+}
+
+.mobile-nav li {
+ display: table-cell;
+ width: 25%;
+ padding: 8px;
+}
+
+ at media (max-width: 768px){
+ .main-nav ul {
+ text-align: right;
+ }
+}
+ at media (max-width: 830px){
+ .main-nav .show-on-mobiles {
+ display: inline;
+ }
+ .main-nav .hide-on-mobiles {
+ display: none;
+ }
+}
+
+/* Footer */
+
+body > footer {
+ background: #222;
+ font-size: 16px;
+ padding-bottom: 5px;
+ color: #888;
+ margin-top: 40px;
+}
+
+body > footer a {
+ color: #fff;
+}
+
+body > footer .align-right p, body > footer img {
+ display: inline-block;
+}
+
+body > footer img {
+ position: relative;
+ top: 8px;
+ margin-left: 5px;
+ width: 100px;
+ height: 30px;
+ opacity: .8;
+ padding: 1px;
+ -webkit-transition: opacity .2s;
+ -moz-transition: opacity .2s;
+ transition: opacity .2s;
+}
+
+body > footer a:hover img {
+ opacity: 1;
+}
+
+ at media (max-width: 568px){
+ footer .one-third p {
+ margin-bottom: 0;
+ }
+ footer .two-thirds p {
+ margin-top: -20px;
+ }
+}
+
+/* Intro */
+
+.intro .unit {
+ padding: 10px 0 40px;
+}
+
+.intro p {
+ font-size: 1.75em;
+ line-height: 1em;
+ margin: 0;
+}
+
+ at media (min-width: 569px){
+ .intro p {
+ font-size: 3.2em;
+ }
+}
+
+/* Quickstart */
+
+.quickstart {
+ background: #3F1F1F;
+ color: #fff;
+ margin: 60px 0;
+ box-shadow: inset 0 3px 10px rgba(0,0,0,.4);
+}
+
+.quickstart .content {
+ padding: 0px 0;
+}
+
+.quickstart h4 {
+ font-size: 24px;
+ line-height: 24px;
+ margin-top: 20px;
+ text-shadow: 0 1px 3px rgba(0,0,0,.8);
+}
+
+.quickstart .code {
+ font-size: 12px;
+ display: block;
+ margin: 0 0 -30px;
+}
+
+ at media (min-width: 768px){
+ .quickstart .code {
+ font-size: 18px;
+ margin: -30px 0;
+ float: right;
+ }
+ .quickstart h4 {
+ margin: 50px 0 0;
+ text-align: center;
+ }
+}
+
+/* Code */
+
+.quickstart .code {
+ display: block;
+ padding: 0;
+ font-family: Menlo, Consolas, "Courier New", Courier, "Liberation Mono", monospace;
+ line-height: 1.3em;
+}
+
+.quickstart .code .title {
+ display: block;
+ text-align: center;
+ margin: 0 20px;
+ padding: 5px 0;
+ border-radius: 5px 5px 0 0;
+ box-shadow: 0 3px 10px rgba(0,0,0,.5);
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ font-weight: normal;
+ color: #444;
+ text-shadow: 0 1px 0 rgba(255,255,255,.5);
+ background: #f7f7f7;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y3ZjdmNyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjclIiBzdG9wLWNv [...]
+ background: -moz-linear-gradient(top, #f7f7f7 0%, #cfcfcf 7%, #aaaaaa 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f7f7f7), color-stop(7%,#cfcfcf), color-stop(100%,#aaaaaa));
+ background: -webkit-linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%);
+ background: -o-linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%);
+ background: -ms-linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%);
+ background: linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f7f7f7', endColorstr='#aaaaaa',GradientType=0 );
+ border-bottom: 1px solid #111;
+}
+
+.quickstart .code .shell {
+ padding: 20px;
+ text-shadow: none;
+ margin: 0 20px;
+ background: #3d3d3d;
+ border-radius: 0 0 5px 5px;
+ box-shadow: 0 5px 30px rgba(0,0,0,.3);
+}
+
+.quickstart .code .line {
+ display: block;
+ margin: 0;
+ padding: 0;
+}
+
+.quickstart .code .line span {
+ display: inline-block;
+}
+
+.quickstart .code .path {
+ color: #87ceeb;
+}
+
+.quickstart .code .prompt {
+ color: #cd5c5c;
+}
+
+.quickstart .code .command {
+ color: #f0e68c;
+}
+
+.quickstart .code .output {
+ color: #888;
+}
+
+/* Free Hosting */
+
+.free-hosting .pane {
+ background: #444;
+ border-radius: 10px;
+ text-shadow: none;
+ position: relative;
+ padding: 0 20px 30px;
+}
+
+.free-hosting img {
+ margin: -30px 0 0;
+ width: 180px;
+ height: 150px;
+}
+
+.free-hosting h2 {
+ font-size: 28px;
+}
+
+.free-hosting p,
+.free-hosting a {
+ font-size: 16px;
+}
+
+.free-hosting p {
+ margin: .75em 0;
+}
+
+ at media (min-width: 768px){
+ .free-hosting img {
+ float: left;
+ margin: -20px -30px -30px -50px;
+ width: 300px;
+ height: 251px;
+ }
+ .free-hosting .pane-content {
+ margin-top: 35px;
+ padding-right: 30px;
+ }
+ .free-hosting p,
+ .free-hosting a {
+ font-size: 18px;
+ }
+ .free-hosting .pane:after {
+ content: " ";
+ float: right;
+ background: url(../img/footer-arrow.png) top left no-repeat;
+ width: 73px;
+ height: 186px;
+ position: absolute;
+ right: 0;
+ bottom: -30px;
+ }
+}
+
+/* Article - Used for both docs and news */
+
+
+article {
+ background: #444;
+ border-radius: 10px;
+ padding: 20px;
+ margin: 0 10px;
+ box-shadow: 0 3px 10px rgba(0,0,0,.1);
+ font-size: 16px;
+}
+
+ at media (max-width: 480px){
+ article ul {
+ padding-left: 20px;
+ }
+}
+
+ at media (max-width: 568px){
+ article {
+ margin: 0;
+ }
+}
+
+ at media (min-width: 768px){
+ article {
+ padding: 40px 40px 30px;
+ font-size: 21px;
+ }
+}
+
+/* Right-side nav - used by both docs and news */
+
+aside {
+ padding-top: 30px;
+}
+
+aside h4 {
+ text-transform: uppercase;
+ font-size: 14px;
+ font-weight: 700;
+ padding: 0 0 10px 30px;
+ margin-left: -30px;
+ display: inline-block;
+ border-bottom: 1px solid #c00;
+}
+
+aside ul {
+ padding-left: 0;
+}
+
+aside ul:first-child {
+ margin-top: 0;
+}
+
+aside li {
+ list-style-type: none;
+}
+
+aside li a {
+ font-size: 16px;
+ position: relative
+}
+
+aside li.current a:before {
+ content: "";
+ border-color: transparent transparent transparent #444;
+ border-style: solid;
+ border-width: 10px;
+ width: 0;
+ height: 0;
+ position: absolute;
+ top: 0;
+ left: -30px;
+}
+
+/* Documentation */
+
+.docs article {
+ min-height: 800px;
+}
+
+.docs .content {
+ padding: 0;
+}
+
+.section-nav {
+ text-align: center;
+ padding-top: 40px;
+ position: relative;
+ background: url(../img/article-footer.png) top center no-repeat;
+ margin: 40px -20px 10px;
+}
+
+.section-nav > div {
+ width: 49.5%;
+}
+
+.section-nav a, .section-nav span {
+ color: #fff;
+ font-size: 16px;
+ text-transform: uppercase;
+ font-weight: 700;
+ padding: 8px 12px 10px;
+ border-radius: 5px;
+ /*border: 1px solid #333;*/
+ box-shadow: 0 1px 3px rgba(0,0,0,.3), inset 0 1px 1px rgba(255,255,255,.5);
+ background: #777;
+}
+
+.section-nav a:hover {
+ color: #fff;
+ background: #888;
+}
+
+.section-nav .next, .section-nav .prev {
+ position: relative;
+}
+
+.section-nav .next:after, .section-nav .prev:before {
+ font-size: 36px;
+ color: #222;
+ font-weight: 800;
+ text-shadow: 0 1px 0 rgba(255,255,255,.4);
+ position: absolute;
+ top: -7px;
+}
+
+.section-nav .next:after {
+ content: "›";
+ right: 10px;
+}
+
+.section-nav .prev:before {
+ content: "‹";
+ left: 10px;
+}
+
+.section-nav .prev, .section-nav .prev:hover {
+ /*float: left;*/
+ padding-left: 30px;
+}
+
+.section-nav .next, .section-nav .next:hover {
+ /*float: right;*/
+ padding-right: 30px;
+}
+
+.section-nav .disabled {
+ opacity: .5;
+ /*filter: alpha*/
+ cursor: default;
+}
+
+.docs-nav-mobile select {
+ width: 100%;
+}
+
+/* News */
+
+article h2:first-child {
+ margin-top: 0;
+}
+
+.post-category,
+.post-meta {
+ display: inline-block;
+ vertical-align: middle;
+ font-size: .8em;
+}
+
+.post-category {
+ display: inline-block;
+ margin-left: -30px;
+ padding: 6px 10px 8px;
+ padding-left: 50px;
+ border-radius: 0 5px 5px 0;
+ position: relative;
+ box-shadow: 0 1px 5px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255,255,255,.2), inset 0 -1px 0 rgba(0,0,0,.3);
+ background: #9e2812;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzllMjgxMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3At [...]
+ background: -moz-linear-gradient(top, #9e2812 0%, #6f0d0d 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#9e2812), color-stop(100%,#6f0d0d));
+ background: -webkit-linear-gradient(top, #9e2812 0%,#6f0d0d 100%);
+ background: -o-linear-gradient(top, #9e2812 0%,#6f0d0d 100%);
+ background: -ms-linear-gradient(top, #9e2812 0%,#6f0d0d 100%);
+ background: linear-gradient(to bottom, #9e2812 0%,#6f0d0d 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9e2812', endColorstr='#6f0d0d',GradientType=0 );
+}
+
+.label {
+ float: left;
+ text-transform: uppercase;
+ font-weight: bold;
+ text-shadow: 0 -1px 0 rgba(0,0,0,.5);
+}
+
+ at media (max-width: 568px){
+ .post-category {
+ padding-left: 30px;
+ }
+}
+
+ at media (min-width: 768px){
+ .post-category {
+ margin-left: -50px;
+ }
+}
+
+.post-category:before {
+ content: "";
+ position: absolute;
+ top: -10px;
+ left: 0px;
+ border-color: transparent #6f0d0d #6f0d0d transparent;
+ border-style: solid;
+ border-width: 5px;
+ width: 0;
+ height: 0;
+}
+
+.avatar {
+ width: 24px;
+ height: 24px;
+ border-radius: 3px;
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.post-meta {
+ padding: 5px 0;
+ color: #aaa;
+ font-weight: 600;
+ text-shadow: 0 -1px 0 #000;
+}
+
+.post-date,
+.post-author {
+ margin-left: 10px;
+}
+
+.news article + article {
+ margin-top: -10px;
+ border-radius: 0 0 10px 10px;
+ border-top: 1px solid #555;
+ box-shadow: 0 -1px 0 #2f2f2f;
+}
+
+/* Code Highlighting */
+
+
+pre, code {
+ white-space: pre;
+ display: inline-block;
+ margin: 0;
+ padding: 0;
+ font-family: Menlo, Consolas, "Courier New", Courier, "Liberation Mono", monospace;
+ font-size: 14px;
+ padding: 0 .5em;
+ line-height: 1.8em;
+}
+
+ at media (min-width: 768px){
+ pre, code {
+ font-size: 16px;
+ }
+}
+
+.highlight, p > pre, p > code, p > nobr > code, li > code, h5 > code, .note > code {
+ background: #333;
+ color: #fff;
+ border-radius: 5px;
+ box-shadow: inset 0 1px 10px rgba(0,0,0,.3),
+ 0 1px 0 rgba(255,255,255,.1),
+ 0 -1px 0 rgba(0,0,0,.5);
+}
+
+.note code {
+ background-color: rgba(0,0,0,0.2);
+ margin-left: 2.5px;
+ margin-right: 2.5px;
+ font-size: 0.8em;
+}
+
+.highlight {
+ padding: 10px 0;
+ width: 100%;
+ overflow: auto;
+}
+
+/* HTML Elements */
+
+h1, h2, h3, h4, h5, h6 {
+ margin: 0;
+}
+
+a {
+ color: #fc0;
+ text-decoration: none;
+ transition: all .25s;
+ -moz-transition: all .25s;
+ -webkit-transition: all .25s;
+}
+
+a:hover {
+ color: #f90;
+}
+
+strong {
+ font-weight: 700;
+}
+
+p {
+ line-height: 1.5em;
+}
+
+.left { float: left; }
+.right { float: right; }
+.align-right { text-align: right; }
+.align-left { text-align: left; }
+.align-center { text-align: center; }
+
+/* Article HTML */
+
+article h2,
+article h3,
+article h4,
+article h5,
+article h6 {
+ margin: 1em 0;
+}
+
+article h4 {
+ color: #fff;
+}
+
+h5, h6 {
+ font-size: 1em;
+ font-style: italic;
+}
+
+article ul li p {
+ margin: 0;
+}
+
+article ul li, article ol li {
+ line-height: 1.5em;
+ margin-bottom: 0.5em;
+}
+
+article ul li blockquote {
+ margin: 10px 0;
+}
+
+blockquote {
+ border-left: 2px solid #777;
+ padding-left: 20px;
+ font-style: italic;
+ font-size: 18px;
+ font-weight: 500;
+}
+
+
+/* Tables */
+
+table {
+ width: 100%;
+ background: #555;
+ margin: .5em 0;
+ border-radius: 5px;
+ box-shadow: 0 1px 3px rgba(0,0,0,.3);
+}
+
+thead {
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+ color: #fff;
+ background: #3a3a3a;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzNhM2EzYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3At [...]
+ background: -moz-linear-gradient(top, #3a3a3a 0%, #1e1e1e 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3a3a3a), color-stop(100%,#1e1e1e));
+ background: -webkit-linear-gradient(top, #3a3a3a 0%,#1e1e1e 100%);
+ background: -o-linear-gradient(top, #3a3a3a 0%,#1e1e1e 100%);
+ background: -ms-linear-gradient(top, #3a3a3a 0%,#1e1e1e 100%);
+ background: linear-gradient(to bottom, #3a3a3a 0%,#1e1e1e 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3a3a3a', endColorstr='#1e1e1e',GradientType=0 );
+}
+
+thead th {
+ position: relative;
+ box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
+}
+
+thead th:first-child {
+ border-top-left-radius: 5px;
+}
+
+thead th:last-child {
+ border-top-right-radius: 5px;
+}
+
+td {
+ padding: .5em .75em;
+}
+
+td p {
+ margin: 0;
+}
+
+th {
+ text-transform: uppercase;
+ font-size: 16px;
+ padding: .5em .75em;
+ text-shadow: 0 -1px 0 rgba(0,0,0,.9);
+ color: #888;
+}
+
+tbody td {
+ border-top: 1px solid rgba(0,0,0,.1);
+ box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3Rv [...]
+ background: -moz-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.1)), color-stop(100%,rgba(255,255,255,0)));
+ background: -webkit-linear-gradient(top, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%);
+ background: -o-linear-gradient(top, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%);
+ background: -ms-linear-gradient(top, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%);
+ background: linear-gradient(to bottom, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1affffff', endColorstr='#00ffffff',GradientType=0 );
+}
+
+td p {
+ font-size: 16px;
+}
+
+td p code {
+ font-size: 14px;
+}
+
+code.option, th .option, code.filter, th .filter {
+ color: #50B600;
+}
+
+code.flag, th .flag, code.output, th .output {
+ color: #049DCE;
+}
+
+code.option, code.flag, code.filter, code.output {
+ margin-bottom: 2px;
+}
+
+/* Note types */
+
+.note {
+ margin: 30px 0;
+ margin-left: -30px;
+ padding: 20px 20px 24px;
+ padding-left: 50px;
+ border-radius: 0 5px 5px 0;
+ position: relative;
+ box-shadow: 0 1px 5px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255,255,255,.2), inset 0 -1px 0 rgba(0,0,0,.3);
+ background: #7e6d42;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzdlNmQ0MiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3At [...]
+ background: -moz-linear-gradient(top, #7e6d42 0%, #5c4e35 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7e6d42), color-stop(100%,#5c4e35));
+ background: -webkit-linear-gradient(top, #7e6d42 0%,#5c4e35 100%);
+ background: -o-linear-gradient(top, #7e6d42 0%,#5c4e35 100%);
+ background: -ms-linear-gradient(top, #7e6d42 0%,#5c4e35 100%);
+ background: linear-gradient(to bottom, #7e6d42 0%,#5c4e35 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7e6d42', endColorstr='#5c4e35',GradientType=0 );
+}
+
+ at media (max-width: 568px){
+ .note {
+ margin-right: -30px;
+ }
+}
+
+ at media (min-width: 768px){
+ .note {
+ margin-left: -50px;
+ }
+}
+
+.note:before {
+ content: "";
+ position: absolute;
+ top: -10px;
+ left: 0px;
+ border-color: transparent #222 #222 transparent;
+ border-style: solid;
+ border-width: 5px;
+ width: 0;
+ height: 0;
+}
+
+.note h5, .note p {
+ margin: 0;
+ color: #fff;
+}
+
+.note h5 {
+ line-height: 1.5em;
+ font-weight: 800;
+ font-style: normal;
+}
+
+.note p {
+ font-weight: 400;
+ font-size: .75em;
+}
+
+.info {
+ background: #0389aa;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAzODlhYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3At [...]
+ background: -moz-linear-gradient(top, #0389aa 0%, #00617f 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#0389aa), color-stop(100%,#00617f));
+ background: -webkit-linear-gradient(top, #0389aa 0%,#00617f 100%);
+ background: -o-linear-gradient(top, #0389aa 0%,#00617f 100%);
+ background: -ms-linear-gradient(top, #0389aa 0%,#00617f 100%);
+ background: linear-gradient(to bottom, #0389aa 0%,#00617f 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0389aa', endColorstr='#00617f',GradientType=0 );
+}
+
+.warning {
+ background: #9e2812;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzllMjgxMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3At [...]
+ background: -moz-linear-gradient(top, #9e2812 0%, #6f0d0d 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#9e2812), color-stop(100%,#6f0d0d));
+ background: -webkit-linear-gradient(top, #9e2812 0%,#6f0d0d 100%);
+ background: -o-linear-gradient(top, #9e2812 0%,#6f0d0d 100%);
+ background: -ms-linear-gradient(top, #9e2812 0%,#6f0d0d 100%);
+ background: linear-gradient(to bottom, #9e2812 0%,#6f0d0d 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9e2812', endColorstr='#6f0d0d',GradientType=0 );
+}
+
+.info:before {
+ border-color: transparent #00617f #00617f transparent;
+}
+
+.warning:before {
+ border-color: transparent #6f0d0d #6f0d0d transparent;
+}
+
+.note:after {
+ content: "★";
+ color: #fc0;
+ position: absolute;
+ top: 14px;
+ left: 14px;
+ font-size: 28px;
+ font-weight: bold;
+ text-shadow: 0 -1px 0 rgba(0,0,0,.5);
+}
+
+.info:after {
+ content: "ⓘ";
+ color: #fff;
+ position: absolute;
+ top: 15px;
+ left: 15px;
+ font-size: 28px;
+ font-weight: bold;
+ text-shadow: 0 -1px 0 rgba(0,0,0,.5);
+}
+
+.warning:after {
+ content: "‼";
+ color: #fc0;
+ position: absolute;
+ top: 15px;
+ left: 15px;
+ font-size: 32px;
+ font-weight: bold;
+ text-shadow: 0 -1px 0 rgba(0,0,0,.5);
+}
+
+/* Responsive tables */
+
+ at media (max-width: 768px){
+ .mobile-side-scroller {
+ overflow-x: scroll;
+ margin: 0 -40px;
+ padding: 0 10px;
+ }
+}
diff --git a/site/docs/configuration.md b/site/docs/configuration.md
new file mode 100644
index 0000000..1594d75
--- /dev/null
+++ b/site/docs/configuration.md
@@ -0,0 +1,375 @@
+---
+layout: docs
+title: Configuration
+prev_section: structure
+next_section: frontmatter
+permalink: /docs/configuration/
+---
+
+Jekyll allows you to concoct your sites in any way you can dream up, and it’s
+thanks to the powerful and flexible configuration options that this is possible.
+These options can either be specified in a `_config.yml` file placed in your
+site’s root directory, or can be specified as flags for the `jekyll` executable
+in the terminal.
+
+## Configuration Settings
+
+### Global Configuration
+
+The table below lists the available settings for Jekyll, and the various <code
+class="option">options</code> (specified in the configuration file) and <code
+class="flag">flags</code> (specified on the command-line) that control them.
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Setting</th>
+ <th>
+ <span class="option">Options</span> and <span class="flag">Flags</span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Site Source</strong></p>
+ <p class='description'>Change the directory where Jekyll will read files</p>
+ </td>
+ <td class="align-center">
+ <p><code class="option">source: DIR</code></p>
+ <p><code class="flag">-s, --source DIR</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Site Destination</strong></p>
+ <p class='description'>Change the directory where Jekyll will write files</p>
+ </td>
+ <td class="align-center">
+ <p><code class="option">destination: DIR</code></p>
+ <p><code class="flag">-d, --destination DIR</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Safe</strong></p>
+ <p class='description'>Disable <a href="../plugins/">custom plugins</a>.</p>
+ </td>
+ <td class="align-center">
+ <p><code class="option">safe: BOOL</code></p>
+ <p><code class="flag">--safe</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Exclude</strong></p>
+ <p class="description">Exclude directories and/or files from the conversion</p>
+ </td>
+ <td class='align-center'>
+ <p><code class="option">exclude: [DIR, FILE, ...]</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Include</strong></p>
+ <p class="description">
+ Force inclusion of directories and/or files in the conversion.
+ <code>.htaccess</code> is a good example since dotfiles are excluded
+ by default.
+ </p>
+ </td>
+ <td class='align-center'>
+ <p><code class="option">include: [DIR, FILE, ...]</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Time Zone</strong></p>
+ <p class="description">
+ Set the time zone for site generation. This sets the <code>TZ</code>
+ environment variable, which Ruby uses to handle time and date
+ creation and manipulation. Any entry from the
+ <a href="http://en.wikipedia.org/wiki/Tz_database">IANA Time Zone
+ Database</a> is valid, e.g. <code>America/New_York</code>. The default
+ is the local time zone, as set by your operating system.
+ </p>
+ </td>
+ <td class='align-center'>
+ <p><code class="option">timezone: TIMEZONE</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Encoding</strong></p>
+ <p class="description">
+ Set the encoding of files by name. Only available for Ruby
+ 1.9 or later).
+ The default value is nil, which use Ruby default,
+ <code>ASCII-8BIT</code>.
+ Available encoding for the ruby in use, can be shown by
+ command <code>ruby -e 'puts Encoding::list.join("\n")'</code>
+ </p>
+ </td>
+ <td class='align-center'>
+ <p><code class="option">encoding: ENCODING</code></p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+### Build Command Options
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Setting</th>
+ <th><span class="option">Options</span> and <span class="flag">Flags</span></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Regeneration</strong></p>
+ <p class='description'>Enable auto-regeneration of the site when files are modified.</p>
+ </td>
+ <td class="align-center">
+ <p><code class="flag">-w, --watch</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Configuration</strong></p>
+ <p class="description">Specify config files instead of using <code>_config.yml</code> automatically. Settings in later files override settings in earlier files.</p>
+ </td>
+ <td class='align-center'>
+ <p><code class="flag">--config FILE1[,FILE2,...]</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Drafts</strong></p>
+ <p class="description">Process and render draft posts.</p>
+ </td>
+ <td class='align-center'>
+ <p><code class="flag">--drafts</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Future</strong></p>
+ <p class="description">Publish posts with a future date.</p>
+ </td>
+ <td class='align-center'>
+ <p><code class="option">future: BOOL</code></p>
+ <p><code class="flag">--future</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>LSI</strong></p>
+ <p class="description">Produce an index for related posts.</p>
+ </td>
+ <td class='align-center'>
+ <p><code class="option">lsi: BOOL</code></p>
+ <p><code class="flag">--lsi</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Limit Posts</strong></p>
+ <p class="description">Limit the number of posts to parse and publish.</p>
+ </td>
+ <td class='align-center'>
+ <p><code class="option">limit_posts: NUM</code></p>
+ <p><code class="flag">--limit_posts NUM</code></p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+### Serve Command Options
+
+In addition to the options below, the `serve` sub-command can accept any of the options
+for the `build` sub-command, which are then applied to the site build which occurs right
+before your site is served.
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Setting</th>
+ <th><span class="option">Options</span> and <span class="flag">Flags</span></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Local Server Port</strong></p>
+ <p class='description'>Listen on the given port.</p>
+ </td>
+ <td class="align-center">
+ <p><code class="option">port: PORT</code></p>
+ <p><code class="flag">--port PORT</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Local Server Hostname</strong></p>
+ <p class='description'>Listen at the given hostname.</p>
+ </td>
+ <td class="align-center">
+ <p><code class="option">host: HOSTNAME</code></p>
+ <p><code class="flag">--host HOSTNAME</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Base URL</strong></p>
+ <p class='description'>Serve the website from the given base URL</p>
+ </td>
+ <td class="align-center">
+ <p><code class="option">baseurl: URL</code></p>
+ <p><code class="flag">--baseurl URL</code></p>
+ </td>
+ </tr>
+ <tr class='setting'>
+ <td>
+ <p class='name'><strong>Detach</strong></p>
+ <p class='description'>Detach the server from the terminal</p>
+ </td>
+ <td class="align-center">
+ <p><code class="option">detach: BOOL</code></p>
+ <p><code class="flag">-B, --detach</code></p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<div class="note warning">
+ <h5>Do not use tabs in configuration files</h5>
+ <p>
+ This will either lead to parsing errors, or Jekyll will revert to the
+ default settings. Use spaces instead.
+ </p>
+</div>
+
+## Default Configuration
+
+Jekyll runs with the following configuration options by default. Unless
+alternative settings for these options are explicitly specified in the
+configuration file or on the command-line, Jekyll will run using these options.
+
+<div class="note warning">
+ <h5>There are two unsupported kramdown options</h5>
+ <p>
+ Please note that both <code>remove_block_html_tags</code> and
+ <code>remove_span_html_tags</code> are currently unsupported in Jekyll due to the
+ fact that they are not included within the kramdown HTML converter.
+ </p>
+</div>
+
+{% highlight yaml %}
+source: .
+destination: ./_site
+plugins: ./_plugins
+layouts: ./_layouts
+include: ['.htaccess']
+exclude: []
+keep_files: ['.git','.svn']
+gems: []
+timezone: nil
+encoding: nil
+
+future: true
+show_drafts: nil
+limit_posts: 0
+pygments: true
+
+relative_permalinks: true
+
+permalink: date
+paginate_path: 'page:num'
+
+markdown: maruku
+markdown_ext: markdown,mkd,mkdn,md
+textile_ext: textile
+
+excerpt_separator: "\n\n"
+
+safe: false
+watch: false # deprecated
+server: false # deprecated
+host: 0.0.0.0
+port: 4000
+baseurl: /
+url: http://localhost:4000
+lsi: false
+
+maruku:
+ use_tex: false
+ use_divs: false
+ png_engine: blahtex
+ png_dir: images/latex
+ png_url: /images/latex
+ fenced_code_blocks: true
+
+rdiscount:
+ extensions: []
+
+redcarpet:
+ extensions: []
+
+kramdown:
+ auto_ids: true
+ footnote_nr: 1
+ entity_output: as_char
+ toc_levels: 1..6
+ smart_quotes: lsquo,rsquo,ldquo,rdquo
+ use_coderay: false
+
+ coderay:
+ coderay_wrap: div
+ coderay_line_numbers: inline
+ coderay_line_numbers_start: 1
+ coderay_tab_width: 4
+ coderay_bold_every: 10
+ coderay_css: style
+
+redcloth:
+ hard_breaks: true
+{% endhighlight %}
+
+
+## Markdown Options
+
+The various Markdown renderers supported by Jekyll sometimes have extra options available.
+
+### Redcarpet
+
+Redcarpet can be configured by providing an `extensions` sub-setting, whose value should be an array of strings. Each string should be the name of one of the `Redcarpet::Markdown` class's extensions; if present in the array, it will set the corresponding extension to `true`.
+
+Jekyll handles two special Redcarpet extensions:
+
+- `no_fenced_code_blocks` --- By default, Jekyll sets the `fenced_code_blocks` extension (for delimiting code blocks with triple tildes or triple backticks) to `true`, probably because GitHub's eager adoption of them is starting to make them inescapable. Redcarpet's normal `fenced_code_blocks` extension is inert when used with Jekyll; instead, you can use this inverted version of the extension for disabling fenced code.
+
+ Note that you can also specify a language for highlighting after the first delimiter:
+
+ ```ruby
+ # ...ruby code
+ ```
+
+ With both fenced code blocks and pygments enabled, this will statically highlight the code; without pygments, it will add a `class="LANGUAGE"` attribute to the `<code>` element, which can be used as a hint by various JavaScript code highlighting libraries.
+- `smart` --- This pseudo-extension turns on SmartyPants, which converts straight quotes to curly quotes and runs of hyphens to em (`---`) and en (`--`) dashes.
+
+All other extensions retain their usual names from Redcarpet, and no renderer options aside from `smart` can be specified in Jekyll. [A list of available extensions can be found in the Redcarpet README file.][redcarpet_extensions] Make sure you're looking at the README for the right version of Redcarpet: Jekyll currently uses v2.2.x, and extensions like `footnotes` and `highlight` weren't added until after version 3.0.0. The most commonly used extensions are:
+
+- `tables`
+- `no_intra_emphasis`
+- `autolink`
+
+[redcarpet_extensions]: https://github.com/vmg/redcarpet/blob/v2.2.2/README.markdown#and-its-like-really-simple-to-use
diff --git a/site/docs/contributing.md b/site/docs/contributing.md
new file mode 100644
index 0000000..0740e32
--- /dev/null
+++ b/site/docs/contributing.md
@@ -0,0 +1,128 @@
+---
+layout: docs
+title: Contributing
+prev_section: upgrading
+next_section: history
+permalink: /docs/contributing/
+---
+
+So you've got an awesome idea to throw into Jekyll. Great! Please keep the
+following in mind:
+
+* If you're creating a small fix or patch to an existing feature, just a simple
+ test will do. Please stay in the confines of the current test suite and use
+ [Shoulda](http://github.com/thoughtbot/shoulda/tree/master) and
+ [RR](http://github.com/btakita/rr/tree/master).
+* If it's a brand new feature, make sure to create a new
+ [Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
+ where appropriate. Also, whipping up some documentation in your fork's `site`
+ would be appreciated, and once merged it will be transferred over to the main
+ `site`, jekyllrb.com.
+* If your contribution changes any Jekyll behavior, make sure to update the
+ documentation. It lives in `site/docs`. If the docs are missing information,
+ please feel free to add it in. Great docs make a great project!
+* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
+ when modifying Ruby code.
+* Please do your best to submit **small pull requests**. The easier the proposed
+ change is to review, the more likely it will be merged.
+* When submitting a pull request, please make judicious use of the pull request
+ body. A description of what changes were made, the motivations behind the
+ changes and [any tasks completed or left to complete](http://git.io/gfm-tasks)
+ will also speed up review time.
+
+<div class="note warning">
+ <h5>Contributions will not be accepted without tests</h5>
+ <p>
+ If you’re creating a small fix or patch to an existing feature, just
+ a simple test will do.
+ </p>
+</div>
+
+Test Dependencies
+-----------------
+
+To run the test suite and build the gem you'll need to install Jekyll's
+dependencies. Jekyll uses Bundler, so a quick run of the `bundle` command and
+you're all set!
+
+{% highlight bash %}
+$ bundle
+{% endhighlight %}
+
+Before you start, run the tests and make sure that they pass (to confirm your
+environment is configured properly):
+
+{% highlight bash %}
+$ bundle exec rake test
+$ bundle exec rake features
+{% endhighlight %}
+
+Workflow
+--------
+
+Here's the most direct way to get your work merged into the project:
+
+* Fork the project.
+* Clone down your fork:
+
+{% highlight bash %}
+git clone git://github.com/<username>/jekyll.git
+{% endhighlight %}
+
+* Create a topic branch to contain your change:
+
+{% highlight bash %}
+git checkout -b my_awesome_feature
+{% endhighlight %}
+
+
+* Hack away, add tests. Not necessarily in that order.
+* Make sure everything still passes by running `rake`.
+* If necessary, rebase your commits into logical chunks, without errors.
+* Push the branch up:
+
+{% highlight bash %}
+git push origin my_awesome_feature
+{% endhighlight %}
+
+* Create a pull request against mojombo/jekyll:master and describe what your
+ change does and the why you think it should be merged.
+
+Updating Documentation
+----------------------
+
+We want the Jekyll documentation to be the best it can be. We've
+open-sourced our docs and we welcome any pull requests if you find it
+lacking.
+
+You can find the documentation for jekyllrb.com in the
+[site]({{ site.repository }}/tree/master/site) directory of
+Jekyll's repo on GitHub.com.
+
+All documentation pull requests should be directed at `master`. Pull
+requests directed at another branch will not be accepted.
+
+The [Jekyll wiki]({{ site.repository }}/wiki) on GitHub
+can be freely updated without a pull request as all
+GitHub users have access.
+
+Gotchas
+-------
+
+* If you want to bump the gem version, please put that in a separate commit.
+ This way, the maintainers can control when the gem gets released.
+* Try to keep your patch(es) based from the latest commit on mojombo/jekyll.
+ The easier it is to apply your work, the less work the maintainers have to do,
+ which is always a good thing.
+* Please don't tag your GitHub issue with \[fix\], \[feature\], etc. The maintainers
+ actively read the issues and will label it once they come across it.
+
+<div class="note">
+ <h5>Let us know what could be better!</h5>
+ <p>
+ Both using and hacking on Jekyll should be fun, simple, and easy, so if for
+ some reason you find it’s a pain, please <a
+ href="{{ site.repository }}/issues/new">create an issue</a> on
+ GitHub describing your experience so we can make it better.
+ </p>
+</div>
diff --git a/site/docs/datafiles.md b/site/docs/datafiles.md
new file mode 100644
index 0000000..93b50aa
--- /dev/null
+++ b/site/docs/datafiles.md
@@ -0,0 +1,63 @@
+---
+layout: docs
+title: Data Files
+prev_section: variables
+next_section: migrations
+permalink: /docs/datafiles/
+---
+
+In addition to the [built-in variables](../variables/) available from Jekyll,
+you can specify your own custom data that can be accessed via the [Liquid
+templating system](http://wiki.github.com/shopify/liquid/liquid-for-designers).
+
+Jekyll supports loading data from [YAML](http://yaml.org/) files located in the
+`_data` directory.
+
+This powerful features allows you to avoid repetition in your templates and to
+set site specific options without changing `_config.yml`.
+
+Plugins/themes can also leverage Data Files to set configuration variables.
+
+## The Data Folder
+
+As explained on the [directory structure](../structure/) page, the `_data`
+folder is where you can store additional data for Jekyll to use when generating
+your site. These files must be YAML files (using either the `.yml` or `.yaml`
+extension) and they will be accessible via `site.data`.
+
+## Example: List of members
+
+Here is a basic example of using Data Files to avoid copy-pasting large chunks of
+code in your Jekyll templates:
+
+In `_data/members.yml`:
+
+{% highlight yaml %}
+- name: Tom Preston-Werner
+ github: mojombo
+
+- name: Parker Moore
+ github: parkr
+
+- name: Liu Fengyun
+ github: liufengyun
+{% endhighlight %}
+
+This data can be accessed via `site.data.members` (notice that the filename
+determines the variable name).
+
+You can now render the list of members in a template:
+
+{% highlight html %}
+{% raw %}
+<ul>
+{% for member in site.data.members %}
+ <li>
+ <a href="https://github.com/{{ member.github }}">
+ {{ member.name }}
+ </a>
+ </li>
+{% endfor %}
+</ul>
+{% endraw %}
+{% endhighlight %}
diff --git a/site/docs/deployment-methods.md b/site/docs/deployment-methods.md
new file mode 100644
index 0000000..6922a9d
--- /dev/null
+++ b/site/docs/deployment-methods.md
@@ -0,0 +1,109 @@
+---
+layout: docs
+title: Deployment methods
+prev_section: github-pages
+next_section: troubleshooting
+permalink: /docs/deployment-methods/
+---
+
+Sites built using Jekyll can be deployed in a large number of ways due to the static nature of the generated output. A few of the most common deployment techniques are described below.
+
+## Web hosting providers (FTP)
+
+Just about any traditional web hosting provider will let you upload files to their servers over FTP. To upload a Jekyll site to a web host using FTP, simply run the `jekyll` command and copy the generated `_site` folder to the root folder of your hosting account. This is most likely to be the `httpdocs` or `public_html` folder on most hosting providers.
+
+### FTP using Glynn
+
+There is a project called [Glynn](https://github.com/dmathieu/glynn), which lets you easily generate your Jekyll powered website’s static files and
+send them to your host through FTP.
+
+## Self-managed web server
+
+If you have direct access yourself to the deployment web server yourself, the process is essentially the same, except you might have other methods available to you (such as `scp`, or even direct filesystem access) for transferring the files. Just remember to make sure the contents of the generated `_site` folder get placed in the appropriate web root directory for your web server.
+
+## Automated methods
+
+There are also a number of ways to easily automate the deployment of a Jekyll site. If you’ve got another method that isn’t listed below, we’d love it if you [contributed](../contributing/) so that everyone else can benefit too.
+
+### Git post-update hook
+
+If you store your jekyll site in [Git](http://git-scm.com/) (you are using version control, right?), it’s pretty easy to automate the
+deployment process by setting up a post-update hook in your Git
+repository, [like
+this](http://web.archive.org/web/20091223025644/http://www.taknado.com/en/2009/03/26/deploying-a-jekyll-generated-site/).
+
+### Git post-receive hook
+
+To have a remote server handle the deploy for you every time you push changes using Git, you can create a user account which has all the public keys that are authorized to deploy in its `authorized_keys` file. With that in place, setting up the post-receive hook is done as follows:
+
+{% highlight bash %}
+laptop$ ssh deployer at example.com
+server$ mkdir myrepo.git
+server$ cd myrepo.git
+server$ git --bare init
+server$ cp hooks/post-receive.sample hooks/post-receive
+server$ mkdir /var/www/myrepo
+{% endhighlight %}
+
+Next, add the following lines to hooks/post-receive and be sure Jekyll is
+installed on the server:
+
+{% highlight bash %}
+GIT_REPO=$HOME/myrepo.git
+TMP_GIT_CLONE=$HOME/tmp/myrepo
+PUBLIC_WWW=/var/www/myrepo
+
+git clone $GIT_REPO $TMP_GIT_CLONE
+jekyll build -s $TMP_GIT_CLONE -d $PUBLIC_WWW
+rm -Rf $TMP_GIT_CLONE
+exit
+{% endhighlight %}
+
+Finally, run the following command on any users laptop that needs to be able to
+deploy using this hook:
+
+{% highlight bash %}
+laptops$ git remote add deploy deployer at example.com:~/myrepo.git
+{% endhighlight %}
+
+Deploying is now as easy as telling nginx or Apache to look at
+`/var/www/myrepo` and running the following:
+
+{% highlight bash %}
+laptops$ git push deploy master
+{% endhighlight %}
+
+### Rake
+
+Another way to deploy your Jekyll site is to use [Rake](https://github.com/jimweirich/rake), [HighLine](https://github.com/JEG2/highline), and
+[Net::SSH](http://net-ssh.rubyforge.org/). A more complex example of deploying Jekyll with Rake that deals with multiple branches can be found in [Git Ready](https://github.com/gitready/gitready/blob/cdfbc4ec5321ff8d18c3ce936e9c749dbbc4f190/Rakefile).
+
+### rsync
+
+Once you’ve generated the `_site` directory, you can easily rsync it using a `tasks/deploy` shell script similar to [this deploy script here](http://github.com/henrik/henrik.nyh.se/blob/master/tasks/deploy). You’d obviously need to change the values to reflect your site’s details. There is even [a matching TextMate command](http://gist.github.com/214959) that will help you run
+this script from within Textmate.
+
+
+## Rack-Jekyll
+
+[Rack-Jekyll](http://github.com/bry4n/rack-jekyll/) is an easy way to deploy your site on any Rack server such as Amazon EC2, Slicehost, Heroku, and so forth. It also can run with [shotgun](http://github.com/rtomakyo/shotgun/), [rackup](http://github.com/rack/rack), [mongrel](http://github.com/mongrel/mongrel), [unicorn](http://github.com/defunkt/unicorn/), and [others](https://github.com/adaoraul/rack-jekyll#readme).
+
+Read [this post](http://blog.crowdint.com/2010/08/02/instant-blog-using-jekyll-and-heroku.html) on how to deploy to Heroku using Rack-Jekyll.
+
+## Jekyll-Admin for Rails
+
+If you want to maintain Jekyll inside your existing Rails app, [Jekyll-Admin](http://github.com/zkarpinski/Jekyll-Admin) contains drop in code to make this possible. See Jekyll-Admin’s [README](http://github.com/zkarpinski/Jekyll-Admin/blob/master/README) for more details.
+
+## Amazon S3
+
+If you want to host your site in Amazon S3, you can do so with
+[s3_website](https://github.com/laurilehmijoki/s3_website) application. It will
+push your site to Amazon S3 where it can be served like any web server,
+dynamically scaling to almost unlimited traffic. This approach has the
+benefit of being about the cheapest hosting option available for
+low-volume blogs as you only pay for what you use.
+
+<div class="note">
+ <h5>ProTip™: Use GitHub Pages for zero-hassle Jekyll hosting</h5>
+ <p>GitHub Pages are powered by Jekyll behind the scenes, so if you’re looking for a zero-hassle, zero-cost solution, GitHub Pages are a great way to <a href="../github-pages/">host your Jekyll-powered website for free</a>.</p>
+</div>
diff --git a/site/docs/drafts.md b/site/docs/drafts.md
new file mode 100644
index 0000000..959964d
--- /dev/null
+++ b/site/docs/drafts.md
@@ -0,0 +1,21 @@
+---
+layout: docs
+title: Working with drafts
+prev_section: posts
+next_section: pages
+permalink: /docs/drafts/
+---
+
+Drafts are posts without a date. They're posts you're still working on and don't want to
+publish yet. To get up and running with drafts, create a `_drafts` folder in your site's
+root (as described in the [site structure](/docs/structure/) section) and create your
+first draft:
+
+{% highlight text %}
+|-- _drafts/
+| |-- a-draft-post.md
+{% endhighlight %}
+
+To preview your site with drafts, simply run `jekyll serve` or `jekyll build` with
+the `--drafts` switch. Each will be assigned the value modification time of the draft file
+for its date, and thus you will see currently edited drafts as the latest posts.
diff --git a/site/docs/extras.md b/site/docs/extras.md
new file mode 100644
index 0000000..0c190ec
--- /dev/null
+++ b/site/docs/extras.md
@@ -0,0 +1,56 @@
+---
+layout: docs
+title: Extras
+prev_section: plugins
+next_section: github-pages
+permalink: /docs/extras/
+---
+
+There are a number of (optional) extra features that Jekyll supports that you
+may want to install, depending on how you plan to use Jekyll.
+
+## LaTeX Support
+
+Maruku comes with optional support for LaTeX to PNG rendering via blahtex
+(Version 0.6) which must be in your `$PATH` along with `dvips`. If you need
+Maruku to not assume a fixed location for `dvips`, check out [Remi’s Maruku
+fork](http://github.com/remi/maruku).
+
+## RDiscount
+
+If you prefer to use [RDiscount](http://github.com/rtomayko/rdiscount) instead
+of [Maruku](http://github.com/bhollis/maruku) for Markdown, just make sure you have
+it installed:
+
+{% highlight bash %}
+$ [sudo] gem install rdiscount
+{% endhighlight %}
+
+And then specify RDiscount as the Markdown engine in your `_config.yml` file to
+have Jekyll run with that option.
+
+{% highlight yaml %}
+# In _config.yml
+markdown: rdiscount
+{% endhighlight %}
+
+## Kramdown
+
+You can also use [Kramdown](http://kramdown.rubyforge.org/) instead of Maruku
+for Markdown. Make sure that Kramdown is installed:
+
+{% highlight bash %}
+$ [sudo] gem install kramdown
+{% endhighlight %}
+
+Then you can specify Kramdown as the Markdown engine in `_config.yml`.
+
+{% highlight yaml %}
+# In _config.yml
+markdown: kramdown
+{% endhighlight %}
+
+Kramdown has various options for customizing the HTML output. The
+[Configuration](/docs/configuration/) page lists the default options used by
+Jekyll. A complete list of options is also available on the [Kramdown
+website](http://kramdown.rubyforge.org/options.html).
diff --git a/site/docs/frontmatter.md b/site/docs/frontmatter.md
new file mode 100644
index 0000000..98c15cc
--- /dev/null
+++ b/site/docs/frontmatter.md
@@ -0,0 +1,180 @@
+---
+layout: docs
+title: Front-matter
+prev_section: configuration
+next_section: posts
+permalink: /docs/frontmatter/
+---
+
+The front-matter is where Jekyll starts to get really cool. Any file that
+contains a [YAML](http://yaml.org/) front matter block will be processed by
+Jekyll as a special file. The front matter must be the first thing in the file
+and must take the form of valid YAML set between triple-dashed lines. Here is a
+basic example:
+
+{% highlight yaml %}
+---
+layout: post
+title: Blogging Like a Hacker
+---
+{% endhighlight %}
+
+Between these triple-dashed lines, you can set predefined variables (see below
+for a reference) or even create custom ones of your own. These variables will
+then be available to you to access using Liquid tags both further down in the
+file and also in any layouts or includes that the page or post in question
+relies on.
+
+<div class="note warning">
+ <h5>UTF-8 Character Encoding Warning</h5>
+ <p>
+ If you use UTF-8 encoding, make sure that no <code>BOM</code> header
+ characters exist in your files or very, very bad things will happen to
+ Jekyll. This is especially relevant if you’re running Jekyll on Windows.
+ </p>
+</div>
+
+<div class="note">
+ <h5>ProTip™: Front Matter Variables Are Optional</h5>
+ <p>
+ If you want to use <a href="../variables/">Liquid tags and variables</a> but
+ don’t need anything in your front-matter, just leave it empty! The set of
+ triple-dashed lines with nothing in between will still get Jekyll to process
+ your file. (This is useful for things like CSS and RSS feeds!)
+ </p>
+</div>
+
+## Predefined Global Variables
+
+There are a number of predefined global variables that you can set in the
+front-matter of a page or post.
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Variable</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>layout</code></p>
+ </td>
+ <td>
+ <p>
+
+ If set, this specifies the layout file to use. Use the layout file
+ name without the file extension. Layout files must be placed in the
+ <code>_layouts</code> directory.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>permalink</code></p>
+ </td>
+ <td>
+ <p>
+
+ If you need your processed blog post URLs to be something other than
+ the default <code>/year/month/day/title.html</code> then you can set
+ this variable and it will be used as the final URL.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>published</code></p>
+ </td>
+ <td>
+ <p>
+ Set to false if you don’t want a specific post to show up when the
+ site is generated.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p style="margin-bottom: 5px;"><code>category</code></p>
+ <p><code>categories</code></p>
+ </td>
+ <td>
+ <p>
+
+ Instead of placing posts inside of folders, you can specify one or
+ more categories that the post belongs to. When the site is generated
+ the post will act as though it had been set with these categories
+ normally. Categories (plural key) can be specified as a <a
+ href="http://en.wikipedia.org/wiki/YAML#Lists">YAML list</a> or a
+ space-separated string.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>tags</code></p>
+ </td>
+ <td>
+ <p>
+
+ Similar to categories, one or multiple tags can be added to a post.
+ Also like categories, tags can be specified as a YAML list or a space-
+ separated string.
+
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+
+## Custom Variables
+
+Any variables in the front matter that are not predefined are mixed into the
+data that is sent to the Liquid templating engine during the conversion. For
+instance, if you set a title, you can use that in your layout to set the page
+title:
+
+{% highlight html %}
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>{% raw %}{{ page.title }}{% endraw %}</title>
+ </head>
+ <body>
+ ...
+{% endhighlight %}
+
+## Predefined Variables for Posts
+
+These are available out-of-the-box to be used in the front-matter for a post.
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Variable</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>date</code></p>
+ </td>
+ <td>
+ <p>
+ A date here overrides the date from the name of the post. This can be
+ used to ensure correct sorting of posts.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
diff --git a/site/docs/github-pages.md b/site/docs/github-pages.md
new file mode 100644
index 0000000..d5036c5
--- /dev/null
+++ b/site/docs/github-pages.md
@@ -0,0 +1,91 @@
+---
+layout: docs
+title: GitHub Pages
+prev_section: extras
+next_section: deployment-methods
+permalink: /docs/github-pages/
+---
+
+[GitHub Pages](http://pages.github.com) are public web pages for users,
+organizations, and repositories, that are freely hosted on GitHub's
+[github.io]() domain or on a custom domain name of your choice. GitHub Pages are
+powered by Jekyll behind the scenes, so in addition to supporting regular HTML
+content, they’re also a great way to host your Jekyll-powered website for free.
+
+## Deploying Jekyll to GitHub Pages
+
+GitHub Pages work by looking at certain branches of repositories on GitHub.
+There are two basic types available: user/organization pages and project pages.
+The way to deploy these two types of sites are nearly identical, except for a
+few minor details.
+
+### User and Organization Pages
+
+User and organization pages live in a special GitHub repository dedicated to
+only the GitHub Pages files. This repository must be named after the account
+name. For example, [@mojombo’s user page
+repository](https://github.com/mojombo/mojombo.github.io) has the name
+`mojombo.github.io`.
+
+Content from the `master` branch of your repository will be used to build and
+publish the GitHub Pages site, so make sure your Jekyll site is stored there.
+
+<div class="note info">
+ <h5>Custom domains do not affect repository names</h5>
+ <p>
+ GitHub Pages are initially configured to live under the
+ <code>username.github.io</code> subdomain, which is why repositories must
+ be named this way <strong>even if a custom domain is being used</strong>.
+ </p>
+</div>
+
+### Project Pages
+
+Unlike user and organization Pages, Project Pages are kept in the same
+repository as the project they are for, except that the website content is
+stored in a specially named `gh-pages` branch. The content of this branch will
+be rendered using Jekyll, and the output will become available under a subpath
+of your user pages subdomain, such as `username.github.io/project` (unless a
+custom domain is specified—see below).
+
+The Jekyll project repository itself is a perfect example of this branch
+structure—the [master branch]({{ site.repository }}) contains the
+actual software project for Jekyll, however the Jekyll website (that you’re
+looking at right now) is contained in the [gh-pages
+branch]({{ site.repository }}/tree/gh-pages) of the same repository.
+
+### Project Page URL Structure
+
+Sometimes it's nice to preview your Jekyll site before you push your `gh-pages`
+branch to GitHub. However, the subdirectory-like URL structure GitHub uses for
+Project Pages complicates the proper resolution of URLs. Here is an approach to
+utilizing the GitHub Project Page URL structure (`username.github.io/project-name/`)
+whilst maintaining the ability to preview your Jekyll site locally.
+
+1. In `_config.yml`, set the `baseurl` option to `/project-name` -- note the
+ leading slash and the **absence** of a trailing slash.
+2. When referencing JS or CSS files, do it like this:
+ `{% raw %}{{ site.baseurl}}/path/to/css.css{% endraw %}` -- note the slash
+ immediately following the variable (just before "path").
+3. When doing permalinks or internal links, do it like this:
+ `{% raw %}{{ site.baseurl }}{{ post.url }}{% endraw %}` -- note that there
+ is **no** slash between the two variables.
+4. Finally, if you'd like to preview your site before committing/deploying using
+ `jekyll serve`, be sure to pass an **empty string** to the `--baseurl` option,
+ so that you can view everything at `localhost:4000` normally (without
+ `/project-name` at the beginning): `jekyll serve --baseurl ''`
+
+This way you can preview your site locally from the site root on localhost,
+but when GitHub generates your pages from the gh-pages branch all the URLs
+will start with `/project-name` and resolve properly.
+
+<div class="note">
+ <h5>GitHub Pages Documentation, Help, and Support</h5>
+ <p>
+ For more information about what you can do with GitHub Pages, as well as for
+ troubleshooting guides, you should check out <a
+ href="https://help.github.com/categories/20/articles">GitHub’s Pages Help
+ section</a>. If all else fails, you should contact <a
+ href="https://github.com/contact">GitHub Support</a>.
+ </p>
+</div>
diff --git a/site/docs/heroku.md b/site/docs/heroku.md
new file mode 100644
index 0000000..84b448b
--- /dev/null
+++ b/site/docs/heroku.md
@@ -0,0 +1,9 @@
+---
+layout: docs
+title: Heroku
+prev_section: github-pages
+next_section: manual-deployment
+permalink: /docs/heroku/
+---
+
+Move along, people. Nothing to see here.
diff --git a/site/docs/history.md b/site/docs/history.md
new file mode 100644
index 0000000..db10e10
--- /dev/null
+++ b/site/docs/history.md
@@ -0,0 +1,850 @@
+---
+layout: docs
+title: History
+permalink: /docs/history/
+prev_section: contributing
+---
+
+## 1.4.0 / 2013-12-07
+
+### Major Enhancements
+- Add support for TOML config files ([#1765]({{ site.repository }}/issues/1765))
+
+### Minor Enhancements
+- Sort plugins as a way to establish a load order ([#1682]({{ site.repository }}/issues/1682))
+- Update Maruku to 0.7.0 ([#1775]({{ site.repository }}/issues/1775))
+
+### Bug Fixes
+- Add a space between two words in a Pagination warning message ([#1769]({{ site.repository }}/issues/1769))
+- Upgrade `toml` gem to `v0.1.0` to maintain compat with Ruby 1.8.7 ([#1778]({{ site.repository }}/issues/1778))
+
+### Development Fixes
+- Remove some whitespace in the code ([#1755]({{ site.repository }}/issues/1755))
+- Remove some duplication in the reading of posts and drafts ([#1779]({{ site.repository }}/issues/1779))
+
+### Site Enhancements
+- Fixed case of a word in the Jekyll v1.3.0 release post ([#1762]({{ site.repository }}/issues/1762))
+- Fixed the mime type for the favicon ([#1772]({{ site.repository }}/issues/1772))
+
+## 1.3.1 / 2013-11-26
+
+### Minor Enhancements
+- Add a `--prefix` option to passthrough for the importers ([#1669]({{ site.repository }}/issues/1669))
+- Push the paginator plugin lower in the plugin priority order so
+ other plugins run before it ([#1759]({{ site.repository }}/issues/1759))
+
+### Bug Fixes
+- Fix the include tag when ran in a loop ([#1726]({{ site.repository }}/issues/1726))
+- Fix errors when using `--watch` on 1.8.7 ([#1730]({{ site.repository }}/issues/1730))
+- Specify where the include is called from if an included file is
+ missing ([#1746]({{ site.repository }}/issues/1746))
+
+### Development Fixes
+- Extract `Site#filter_entries` into its own object ([#1697]({{ site.repository }}/issues/1697))
+- Enable Travis' bundle caching ([#1734]({{ site.repository }}/issues/1734))
+- Remove trailing whitespace in some files ([#1736]({{ site.repository }}/issues/1736))
+- Fix a duplicate test name ([#1754]({{ site.repository }}/issues/1754))
+
+### Site Enhancements
+- Update link to example Rakefile to point to specific commit ([#1741]({{ site.repository }}/issues/1741))
+- Fix drafts docs to indicate that draft time is based on file modification
+ time, not `Time.now` ([#1695]({{ site.repository }}/issues/1695))
+- Add `jekyll-monthly-archive-plugin` and `jekyll-category-archive-plugin` to
+ list of third-party plugins ([#1693]({{ site.repository }}/issues/1693))
+- Add `jekyll-asset-path-plugin` to list of third-party plugins ([#1670]({{ site.repository }}/issues/1670))
+- Add `emoji-for-jekyll` to list of third-part plugins ([#1708]({{ site.repository }}/issues/1708))
+- Fix previous section link on plugins page to point to pagination page ([#1707]({{ site.repository }}/issues/1707))
+- Add `org-mode` converter plugin to third-party plugins ([#1711]({{ site.repository }}/issues/1711))
+- Point "Blog migrations" page to http://import.jekyllrb.com ([#1732]({{ site.repository }}/issues/1732))
+- Add docs for `post_url` when posts are in subdirectories ([#1718]({{ site.repository }}/issues/1718))
+- Update the docs to point to `example.com` ([#1448]({{ site.repository }}/issues/1448))
+
+## 1.3.0 / 2013-11-04
+
+### Major Enhancements
+- Add support for adding data as YAML files under a site's `_data`
+ directory ([#1003]({{ site.repository }}/issues/1003))
+- Allow variables to be used with `include` tags ([#1495]({{ site.repository }}/issues/1495))
+- Allow using gems for plugin management ([#1557]({{ site.repository }}/issues/1557))
+
+### Minor Enhancements
+- Decrease the specificity in the site template CSS ([#1574]({{ site.repository }}/issues/1574))
+- Add `encoding` configuration option ([#1449]({{ site.repository }}/issues/1449))
+- Provide better error handling for Jekyll's custom Liquid tags
+ ([#1514]({{ site.repository }}/issues/1514))
+- If an included file causes a Liquid error, add the path to the
+ include file that caused the error to the error message ([#1596]({{ site.repository }}/issues/1596))
+- If a layout causes a Liquid error, change the error message so that
+ we know it comes from the layout ([#1601]({{ site.repository }}/issues/1601))
+- Update Kramdown dependency to `~> 1.2` ([#1610]({{ site.repository }}/issues/1610))
+- Update `safe_yaml` dependency to `~> 0.9.7` ([#1602]({{ site.repository }}/issues/1602))
+- Allow layouts to be in subfolders like includes ([#1622]({{ site.repository }}/issues/1622))
+- Switch to listen for site watching while serving ([#1589]({{ site.repository }}/issues/1589))
+- Add a `json` liquid filter to be used in sites ([#1651]({{ site.repository }}/issues/1651))
+- Point people to the migration docs when the `jekyll-import` gem is
+ missing ([#1662]({{ site.repository }}/issues/1662))
+
+### Bug Fixes
+- Fix up matching against source and destination when the two
+ locations are similar ([#1556]({{ site.repository }}/issues/1556))
+- Fix the missing `pathname` require in certain cases ([#1255]({{ site.repository }}/issues/1255))
+- Use `+` instead of `Array#concat` when building `Post` attribute list ([#1571]({{ site.repository }}/issues/1571))
+- Print server address when launching a server ([#1586]({{ site.repository }}/issues/1586))
+- Downgrade to Maruku `~> 0.6.0` in order to avoid changes in rendering ([#1598]({{ site.repository }}/issues/1598))
+- Fix error with failing include tag when variable was file name ([#1613]({{ site.repository }}/issues/1613))
+- Downcase lexers before passing them to pygments ([#1615]({{ site.repository }}/issues/1615))
+- Capitalize the short verbose switch because it conflicts with the
+ built-in Commander switch ([#1660]({{ site.repository }}/issues/1660))
+- Fix compatibility with 1.8.x ([#1665]({{ site.repository }}/issues/1665))
+- Fix an error with the new file watching code due to library version
+ incompatibilities ([#1687]({{ site.repository }}/issues/1687))
+
+### Development Fixes
+- Add coverage reporting with Coveralls ([#1539]({{ site.repository }}/issues/1539))
+- Refactor the Liquid `include` tag ([#1490]({{ site.repository }}/issues/1490))
+- Update launchy dependency to `~> 2.3` ([#1608]({{ site.repository }}/issues/1608))
+- Update rr dependency to `~> 1.1` ([#1604]({{ site.repository }}/issues/1604))
+- Update cucumber dependency to `~> 1.3` ([#1607]({{ site.repository }}/issues/1607))
+- Update coveralls dependency to `~> 0.7.0` ([#1606]({{ site.repository }}/issues/1606))
+- Update rake dependency to `~> 10.1` ([#1603]({{ site.repository }}/issues/1603))
+- Clean up `site.rb` comments to be more concise/uniform ([#1616]({{ site.repository }}/issues/1616))
+- Use the master branch for the build badge in the readme ([#1636]({{ site.repository }}/issues/1636))
+- Refactor Site#render ([#1638]({{ site.repository }}/issues/1638))
+- Remove duplication in command line options ([#1637]({{ site.repository }}/issues/1637))
+- Add tests for all the coderay options ([#1543]({{ site.repository }}/issues/1543))
+- Improve some of the cucumber test code ([#1493]({{ site.repository }}/issues/1493))
+- Improve comparisons of timestamps by ignoring the seconds ([#1582]({{ site.repository }}/issues/1582))
+
+### Site Enhancements
+- Fix params for `JekyllImport::WordPress.process` arguments ([#1554]({{ site.repository }}/issues/1554))
+- Add `jekyll-suggested-tweet` to list of third-party plugins ([#1555]({{ site.repository }}/issues/1555))
+- Link to Liquid's docs for tags and filters ([#1553]({{ site.repository }}/issues/1553))
+- Add note about installing Xcode on the Mac in the Installation docs ([#1561]({{ site.repository }}/issues/1561))
+- Simplify/generalize pagination docs ([#1577]({{ site.repository }}/issues/1577))
+- Add documentation for the new data sources feature ([#1503]({{ site.repository }}/issues/1503))
+- Add more information on how to create generators ([#1590]({{ site.repository }}/issues/1590), [#1592]({{ site.repository }}/issues/1592))
+- Improve the instructions for mimicking GitHub Flavored Markdown
+ ([#1614]({{ site.repository }}/issues/1614))
+- Add `jekyll-import` warning note of missing dependencies ([#1626]({{ site.repository }}/issues/1626))
+- Fix grammar in the Usage section ([#1635]({{ site.repository }}/issues/1635))
+- Add documentation for the use of gems as plugins ([#1656]({{ site.repository }}/issues/1656))
+- Document the existence of a few additional plugins ([#1405]({{ site.repository }}/issues/1405))
+- Document that the `date_to_string` always returns a two digit day ([#1663]({{ site.repository }}/issues/1663))
+- Fix navigation in the "Working with Drafts" page ([#1667]({{ site.repository }}/issues/1667))
+- Fix an error with the data documentation ([#1691]({{ site.repository }}/issues/1691))
+
+## 1.2.1 / 2013-09-14
+
+### Minor Enhancements
+- Print better messages for detached server. Mute output on detach. ([#1518]({{ site.repository }}/issues/1518))
+- Disable reverse lookup when running `jekyll serve` ([#1363]({{ site.repository }}/issues/1363))
+- Upgrade RedCarpet dependency to `~> 2.3.0` ([#1515]({{ site.repository }}/issues/1515))
+- Upgrade to Liquid `>= 2.5.2, < 2.6` ([#1536]({{ site.repository }}/issues/1536))
+
+### Bug Fixes
+- Fix file discrepancy in gemspec ([#1522]({{ site.repository }}/issues/1522))
+- Force rendering of Include tag ([#1525]({{ site.repository }}/issues/1525))
+
+### Development Fixes
+- Add a rake task to generate a new release post ([#1404]({{ site.repository }}/issues/1404))
+- Mute LSI output in tests ([#1531]({{ site.repository }}/issues/1531))
+- Update contributor documentation ([#1537]({{ site.repository }}/issues/1537))
+
+### Site Enhancements
+- Fix a couple of validation errors on the site ([#1511]({{ site.repository }}/issues/1511))
+- Make navigation menus reusable ([#1507]({{ site.repository }}/issues/1507))
+- Fix link to History page from Release v1.2.0 notes post.
+- Fix markup in History file for command line options ([#1512]({{ site.repository }}/issues/1512))
+- Expand 1.2 release post title to 1.2.0 ([#1516]({{ site.repository }}/issues/1516))
+
+## 1.2.0 / 2013-09-06
+
+### Major Enhancements
+- Disable automatically-generated excerpts when `excerpt_separator` is `""`. ([#1386]({{ site.repository }}/issues/1386))
+- Add checking for URL conflicts when running `jekyll doctor` ([#1389]({{ site.repository }}/issues/1389))
+
+### Minor Enhancements
+- Catch and fix invalid `paginate` values ([#1390]({{ site.repository }}/issues/1390))
+- Remove superfluous `div.container` from the default html template for
+ `jekyll new` ([#1315]({{ site.repository }}/issues/1315))
+- Add `-D` short-form switch for the drafts option ([#1394]({{ site.repository }}/issues/1394))
+- Update the links in the site template for Twitter and GitHub ([#1400]({{ site.repository }}/issues/1400))
+- Update dummy email address to example.com domain ([#1408]({{ site.repository }}/issues/1408))
+- Update normalize.css to v2.1.2 and minify; add rake task to update
+ normalize.css with greater ease. ([#1430]({{ site.repository }}/issues/1430))
+- Add the ability to detach the server ran by `jekyll serve` from it's
+ controlling terminal ([#1443]({{ site.repository }}/issues/1443))
+- Improve permalink generation for URLs with special characters ([#944]({{ site.repository }}/issues/944))
+- Expose the current Jekyll version to posts and pages via a new
+ `jekyll.version` variable ([#1481]({{ site.repository }}/issues/1481))
+
+### Bug Fixes
+- Markdown extension matching matches only exact matches ([#1382]({{ site.repository }}/issues/1382))
+- Fixed NoMethodError when message passed to `Stevenson#message` is nil ([#1388]({{ site.repository }}/issues/1388))
+- Use binary mode when writing file ([#1364]({{ site.repository }}/issues/1364))
+- Fix 'undefined method `encoding` for "mailto"' errors w/ Ruby 1.8 and
+ Kramdown > 0.14.0 ([#1397]({{ site.repository }}/issues/1397))
+- Do not force the permalink to be a dir if it ends on .html ([#963]({{ site.repository }}/issues/963))
+- When a Liquid Exception is caught, show the full path rel. to site source ([#1415]({{ site.repository }}/issues/1415))
+- Properly read in the config options when serving the docs locally
+ ([#1444]({{ site.repository }}/issues/1444))
+- Fixed `--layouts` option for `build` and `serve` commands ([#1458]({{ site.repository }}/issues/1458))
+- Remove kramdown as a runtime dependency since it's optional ([#1498]({{ site.repository }}/issues/1498))
+- Provide proper error handling for invalid file names in the include
+ tag ([#1494]({{ site.repository }}/issues/1494))
+
+### Development Fixes
+- Remove redundant argument to
+ Jekyll::Commands::New#scaffold_post_content ([#1356]({{ site.repository }}/issues/1356))
+- Add new dependencies to the README ([#1360]({{ site.repository }}/issues/1360))
+- Fix link to contributing page in README ([#1424]({{ site.repository }}/issues/1424))
+- Update TomDoc in Pager#initialize to match params ([#1441]({{ site.repository }}/issues/1441))
+- Refactor `Site#cleanup` into `Jekyll::Site::Cleaner` class ([#1429]({{ site.repository }}/issues/1429))
+- Several other small minor refactorings ([#1341]({{ site.repository }}/issues/1341))
+- Ignore `_site` in jekyllrb.com deploy ([#1480]({{ site.repository }}/issues/1480))
+- Add Gem version and dependency badge to README ([#1497]({{ site.repository }}/issues/1497))
+
+### Site Enhancements
+- Add info about new releases ([#1353]({{ site.repository }}/issues/1353))
+- Update plugin list with jekyll-rss plugin ([#1354]({{ site.repository }}/issues/1354))
+- Update the site list page with Ruby's official site ([#1358]({{ site.repository }}/issues/1358))
+- Add `jekyll-ditaa` to list of third-party plugins ([#1370]({{ site.repository }}/issues/1370))
+- Add `postfiles` to list of third-party plugins ([#1373]({{ site.repository }}/issues/1373))
+- For internal links, use full path including trailing `/` ([#1411]({{ site.repository }}/issues/1411))
+- Use curly apostrophes in the docs ([#1419]({{ site.repository }}/issues/1419))
+- Update the docs for Redcarpet in Jekyll ([#1418]({{ site.repository }}/issues/1418))
+- Add `pluralize` and `reading_time` filters to docs ([#1439]({{ site.repository }}/issues/1439))
+- Fix markup for the Kramdown options ([#1445]({{ site.repository }}/issues/1445))
+- Fix typos in the History file ([#1454]({{ site.repository }}/issues/1454))
+- Add trailing slash to site's post URL ([#1462]({{ site.repository }}/issues/1462))
+- Clarify that `--config` will take multiple files ([#1474]({{ site.repository }}/issues/1474))
+- Fix docs/templates.md private gist example ([#1477]({{ site.repository }}/issues/1477))
+- Use `site.repository` for Jekyll's GitHub URL ([#1463]({{ site.repository }}/issues/1463))
+- Add `jekyll-pageless-redirects` to list of third-party plugins ([#1486]({{ site.repository }}/issues/1486))
+- Clarify that `date_to_xmlschema` returns an ISO 8601 string ([#1488]({{ site.repository }}/issues/1488))
+- Add `jekyll-good-include` to list of third-party plugins ([#1491]({{ site.repository }}/issues/1491))
+- XML escape the blog post title in our feed ([#1501]({{ site.repository }}/issues/1501))
+- Add `jekyll-toc-generator` to list of third-party plugins ([#1506]({{ site.repository }}/issues/1506))
+
+## 1.1.2 / 2013-07-25
+
+### Bug Fixes
+- Require Liquid 2.5.1 ([#1349]({{ site.repository }}/issues/1349))
+
+## 1.1.1 / 2013-07-24
+
+### Minor Enhancements
+- Remove superfluous `table` selector from main.css in `jekyll new` template ([#1328]({{ site.repository }}/issues/1328))
+- Abort with non-zero exit codes ([#1338]({{ site.repository }}/issues/1338))
+
+### Bug Fixes
+- Fix up the rendering of excerpts ([#1339]({{ site.repository }}/issues/1339))
+
+### Site Enhancements
+- Add Jekyll Image Tag to the plugins list ([#1306]({{ site.repository }}/issues/1306))
+- Remove erroneous statement that `site.pages` are sorted alphabetically.
+- Add info about the `_drafts` directory to the directory structure
+ docs ([#1320]({{ site.repository }}/issues/1320))
+- Improve the layout of the plugin listing by organizing it into
+ categories ([#1310]({{ site.repository }}/issues/1310))
+- Add generator-jekyllrb and grunt-jekyll to plugins page ([#1330]({{ site.repository }}/issues/1330))
+- Mention Kramdown as option for markdown parser on Extras page ([#1318]({{ site.repository }}/issues/1318))
+- Update Quick-Start page to include reminder that all requirements must be installed ([#1327]({{ site.repository }}/issues/1327))
+- Change filename in `include` example to an HTML file so as not to indicate that Jekyll
+ will automatically convert them. ([#1303]({{ site.repository }}/issues/1303))
+- Add an RSS feed for commits to Jekyll ([#1343]({{ site.repository }}/issues/1343))
+
+## 1.1.0 / 2013-07-14
+
+### Major Enhancements
+- Add `docs` subcommand to read Jekyll's docs when offline. ([#1046]({{ site.repository }}/issues/1046))
+- Support passing parameters to templates in `include` tag ([#1204]({{ site.repository }}/issues/1204))
+- Add support for Liquid tags to post excerpts ([#1302]({{ site.repository }}/issues/1302))
+
+### Minor Enhancements
+- Search the hierarchy of pagination path up to site root to determine template page for
+ pagination. ([#1198]({{ site.repository }}/issues/1198))
+- Add the ability to generate a new Jekyll site without a template ([#1171]({{ site.repository }}/issues/1171))
+- Use redcarpet as the default markdown engine in newly generated
+ sites ([#1245]({{ site.repository }}/issues/1245), [#1247]({{ site.repository }}/issues/1247))
+- Add `redcarpet` as a runtime dependency so `jekyll build` works out-of-the-box for new
+ sites. ([#1247]({{ site.repository }}/issues/1247))
+- In the generated site, remove files that will be replaced by a
+ directory ([#1118]({{ site.repository }}/issues/1118))
+- Fail loudly if a user-specified configuration file doesn't exist ([#1098]({{ site.repository }}/issues/1098))
+- Allow for all options for Kramdown HTML Converter ([#1201]({{ site.repository }}/issues/1201))
+
+### Bug Fixes
+- Fix pagination in subdirectories. ([#1198]({{ site.repository }}/issues/1198))
+- Fix an issue with directories and permalinks that have a plus sign
+ (+) in them ([#1215]({{ site.repository }}/issues/1215))
+- Provide better error reporting when generating sites ([#1253]({{ site.repository }}/issues/1253))
+- Latest posts first in non-LSI `related_posts` ([#1271]({{ site.repository }}/issues/1271))
+
+### Development Fixes
+- Merge the theme and layout cucumber steps into one step ([#1151]({{ site.repository }}/issues/1151))
+- Restrict activesupport dependency to pre-4.0.0 to maintain compatibility with `<= 1.9.2`
+- Include/exclude deprecation handling simplification ([#1284]({{ site.repository }}/issues/1284))
+- Convert README to Markdown. ([#1267]({{ site.repository }}/issues/1267))
+- Refactor Jekyll::Site ([#1144]({{ site.repository }}/issues/1144))
+
+### Site Enhancements
+- Add "News" section for release notes, along with an RSS feed ([#1093]({{ site.repository }}/issues/1093), [#1285]({{ site.repository }}/issues/1285), [#1286]({{ site.repository }}/issues/1286))
+- Add "History" page.
+- Restructured docs sections to include "Meta" section.
+- Add message to "Templates" page that specifies that Python must be installed in order
+ to use Pygments. ([#1182]({{ site.repository }}/issues/1182))
+- Update link to the official Maruku repo ([#1175]({{ site.repository }}/issues/1175))
+- Add documentation about `paginate_path` to "Templates" page in docs ([#1129]({{ site.repository }}/issues/1129))
+- Give the quick-start guide its own page ([#1191]({{ site.repository }}/issues/1191))
+- Update ProTip on Installation page in docs to point to all the info about Pygments and
+ the 'highlight' tag. ([#1196]({{ site.repository }}/issues/1196))
+- Run `site/img` through ImageOptim (thanks [@qrush](https://github.com/qrush)!) ([#1208]({{ site.repository }}/issues/1208))
+- Added Jade Converter to `site/docs/plugins` ([#1210]({{ site.repository }}/issues/1210))
+- Fix location of docs pages in Contributing pages ([#1214]({{ site.repository }}/issues/1214))
+- Add ReadInXMinutes plugin to the plugin list ([#1222]({{ site.repository }}/issues/1222))
+- Remove plugins from the plugin list that have equivalents in Jekyll
+ proper ([#1223]({{ site.repository }}/issues/1223))
+- Add jekyll-assets to the plugin list ([#1225]({{ site.repository }}/issues/1225))
+- Add jekyll-pandoc-mulitple-formats to the plugin list ([#1229]({{ site.repository }}/issues/1229))
+- Remove dead link to "Using Git to maintain your blog" ([#1227]({{ site.repository }}/issues/1227))
+- Tidy up the third-party plugins listing ([#1228]({{ site.repository }}/issues/1228))
+- Update contributor information ([#1192]({{ site.repository }}/issues/1192))
+- Update URL of article about Blogger migration ([#1242]({{ site.repository }}/issues/1242))
+- Specify that RedCarpet is the default for new Jekyll sites on Quickstart page ([#1247]({{ site.repository }}/issues/1247))
+- Added site.pages to Variables page in docs ([#1251]({{ site.repository }}/issues/1251))
+- Add Youku and Tudou Embed link on Plugins page. ([#1250]({{ site.repository }}/issues/1250))
+- Add note that `gist` tag supports private gists. ([#1248]({{ site.repository }}/issues/1248))
+- Add `jekyll-timeago` to list of third-party plugins. ([#1260]({{ site.repository }}/issues/1260))
+- Add `jekyll-swfobject` to list of third-party plugins. ([#1263]({{ site.repository }}/issues/1263))
+- Add `jekyll-picture-tag` to list of third-party plugins. ([#1280]({{ site.repository }}/issues/1280))
+- Update the GitHub Pages documentation regarding relative URLs
+ ([#1291]({{ site.repository }}/issues/1291))
+- Update the S3 deployment documentation ([#1294]({{ site.repository }}/issues/1294))
+- Add suggestion for Xcode CLT install to troubleshooting page in docs ([#1296]({{ site.repository }}/issues/1296))
+- Add 'Working with drafts' page to docs ([#1289]({{ site.repository }}/issues/1289))
+- Add information about time zones to the documentation for a page's
+ date ([#1304]({{ site.repository }}/issues/1304))
+
+## 1.0.3 / 2013-06-07
+
+### Minor Enhancements
+- Add support to gist tag for private gists. ([#1189]({{ site.repository }}/issues/1189))
+- Fail loudly when MaRuKu errors out ([#1190]({{ site.repository }}/issues/1190))
+- Move the building of related posts into their own class ([#1057]({{ site.repository }}/issues/1057))
+- Removed trailing spaces in several places throughout the code ([#1116]({{ site.repository }}/issues/1116))
+- Add a `--force` option to `jekyll new` ([#1115]({{ site.repository }}/issues/1115))
+- Convert IDs in the site template to classes ([#1170]({{ site.repository }}/issues/1170))
+
+### Bug Fixes
+- Fix typo in Stevenson constant "ERROR". ([#1166]({{ site.repository }}/issues/1166))
+- Rename Jekyll::Logger to Jekyll::Stevenson to fix inheritance issue ([#1106]({{ site.repository }}/issues/1106))
+- Exit with a non-zero exit code when dealing with a Liquid error ([#1121]({{ site.repository }}/issues/1121))
+- Make the `exclude` and `include` options backwards compatible with
+ versions of Jekyll prior to 1.0 ([#1114]({{ site.repository }}/issues/1114))
+- Fix pagination on Windows ([#1063]({{ site.repository }}/issues/1063))
+- Fix the application of Pygments' Generic Output style to Go code
+ ([#1156]({{ site.repository }}/issues/1156))
+
+### Site Enhancements
+- Add a Pro Tip to docs about front matter variables being optional ([#1147]({{ site.repository }}/issues/1147))
+- Add changelog to site as History page in /docs/ ([#1065]({{ site.repository }}/issues/1065))
+- Add note to Upgrading page about new config options in 1.0.x ([#1146]({{ site.repository }}/issues/1146))
+- Documentation for `date_to_rfc822` and `uri_escape` ([#1142]({{ site.repository }}/issues/1142))
+- Documentation highlight boxes shouldn't show scrollbars if not necessary ([#1123]({{ site.repository }}/issues/1123))
+- Add link to jekyll-minibundle in the doc's plugins list ([#1035]({{ site.repository }}/issues/1035))
+- Quick patch for importers documentation
+- Fix prefix for WordpressDotCom importer in docs ([#1107]({{ site.repository }}/issues/1107))
+- Add jekyll-contentblocks plugin to docs ([#1068]({{ site.repository }}/issues/1068))
+- Make code bits in notes look more natural, more readable ([#1089]({{ site.repository }}/issues/1089))
+- Fix logic for `relative_permalinks` instructions on Upgrading page ([#1101]({{ site.repository }}/issues/1101))
+- Add docs for post excerpt ([#1072]({{ site.repository }}/issues/1072))
+- Add docs for gist tag ([#1072]({{ site.repository }}/issues/1072))
+- Add docs indicating that Pygments does not need to be installed
+ separately ([#1099]({{ site.repository }}/issues/1099), [#1119]({{ site.repository }}/issues/1119))
+- Update the migrator docs to be current ([#1136]({{ site.repository }}/issues/1136))
+- Add the Jekyll Gallery Plugin to the plugin list ([#1143]({{ site.repository }}/issues/1143))
+
+### Development Fixes
+- Use Jekyll.logger instead of Jekyll::Stevenson to log things ([#1149]({{ site.repository }}/issues/1149))
+- Fix pesky Cucumber infinite loop ([#1139]({{ site.repository }}/issues/1139))
+- Do not write posts with timezones in Cucumber tests ([#1124]({{ site.repository }}/issues/1124))
+- Use ISO formatted dates in Cucumber features ([#1150]({{ site.repository }}/issues/1150))
+
+## 1.0.2 / 2013-05-12
+
+### Major Enhancements
+- Add `jekyll doctor` command to check site for any known compatibility problems ([#1081]({{ site.repository }}/issues/1081))
+- Backwards-compatibilize relative permalinks ([#1081]({{ site.repository }}/issues/1081))
+
+### Minor Enhancements
+- Add a `data-lang="<lang>"` attribute to Redcarpet code blocks ([#1066]({{ site.repository }}/issues/1066))
+- Deprecate old config `server_port`, match to `port` if `port` isn't set ([#1084]({{ site.repository }}/issues/1084))
+- Update pygments.rb version to 0.5.0 ([#1061]({{ site.repository }}/issues/1061))
+- Update Kramdown version to 1.0.2 ([#1067]({{ site.repository }}/issues/1067))
+
+### Bug Fixes
+- Fix issue when categories are numbers ([#1078]({{ site.repository }}/issues/1078))
+- Catching that Redcarpet gem isn't installed ([#1059]({{ site.repository }}/issues/1059))
+
+### Site Enhancements
+- Add documentation about `relative_permalinks` ([#1081]({{ site.repository }}/issues/1081))
+- Remove pygments-installation instructions, as pygments.rb is bundled with it ([#1079]({{ site.repository }}/issues/1079))
+- Move pages to be Pages for realz ([#985]({{ site.repository }}/issues/985))
+- Updated links to Liquid documentation ([#1073]({{ site.repository }}/issues/1073))
+
+## 1.0.1 / 2013-05-08
+
+### Minor Enhancements
+- Do not force use of toc_token when using generate_tok in RDiscount ([#1048]({{ site.repository }}/issues/1048))
+- Add newer `language-` class name prefix to code blocks ([#1037]({{ site.repository }}/issues/1037))
+- Commander error message now preferred over process abort with incorrect args ([#1040]({{ site.repository }}/issues/1040))
+
+### Bug Fixes
+- Make Redcarpet respect the pygments configuration option ([#1053]({{ site.repository }}/issues/1053))
+- Fix the index build with LSI ([#1045]({{ site.repository }}/issues/1045))
+- Don't print deprecation warning when no arguments are specified. ([#1041]({{ site.repository }}/issues/1041))
+- Add missing `</div>` to site template used by `new` subcommand, fixed typos in code ([#1032]({{ site.repository }}/issues/1032))
+
+### Site Enhancements
+- Changed https to http in the GitHub Pages link ([#1051]({{ site.repository }}/issues/1051))
+- Remove CSS cruft, fix typos, fix HTML errors ([#1028]({{ site.repository }}/issues/1028))
+- Removing manual install of Pip and Distribute ([#1025]({{ site.repository }}/issues/1025))
+- Updated URL for Markdown references plugin ([#1022]({{ site.repository }}/issues/1022))
+
+### Development Fixes
+- Markdownify history file ([#1027]({{ site.repository }}/issues/1027))
+- Update links on README to point to new jekyllrb.com ([#1018]({{ site.repository }}/issues/1018))
+
+## 1.0.0 / 2013-05-06
+
+### Major Enhancements
+- Add `jekyll new` subcommand: generate a jekyll scaffold ([#764]({{ site.repository }}/issues/764))
+- Refactored jekyll commands into subcommands: build, serve, and migrate. ([#690]({{ site.repository }}/issues/690))
+- Removed importers/migrators from main project, migrated to jekyll-import sub-gem ([#793]({{ site.repository }}/issues/793))
+- Added ability to render drafts in `_drafts` folder via command line ([#833]({{ site.repository }}/issues/833))
+- Add ordinal date permalink style (/:categories/:year/:y_day/:title.html) ([#928]({{ site.repository }}/issues/928))
+
+### Minor Enhancements
+- Site template HTML5-ified ([#964]({{ site.repository }}/issues/964))
+- Use post's directory path when matching for the post_url tag ([#998]({{ site.repository }}/issues/998))
+- Loosen dependency on Pygments so it's only required when it's needed ([#1015]({{ site.repository }}/issues/1015))
+- Parse strings into Time objects for date-related Liquid filters ([#1014]({{ site.repository }}/issues/1014))
+- Tell the user if there is no subcommand specified ([#1008]({{ site.repository }}/issues/1008))
+- Freak out if the destination of `jekyll new` exists and is non-empty ([#981]({{ site.repository }}/issues/981))
+- Add `timezone` configuration option for compilation ([#957]({{ site.repository }}/issues/957))
+- Add deprecation messages for pre-1.0 CLI options ([#959]({{ site.repository }}/issues/959))
+- Refactor and colorize logging ([#959]({{ site.repository }}/issues/959))
+- Refactor Markdown parsing ([#955]({{ site.repository }}/issues/955))
+- Added application/vnd.apple.pkpass to mime.types served by WEBrick ([#907]({{ site.repository }}/issues/907))
+- Move template site to default markdown renderer ([#961]({{ site.repository }}/issues/961))
+- Expose new attribute to Liquid via `page`: `page.path` ([#951]({{ site.repository }}/issues/951))
+- Accept multiple config files from command line ([#945]({{ site.repository }}/issues/945))
+- Add page variable to liquid custom tags and blocks ([#413]({{ site.repository }}/issues/413))
+- Add paginator.previous_page_path and paginator.next_page_path ([#942]({{ site.repository }}/issues/942))
+- Backwards compatibility for 'auto' ([#821]({{ site.repository }}/issues/821), [#934]({{ site.repository }}/issues/934))
+- Added date_to_rfc822 used on RSS feeds ([#892]({{ site.repository }}/issues/892))
+- Upgrade version of pygments.rb to 0.4.2 ([#927]({{ site.repository }}/issues/927))
+- Added short month (e.g. "Sep") to permalink style options for posts ([#890]({{ site.repository }}/issues/890))
+- Expose site.baseurl to Liquid templates ([#869]({{ site.repository }}/issues/869))
+- Adds excerpt attribute to posts which contains first paragraph of content ([#837]({{ site.repository }}/issues/837))
+- Accept custom configuration file via CLI ([#863]({{ site.repository }}/issues/863))
+- Load in GitHub Pages MIME Types on `jekyll serve` ([#847]({{ site.repository }}/issues/847), [#871]({{ site.repository }}/issues/871))
+- Improve debugability of error message for a malformed highlight tag ([#785]({{ site.repository }}/issues/785))
+- Allow symlinked files in unsafe mode ([#824]({{ site.repository }}/issues/824))
+- Add 'gist' Liquid tag to core ([#822]({{ site.repository }}/issues/822), [#861]({{ site.repository }}/issues/861))
+- New format of Jekyll output ([#795]({{ site.repository }}/issues/795))
+- Reinstate `--limit_posts` and `--future` switches ([#788]({{ site.repository }}/issues/788))
+- Remove ambiguity from command descriptions ([#815]({{ site.repository }}/issues/815))
+- Fix SafeYAML Warnings ([#807]({{ site.repository }}/issues/807))
+- Relaxed Kramdown version to 0.14 ([#808]({{ site.repository }}/issues/808))
+- Aliased `jekyll server` to `jekyll serve`. ([#792]({{ site.repository }}/issues/792))
+- Updated gem versions for Kramdown, Rake, Shoulda, Cucumber, and RedCarpet. ([#744]({{ site.repository }}/issues/744))
+- Refactored jekyll subcommands into Jekyll::Commands submodule, which now contains them ([#768]({{ site.repository }}/issues/768))
+- Rescue from import errors in Wordpress.com migrator ([#671]({{ site.repository }}/issues/671))
+- Massively accelerate LSI performance ([#664]({{ site.repository }}/issues/664))
+- Truncate post slugs when importing from Tumblr ([#496]({{ site.repository }}/issues/496))
+- Add glob support to include, exclude option ([#743]({{ site.repository }}/issues/743))
+- Layout of Page or Post defaults to 'page' or 'post', respectively ([#580]({{ site.repository }}/issues/580))
+ REPEALED by ([#977]({{ site.repository }}/issues/977))
+- "Keep files" feature ([#685]({{ site.repository }}/issues/685))
+- Output full path & name for files that don't parse ([#745]({{ site.repository }}/issues/745))
+- Add source and destination directory protection ([#535]({{ site.repository }}/issues/535))
+- Better YAML error message ([#718]({{ site.repository }}/issues/718))
+- Bug Fixes
+- Paginate in subdirectories properly ([#1016]({{ site.repository }}/issues/1016))
+- Ensure post and page URLs have a leading slash ([#992]({{ site.repository }}/issues/992))
+- Catch all exceptions, not just StandardError descendents ([#1007]({{ site.repository }}/issues/1007))
+- Bullet-proof limit_posts option ([#1004]({{ site.repository }}/issues/1004))
+- Read in YAML as UTF-8 to accept non-ASCII chars ([#836]({{ site.repository }}/issues/836))
+- Fix the CLI option `--plugins` to actually accept dirs and files ([#993]({{ site.repository }}/issues/993))
+- Allow 'excerpt' in YAML Front-Matter to override the extracted excerpt ([#946]({{ site.repository }}/issues/946))
+- Fix cascade problem with site.baseurl, site.port and site.host. ([#935]({{ site.repository }}/issues/935))
+- Filter out directories with valid post names ([#875]({{ site.repository }}/issues/875))
+- Fix symlinked static files not being correctly built in unsafe mode ([#909]({{ site.repository }}/issues/909))
+- Fix integration with directory_watcher 1.4.x ([#916]({{ site.repository }}/issues/916))
+- Accepting strings as arguments to jekyll-import command ([#910]({{ site.repository }}/issues/910))
+- Force usage of older directory_watcher gem as 1.5 is broken ([#883]({{ site.repository }}/issues/883))
+- Ensure all Post categories are downcase ([#842]({{ site.repository }}/issues/842), [#872]({{ site.repository }}/issues/872))
+- Force encoding of the rdiscount TOC to UTF8 to avoid conversion errors ([#555]({{ site.repository }}/issues/555))
+- Patch for multibyte URI problem with jekyll serve ([#723]({{ site.repository }}/issues/723))
+- Order plugin execution by priority ([#864]({{ site.repository }}/issues/864))
+- Fixed Page#dir and Page#url for edge cases ([#536]({{ site.repository }}/issues/536))
+- Fix broken post_url with posts with a time in their YAML Front-Matter ([#831]({{ site.repository }}/issues/831))
+- Look for plugins under the source directory ([#654]({{ site.repository }}/issues/654))
+- Tumblr Migrator: finds `_posts` dir correctly, fixes truncation of long
+ post names ([#775]({{ site.repository }}/issues/775))
+- Force Categories to be Strings ([#767]({{ site.repository }}/issues/767))
+- Safe YAML plugin to prevent vulnerability ([#777]({{ site.repository }}/issues/777))
+- Add SVG support to Jekyll/WEBrick. ([#407]({{ site.repository }}/issues/407), [#406]({{ site.repository }}/issues/406))
+- Prevent custom destination from causing continuous regen on watch ([#528]({{ site.repository }}/issues/528), [#820]({{ site.repository }}/issues/820), [#862]({{ site.repository }}/issues/862))
+
+### Site Enhancements
+- Responsify ([#860]({{ site.repository }}/issues/860))
+- Fix spelling, punctuation and phrasal errors ([#989]({{ site.repository }}/issues/989))
+- Update quickstart instructions with `new` command ([#966]({{ site.repository }}/issues/966))
+- Add docs for page.excerpt ([#956]({{ site.repository }}/issues/956))
+- Add docs for page.path ([#951]({{ site.repository }}/issues/951))
+- Clean up site docs to prepare for 1.0 release ([#918]({{ site.repository }}/issues/918))
+- Bring site into master branch with better preview/deploy ([#709]({{ site.repository }}/issues/709))
+- Redesigned site ([#583]({{ site.repository }}/issues/583))
+
+### Development Fixes
+- Exclude Cucumber 1.2.4, which causes tests to fail in 1.9.2 ([#938]({{ site.repository }}/issues/938))
+- Added "features:html" rake task for debugging purposes, cleaned up
+ cucumber profiles ([#832]({{ site.repository }}/issues/832))
+- Explicitly require HTTPS rubygems source in Gemfile ([#826]({{ site.repository }}/issues/826))
+- Changed Ruby version for development to 1.9.3-p374 from p362 ([#801]({{ site.repository }}/issues/801))
+- Including a link to the GitHub Ruby style guide in CONTRIBUTING.md ([#806]({{ site.repository }}/issues/806))
+- Added script/bootstrap ([#776]({{ site.repository }}/issues/776))
+- Running Simplecov under 2 conditions: ENV(COVERAGE)=true and with Ruby version
+ of greater than 1.9 ([#771]({{ site.repository }}/issues/771))
+- Switch to Simplecov for coverage report ([#765]({{ site.repository }}/issues/765))
+
+## 0.12.1 / 2013-02-19
+### Minor Enhancements
+- Update Kramdown version to 0.14.1 ([#744]({{ site.repository }}/issues/744))
+- Test Enhancements
+- Update Rake version to 10.0.3 ([#744]({{ site.repository }}/issues/744))
+- Update Shoulda version to 3.3.2 ([#744]({{ site.repository }}/issues/744))
+- Update Redcarpet version to 2.2.2 ([#744]({{ site.repository }}/issues/744))
+
+## 0.12.0 / 2012-12-22
+### Minor Enhancements
+- Add ability to explicitly specify included files ([#261]({{ site.repository }}/issues/261))
+- Add --default-mimetype option ([#279]({{ site.repository }}/issues/279))
+- Allow setting of RedCloth options ([#284]({{ site.repository }}/issues/284))
+- Add post_url Liquid tag for internal post linking ([#369]({{ site.repository }}/issues/369))
+- Allow multiple plugin dirs to be specified ([#438]({{ site.repository }}/issues/438))
+- Inline TOC token support for RDiscount ([#333]({{ site.repository }}/issues/333))
+- Add the option to specify the paginated url format ([#342]({{ site.repository }}/issues/342))
+- Swap out albino for pygments.rb ([#569]({{ site.repository }}/issues/569))
+- Support Redcarpet 2 and fenced code blocks ([#619]({{ site.repository }}/issues/619))
+- Better reporting of Liquid errors ([#624]({{ site.repository }}/issues/624))
+- Bug Fixes
+- Allow some special characters in highlight names
+- URL escape category names in URL generation ([#360]({{ site.repository }}/issues/360))
+- Fix error with limit_posts ([#442]({{ site.repository }}/issues/442))
+- Properly select dotfile during directory scan ([#363]({{ site.repository }}/issues/363), [#431]({{ site.repository }}/issues/431), [#377]({{ site.repository }}/issues/377))
+- Allow setting of Kramdown smart_quotes ([#482]({{ site.repository }}/issues/482))
+- Ensure front-matter is at start of file ([#562]({{ site.repository }}/issues/562))
+
+## 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]({{ site.repository }}/issues/409))
+- Update dependencies
+
+## 0.11.0 / 2011-07-10
+### Major Enhancements
+- Add command line importer functionality ([#253]({{ site.repository }}/issues/253))
+- Add Redcarpet Markdown support ([#318]({{ site.repository }}/issues/318))
+- Make markdown/textile extensions configurable ([#312]({{ site.repository }}/issues/312))
+- Add `markdownify` filter
+
+### Minor Enhancements
+- Switch to Albino gem
+- Bundler support
+- Use English library to avoid hoops ([#292]({{ site.repository }}/issues/292))
+- Add Posterous importer ([#254]({{ site.repository }}/issues/254))
+- Fixes for Wordpress importer ([#274]({{ site.repository }}/issues/274), [#252]({{ site.repository }}/issues/252), [#271]({{ site.repository }}/issues/271))
+- Better error message for invalid post date ([#291]({{ site.repository }}/issues/291))
+- Print formatted fatal exceptions to stdout on build failure
+- Add Tumblr importer ([#323]({{ site.repository }}/issues/323))
+- Add Enki importer ([#320]({{ site.repository }}/issues/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]({{ site.repository }}/issues/245))
+- Complain about YAML and Liquid errors ([#249]({{ site.repository }}/issues/249))
+- Remove orphaned files during regeneration ([#247]({{ site.repository }}/issues/247))
+- Add Marley migrator ([#28]({{ site.repository }}/issues/28))
+
+## 0.8.0 / 2010-11-22
+### Minor Enhancements
+- Add wordpress.com importer ([#207]({{ site.repository }}/issues/207))
+- Add --limit-posts cli option ([#212]({{ site.repository }}/issues/212))
+- Add uri_escape filter ([#234]({{ site.repository }}/issues/234))
+- Add --base-url cli option ([#235]({{ site.repository }}/issues/235))
+- Improve MT migrator ([#238]({{ site.repository }}/issues/238))
+- Add kramdown support ([#239]({{ site.repository }}/issues/239))
+- Bug Fixes
+- Fixed filename basename generation ([#208]({{ site.repository }}/issues/208))
+- Set mode to UTF8 on Sequel connections ([#237]({{ site.repository }}/issues/237))
+- Prevent `_includes` dir from being a symlink
+
+## 0.7.0 / 2010-08-24
+### Minor Enhancements
+- Add support for rdiscount extensions ([#173]({{ site.repository }}/issues/173))
+- Bug Fixes
+- Highlight should not be able to render local files
+- The site configuration may not always provide a 'time' setting ([#184]({{ site.repository }}/issues/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]({{ site.repository }}/issues/183))
+- Expand source, destination, and plugin paths ([#180]({{ site.repository }}/issues/180))
+- Fix page.url to include full relative path ([#181]({{ site.repository }}/issues/181))
+
+## 0.6.1 / 2010-06-24
+- Bug Fixes
+- Fix Markdown Pygments prefix and suffix ([#178]({{ site.repository }}/issues/178))
+
+## 0.6.0 / 2010-06-23
+### Major Enhancements
+- Proper plugin system ([#19]({{ site.repository }}/issues/19), [#100]({{ site.repository }}/issues/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]({{ site.repository }}/issues/57))
+
+### Minor Enhancements
+- Inclusion/exclusion of future dated posts ([#59]({{ site.repository }}/issues/59))
+- Generation for a specific time ([#59]({{ site.repository }}/issues/59))
+- Allocate site.time on render not per site_payload invocation ([#59]({{ site.repository }}/issues/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]({{ site.repository }}/issues/142))
+- Allow arbitrary options to Pygments ([#31]({{ site.repository }}/issues/31))
+- Allow URL to be set via command line option ([#147]({{ site.repository }}/issues/147))
+- Bug Fixes
+- Render highlighted code for non markdown/textile pages ([#116]({{ site.repository }}/issues/116))
+- Fix highlighting on Ruby 1.9 ([#65]({{ site.repository }}/issues/65))
+- Fix extension munging when pretty permalinks are enabled ([#64]({{ site.repository }}/issues/64))
+- Stop sorting categories ([#33]({{ site.repository }}/issues/33))
+- Preserve generated attributes over front matter ([#119]({{ site.repository }}/issues/119))
+- Fix source directory binding using Dir.pwd ([#75]({{ site.repository }}/issues/75))
+
+## 0.5.7 / 2010-01-12
+### Minor Enhancements
+- Allow overriding of post date in the front matter ([#62]({{ site.repository }}/issues/62), [#38]({{ site.repository }}/issues/38))
+- Bug Fixes
+- Categories isn't always an array ([#73]({{ site.repository }}/issues/73))
+- Empty tags causes error in read_posts ([#84]({{ site.repository }}/issues/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]({{ site.repository }}/issues/92))
+- Don't break on triple dashes in yaml frontmatter ([#93]({{ site.repository }}/issues/93))
+
+### Minor Enhancements
+- Allow .mkd as markdown extension
+- Use $stdout/err instead of constants ([#99]({{ site.repository }}/issues/99))
+- Properly wrap code blocks ([#91]({{ site.repository }}/issues/91))
+- Add javascript mime type for webrick ([#98]({{ site.repository }}/issues/98))
+
+## 0.5.5 / 2010-01-08
+- Bug Fixes
+- Fix pagination % 0 bug ([#78]({{ site.repository }}/issues/78))
+- Ensure all posts are processed first ([#71]({{ site.repository }}/issues/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
+ ([@jeffrydegrande](https://github.com/jeffrydegrande))
+
+## 0.5.2 / 2009-06-24
+- Enhancements
+- Added --paginate option to the executable along with a paginator object
+ for the payload ([@calavera](https://github.com/calavera))
+- Upgraded RedCloth to 4.2.1, which makes `<notextile>` tags work once
+ again.
+- Configuration options set in config.yml are now available through the
+ site payload ([@vilcans](https://github.com/vilcans))
+- Posts can now have an empty YAML front matter or none at all
+ ([@bahuvrihi](https://github.com/bahuvrihi))
+- Bug Fixes
+- Fixing Ruby 1.9 issue that requires to_s on the err object
+ ([@Chrononaut](https://github.com/Chrononaut))
+- Fixes for pagination and ordering posts on the same day ([@ujh](https://github.com/ujh))
+- Made pages respect permalinks style and permalinks in yml front matter
+ ([@eugenebolshakov](https://github.com/eugenebolshakov))
+- Index.html file should always have index.html permalink
+ ([@eugenebolshakov](https://github.com/eugenebolshakov))
+- Added trailing slash to pretty permalink style so Apache is happy
+ ([@eugenebolshakov](https://github.com/eugenebolshakov))
+- Bad markdown processor in config fails sooner and with better message
+ ([@gcnovus](https://github.com/gcnovus))
+- Allow CRLFs in yaml frontmatter ([@juretta](https://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 ([@pantulis](https://github.com/pantulis), [@tomo](https://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 ([@duritong](https://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 ([@henrik](https://github.com/henrik))
+- Worked around RDiscount bug that prevents Markdown from getting parsed
+ after highlight ([@henrik](https://github.com/henrik))
+- CGI escaped post titles ([@Chrononaut](https://github.com/Chrononaut))
+
+## 0.5.0 / 2009-04-07
+### Minor Enhancements
+- Ability to set post categories via YAML ([@qrush](https://github.com/qrush))
+- Ability to set prevent a post from publishing via YAML ([@qrush](https://github.com/qrush))
+- Add textilize filter ([@willcodeforfoo](https://github.com/willcodeforfoo))
+- Add 'pretty' permalink style for wordpress-like urls ([@dysinger](https://github.com/dysinger))
+- Made it possible to enter categories from YAML as an array ([@Chrononaut](https://github.com/Chrononaut))
+- Ignore Emacs autosave files ([@Chrononaut](https://github.com/Chrononaut))
+- Bug Fixes
+- Use block syntax of popen4 to ensure that subprocesses are properly disposed ([@jqr](https://github.com/jqr))
+- Close open4 streams to prevent zombies ([@rtomayko](https://github.com/rtomayko))
+- Only query required fields from the WP Database ([@ariejan](https://github.com/ariejan))
+- Prevent `_posts` from being copied to the destination directory ([@bdimcheff](https://github.com/bdimcheff))
+- Refactors
+- Factored the filtering code into a method ([@Chrononaut](https://github.com/Chrononaut))
+- Fix tests and convert to Shoulda ([@qrush](https://github.com/qrush), [@technicalpickles](https://github.com/technicalpickles))
+- Add Cucumber acceptance test suite ([@qrush](https://github.com/qrush), [@technicalpickles](https://github.com/technicalpickles))
+
+## 0.4.1
+### Minor Enhancements
+- Changed date format on wordpress converter (zeropadding) ([@dysinger](https://github.com/dysinger))
+- Bug Fixes
+- Add jekyll binary as executable to gemspec ([@dysinger](https://github.com/dysinger))
+
+## 0.4.0 / 2009-02-03
+### Major Enhancements
+- Switch to Jeweler for packaging tasks
+
+### Minor Enhancements
+- Type importer ([@codeslinger](https://github.com/codeslinger))
+- site.topics accessor ([@baz](https://github.com/baz))
+- Add `array_to_sentence_string` filter ([@mchung](https://github.com/mchung))
+- Add a converter for textpattern ([@PerfectlyNormal](https://github.com/PerfectlyNormal))
+- Add a working Mephisto / MySQL converter ([@ivey](https://github.com/ivey))
+- Allowing .htaccess files to be copied over into the generated site ([@briandoll](https://github.com/briandoll))
+- Add option to not put file date in permalink URL ([@mreid](https://github.com/mreid))
+- Add line number capabilities to highlight blocks ([@jcon](https://github.com/jcon))
+- Bug Fixes
+- Fix permalink behavior ([@cavalle](https://github.com/cavalle))
+- Fixed an issue with pygments, markdown, and newlines ([@zpinter](https://github.com/zpinter))
+- Ampersands need to be escaped ([@pufuwozu](https://github.com/pufuwozu), [@ap](https://github.com/ap))
+- Test and fix the site.categories hash ([@zzot](https://github.com/zzot))
+- Fix site payload available to files ([@matrix9180](https://github.com/matrix9180))
+
+## 0.3.0 / 2008-12-24
+### Major Enhancements
+- Added --server option to start a simple WEBrick server on destination
+ directory ([@johnreilly](https://github.com/johnreilly) and [@mchung](https://github.com/mchung))
+
+### Minor Enhancements
+- Added post categories based on directories containing `_posts` ([@mreid](https://github.com/mreid))
+- Added post topics based on directories underneath `_posts`
+- Added new date filter that shows the full month name ([@mreid](https://github.com/mreid))
+- Merge Post's YAML front matter into its to_liquid payload ([@remi](https://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 ([@mreid](https://github.com/mreid))
+- Fix bug that meant page data (such as the date) was not available in
+ templates ([@mreid](https://github.com/mreid))
+- Properly reject directories in `_layouts`
+
+## 0.2.1 / 2008-12-15
+- Major Changes
+- Use Maruku (pure Ruby) for Markdown by default ([@mreid](https://github.com/mreid))
+- Allow use of RDiscount with --rdiscount flag
+
+### Minor Enhancements
+- Don't load directory_watcher unless it's needed ([@pjhyett](https://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 {% raw %}`{% include x.textile %}`{% endraw %}
+
+## 0.1.5 / 2008-12-12
+### Major Enhancements
+- 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 ([@JackDanger](https://github.com/JackDanger))
+- Bug Fixes
+- Prevent Jekyll from picking up the output directory as a source ([@JackDanger](https://github.com/JackDanger))
+- Skip `related_posts` when there is only one post ([@JackDanger](https://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 ([@vanpelt](https://github.com/vanpelt))
+- Mephisto and CSV converters ([@vanpelt](https://github.com/vanpelt))
+- Code hilighting ([@vanpelt](https://github.com/vanpelt))
+- Autobuild
+- Bug Fixes
+- Accept both \r\n and \n in YAML header ([@vanpelt](https://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. {% raw %}`{{ page.url }}`{% endraw %}
+
+## 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!
diff --git a/site/docs/index.md b/site/docs/index.md
new file mode 100644
index 0000000..021a712
--- /dev/null
+++ b/site/docs/index.md
@@ -0,0 +1,52 @@
+---
+layout: docs
+title: Welcome
+next_section: quickstart
+permalink: /docs/home/
+---
+
+This site aims to be a comprehensive guide to Jekyll. We’ll cover topics such
+as getting your site up and running, creating and managing your content,
+customizing the way your site works and looks, deploying to various
+environments, and give you some advice on participating in the future
+development of Jekyll itself.
+
+## So what is Jekyll, exactly?
+
+Jekyll is a simple, blog-aware, static site generator. It takes a template
+directory containing raw text files in various formats, runs it through
+[Markdown](http://daringfireball.net/projects/markdown/) (or
+[Textile](http://textile.sitemonks.com/)) and
+[Liquid](http://wiki.shopify.com/Liquid)
+converters, and spits out a complete, ready-to-publish static website suitable
+for serving with your favorite web server. Jekyll also happens to be the engine
+behind [GitHub Pages](http://pages.github.com), which means you can use Jekyll
+to host your project’s page, blog, or website from GitHub’s servers **for
+free**.
+
+## ProTips™, Notes, and Warnings
+
+Throughout this guide there are a number of small-but-handy pieces of
+information that can make using Jekyll easier, more interesting, and less
+hazardous. Here’s what to look out for.
+
+<div class="note">
+ <h5>ProTips™ help you get more from Jekyll</h5>
+ <p>These are tips and tricks that will help you be a Jekyll wizard!</p>
+</div>
+
+<div class="note info">
+ <h5>Notes are handy pieces of information</h5>
+ <p>These are for the extra tidbits sometimes necessary to understand
+ Jekyll.</p>
+</div>
+
+<div class="note warning">
+ <h5>Warnings help you not blow things up</h5>
+ <p>Be aware of these messages if you wish to avoid certain death.</p>
+</div>
+
+If you come across anything along the way that we haven’t covered, or if you
+know of a tip you think others would find handy, please [file an
+issue]({{ site.repository }}/issues/new) and we’ll see about
+including it in this guide.
diff --git a/site/docs/installation.md b/site/docs/installation.md
new file mode 100644
index 0000000..8610443
--- /dev/null
+++ b/site/docs/installation.md
@@ -0,0 +1,76 @@
+---
+layout: docs
+title: Installation
+prev_section: quickstart
+next_section: usage
+permalink: /docs/installation/
+---
+
+Getting Jekyll installed and ready-to-go should only take a few minutes. If it
+ever becomes a pain in the ass, please [file an
+issue]({{ site.repository }}/issues/new) (or submit a pull request)
+describing the issue you encountered and how we might make the process easier.
+
+### Requirements
+
+Installing Jekyll is easy and straight-forward, but there are a few requirements
+you’ll need to make sure your system has before you start.
+
+- [Ruby](http://www.ruby-lang.org/en/downloads/)
+- [RubyGems](http://rubygems.org/pages/download)
+- Linux, Unix, or Mac OS X
+
+<div class="note info">
+ <h5>Running Jekyll on Windows</h5>
+ <p>
+ It is possible to get
+ <a href="http://www.madhur.co.in/blog/2011/09/01/runningjekyllwindows.html">
+ Jekyll running on Windows</a>, but the official documentation does not
+ support installation on Windows platforms.
+ </p>
+</div>
+
+## Install with RubyGems
+
+The best way to install Jekyll is via
+[RubyGems](http://docs.rubygems.org/read/chapter/3). At the terminal prompt,
+simply run the following command to install Jekyll:
+
+{% highlight bash %}
+$ gem install jekyll
+{% endhighlight %}
+
+All of Jekyll’s gem dependencies are automatically installed by the above
+command, so you won’t have to worry about them at all. If you have problems
+installing Jekyll, check out the [troubleshooting](../troubleshooting/) page or
+[report an issue]({{ site.repository }}/issues/new) so the Jekyll
+community can improve the experience for everyone.
+
+<div class="note info">
+ <h5>Installing Xcode Command-Line Tools</h5>
+ <p>
+ If you run into issues installing Jekyll's dependencies which make use of
+ native extensions and are using Mac OS X, you will need to install Xcode
+ and the Command-Line Tools it ships with. Download in
+ <code>Preferences → Downloads → Components</code>.
+ </p>
+</div>
+
+## Optional Extras
+
+There are a number of (optional) extra features that Jekyll supports that you
+may want to install, depending on how you plan to use Jekyll. These extras
+include LaTeX support, and the use of alternative content rendering engines.
+Check out [the extras page](../extras/) for more information.
+
+<div class="note">
+ <h5>ProTip™: Enable Syntax Highlighting</h5>
+ <p>
+ If you’re the kind of person who is using Jekyll, then chances are you’ll
+ want to enable syntax highlighting using Pygments. You should really
+ <a href="../templates/#code_snippet_highlighting">check out how to do
+ that</a> before you go any further.
+ </p>
+</div>
+
+Now that you’ve got everything installed, let’s get to work!
diff --git a/site/docs/migrations.md b/site/docs/migrations.md
new file mode 100644
index 0000000..27ecf71
--- /dev/null
+++ b/site/docs/migrations.md
@@ -0,0 +1,11 @@
+---
+layout: docs
+title: Blog migrations
+prev_section: datafiles
+next_section: templates
+permalink: /docs/migrations/
+---
+
+If you’re switching to Jekyll from another blogging system, Jekyll’s importers
+can help you with the move. To learn more about importing your site to Jekyll,
+visit our [`jekyll-import` docs site](http://import.jekyllrb.com).
diff --git a/site/docs/pages.md b/site/docs/pages.md
new file mode 100644
index 0000000..e7b837f
--- /dev/null
+++ b/site/docs/pages.md
@@ -0,0 +1,86 @@
+---
+layout: docs
+title: Creating pages
+prev_section: drafts
+next_section: variables
+permalink: /docs/pages/
+---
+
+In addition to [writing posts](../posts/), another thing you may want to do with
+your Jekyll site is create static pages. By taking advantage of the way Jekyll
+copies files and directories, this is easy to do.
+
+## Homepage
+
+Just about every web server configuration you come across will look for an HTML
+file called `index.html` (by convention) in the site's root folder and display
+that as the homepage. Unless the web server you’re using is configured to look
+for some different filename as the default, this file will turn into the
+homepage of your Jekyll-generated site.
+
+<div class="note">
+ <h5>ProTip™: Use layouts on your homepage</h5>
+ <p>
+ Any HTML file on your site can use layouts and/or includes, even the
+ homepage. Common content, like headers and footers, make excellent
+ candidates for extraction into a layout.
+ </p>
+</div>
+
+## Where additional pages live
+
+Where you put HTML files for pages depends on how you want the pages to work.
+There are two main ways of creating pages:
+
+- Place named HTML files for each page in your site's root folder.
+- Create a folder in the site's root for each page, and place an index.html file
+ in each page folder.
+
+Both methods work fine (and can be used in conjunction with each other),
+with the only real difference being the resulting URLs.
+
+### Named HTML files
+
+The simplest way of adding a page is just to add an HTML file in the root
+directory with a suitable name for the page you want to create. For a site with
+a homepage, an about page, and a contact page, here’s what the root directory
+and associated URLs might look like:
+
+{% highlight bash %}
+.
+|-- _config.yml
+|-- _includes/
+|-- _layouts/
+|-- _posts/
+|-- _site/
+|-- about.html # => http://example.com/about.html
+|-- index.html # => http://example.com/
+└── contact.html # => http://example.com/contact.html
+{% endhighlight %}
+
+### Named folders containing index HTML files
+
+There is nothing wrong with the above method, however some people like to keep
+their URLs free from things like filename extensions. To achieve clean URLs for
+pages using Jekyll, you simply need to create a folder for each top-level page
+you want, and then place an `index.html` file in each page’s folder. This way
+the page URL ends up being the folder name, and the web server will serve up the
+respective `index.html` file. Here's an example of what this structure might
+look like:
+
+{% highlight bash %}
+.
+├── _config.yml
+├── _includes/
+├── _layouts/
+├── _posts/
+├── _site/
+├── about/
+| └── index.html # => http://example.com/about/
+├── contact/
+| └── index.html # => http://example.com/contact/
+└── index.html # => http://example.com/
+{% endhighlight %}
+
+This approach may not suit everyone, but for people who like clean URLs it’s
+simple and it works. In the end the decision is yours!
diff --git a/site/docs/pagination.md b/site/docs/pagination.md
new file mode 100644
index 0000000..ccd8ba7
--- /dev/null
+++ b/site/docs/pagination.md
@@ -0,0 +1,211 @@
+---
+layout: docs
+title: Pagination
+prev_section: permalinks
+next_section: plugins
+permalink: /docs/pagination/
+---
+
+With many websites—especially blogs—it’s very common to break the main listing
+of posts up into smaller lists and display them over multiple pages. Jekyll has
+pagination built-in, so you can automatically generate the appropriate files and
+folders you need for paginated listings.
+
+<div class="note info">
+ <h5>Pagination only works within HTML files</h5>
+ <p>
+ Pagination does not work with Markdown or Textile files in your Jekyll site.
+ It will only work when used within HTML files. Since you’ll likely be using
+ this for the list of Posts, this shouldn’t be an issue.
+ </p>
+</div>
+
+## Enable pagination
+
+To enable pagination for your blog, add a line to the `_config.yml` file that
+specifies how many items should be displayed per page:
+
+{% highlight yaml %}
+paginate: 5
+{% endhighlight %}
+
+The number should be the maximum number of Posts you’d like to be displayed per-
+page in the generated site.
+
+You may also specify where the destination of the pagination pages:
+
+{% highlight yaml %}
+paginate_path: "blog/page:num"
+{% endhighlight %}
+
+This will read in `blog/index.html`, send it each pagination page in Liquid as `paginator`
+and write the output to `blog/page:num`, where `:num` is the pagination page number,
+starting with `2`. If a site has 12 posts and specifies `paginate: 5`, Jekyll will write
+`blog/index.html` with the first 5 posts, `blog/page2/index.html` with the next 5 posts
+and `blog/page3/index.html` with the last 2 posts into the destination directory.
+
+## Liquid Attributes Available
+
+The pagination plugin exposes the `paginator` liquid object with the following
+attributes:
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Attribute</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><p><code>page</code></p></td>
+ <td><p>current page number</p></td>
+ </tr>
+ <tr>
+ <td><p><code>per_page</code></p></td>
+ <td><p>number of posts per page</p></td>
+ </tr>
+ <tr>
+ <td><p><code>posts</code></p></td>
+ <td><p>a list of posts for the current page</p></td>
+ </tr>
+ <tr>
+ <td><p><code>total_posts</code></p></td>
+ <td><p>total number of posts in the site</p></td>
+ </tr>
+ <tr>
+ <td><p><code>total_pages</code></p></td>
+ <td><p>number of pagination pages</p></td>
+ </tr>
+ <tr>
+ <td><p><code>previous_page</code></p></td>
+ <td>
+ <p>
+ page number of the previous pagination page,
+ or <code>nil</code> if no previous page exists
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><p><code>previous_page_path</code></p></td>
+ <td>
+ <p>
+ path of previous pagination page,
+ or <code>nil</code> if no previous page exists
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><p><code>next_page</code></p></td>
+ <td>
+ <p>
+ page number of the next pagination page,
+ or <code>nil</code> if no subsequent page exists
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><p><code>next_page_path</code></p></td>
+ <td>
+ <p>
+ path of next pagination page,
+ or <code>nil</code> if no subsequent page exists
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<div class="note info">
+ <h5>Pagination does not support tags or categories</h5>
+ <p>Pagination pages through every post in the <code>posts</code>
+ variable regardless of variables defined in the YAML Front Matter of
+ each. It does not currently allow paging over groups of posts linked
+ by a common tag or category.</p>
+</div>
+
+## Render the paginated Posts
+
+The next thing you need to do is to actually display your posts in a list using
+the `paginator` variable that will now be available to you. You’ll probably want
+to do this in one of the main pages of your site. Here’s one example of a simple
+way of rendering paginated Posts in a HTML file:
+
+{% highlight html %}
+{% raw %}
+---
+layout: default
+title: My Blog
+---
+
+<!-- This loops through the paginated posts -->
+{% for post in paginator.posts %}
+ <h1><a href="{{ post.url }}">{{ post.title }}</a></h1>
+ <p class="author">
+ <span class="date">{{ post.date }}</span>
+ </p>
+ <div class="content">
+ {{ post.content }}
+ </div>
+{% endfor %}
+
+<!-- Pagination links -->
+<div class="pagination">
+ {% if paginator.previous_page %}
+ <a href="/page{{ paginator.previous_page }}" class="previous">Previous</a>
+ {% else %}
+ <span class="previous">Previous</span>
+ {% endif %}
+ <span class="page_number ">Page: {{ paginator.page }} of {{ paginator.total_pages }}</span>
+ {% if paginator.next_page %}
+ <a href="/page{{ paginator.next_page }}" class="next">Next</a>
+ {% else %}
+ <span class="next ">Next</span>
+ {% endif %}
+</div>
+{% endraw %}
+{% endhighlight %}
+
+<div class="note warning">
+ <h5>Beware the page one edge-case</h5>
+ <p>
+ Jekyll does not generate a ‘page1’ folder, so the above code will not work
+ when a <code>/page1</code> link is produced. See below for a way to handle
+ this if it’s a problem for you.
+ </p>
+</div>
+
+The following HTML snippet should handle page one, and render a list of each
+page with links to all but the current page.
+
+{% highlight html %}
+{% raw %}
+{% if paginator.total_pages > 1 %}
+<div class="pagination">
+ {% if paginator.previous_page %}
+ <a href="{{ paginator.previous_page_path | prepend: site.baseurl | replace: '//', '/' }}">« Prev</a>
+ {% else %}
+ <span>« Prev</span>
+ {% endif %}
+
+ {% for page in (1..paginator.total_pages) %}
+ {% if page == paginator.page %}
+ <em>{{ page }}</em>
+ {% elsif page == 1 %}
+ <a href="{{ '/index.html' | prepend: site.baseurl | replace: '//', '/' }}">{{ page }}</a>
+ {% else %}
+ <a href="{{ site.paginate_path | prepend: site.baseurl | replace: '//', '/' | replace: ':num', page }}">{{ page }}</a>
+ {% endif %}
+ {% endfor %}
+
+ {% if paginator.next_page %}
+ <a href="{{ paginator.next_page_path | prepend: site.baseurl | replace: '//', '/' }}">Next »</a>
+ {% else %}
+ <span>Next »</span>
+ {% endif %}
+</div>
+{% endif %}
+{% endraw %}
+{% endhighlight %}
diff --git a/site/docs/permalinks.md b/site/docs/permalinks.md
new file mode 100644
index 0000000..c38ad94
--- /dev/null
+++ b/site/docs/permalinks.md
@@ -0,0 +1,180 @@
+---
+layout: docs
+title: Permalinks
+prev_section: templates
+next_section: pagination
+permalink: /docs/permalinks/
+---
+
+Jekyll supports a flexible way to build your site’s URLs. You can specify the
+permalinks for your site through the [Configuration](../configuration/) or in the
+[YAML Front Matter](../frontmatter/) for each post. You’re free to choose one of
+the built-in styles to create your links or craft your own. The default style is
+`date`.
+
+Permalinks are constructed by creating a template URL where dynamic elements are
+represented by colon-prefixed keywords. For example, the default `date`
+permalink is defined as `/:categories/:year/:month/:day/:title.html`.
+
+## Template variables
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Variable</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>year</code></p>
+ </td>
+ <td>
+ <p>Year from the Post’s filename</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>month</code></p>
+ </td>
+ <td>
+ <p>Month from the Post’s filename</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>i_month</code></p>
+ </td>
+ <td>
+ <p>Month from the Post’s filename without leading zeros.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>day</code></p>
+ </td>
+ <td>
+ <p>Day from the Post’s filename</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>i_day</code></p>
+ </td>
+ <td>
+ <p>Day from the Post’s filename without leading zeros.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>title</code></p>
+ </td>
+ <td>
+ <p>Title from the Post’s filename</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>categories</code></p>
+ </td>
+ <td>
+ <p>
+ The specified categories for this Post. Jekyll automatically parses
+ out double slashes in the URLs, so if no categories are present, it
+ will ignore this.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+## Built-in permalink styles
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Permalink Style</th>
+ <th>URL Template</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>date</code></p>
+ </td>
+ <td>
+ <p><code>/:categories/:year/:month/:day/:title.html</code></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>pretty</code></p>
+ </td>
+ <td>
+ <p><code>/:categories/:year/:month/:day/:title/</code></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>none</code></p>
+ </td>
+ <td>
+ <p><code>/:categories/:title.html</code></p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+## Permalink style examples
+
+Given a post named: `/2009-04-29-slap-chop.textile`
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Permalink Setting</th>
+ <th>Resulting Permalink URL</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p>None specified, or <code>permalink: date</code></p>
+ </td>
+ <td>
+ <p><code>/2009/04/29/slap-chop.html</code></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>permalink: pretty</code></p>
+ </td>
+ <td>
+ <p><code>/2009/04/29/slap-chop/index.html</code></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>permalink: /:month-:day-:year/:title.html</code></p>
+ </td>
+ <td>
+ <p><code>/04-29-2009/slap-chop.html</code></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>permalink: /blog/:year/:month/:day/:title</code></p>
+ </td>
+ <td>
+ <p><code>/blog/2009/04/29/slap-chop/index.html</code></p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
diff --git a/site/docs/plugins.md b/site/docs/plugins.md
new file mode 100644
index 0000000..eb6392f
--- /dev/null
+++ b/site/docs/plugins.md
@@ -0,0 +1,534 @@
+---
+layout: docs
+title: Plugins
+prev_section: pagination
+next_section: extras
+permalink: /docs/plugins/
+---
+
+Jekyll has a plugin system with hooks that allow you to create custom generated
+content specific to your site. You can run custom code for your site without
+having to modify the Jekyll source itself.
+
+<div class="note info">
+ <h5>Plugins on GitHub Pages</h5>
+ <p>
+ <a href="http://pages.github.com/">GitHub Pages</a> is powered by Jekyll,
+ however all Pages sites are generated using the <code>--safe</code> option
+ to disable custom plugins for security reasons. Unfortunately, this means
+ your plugins won’t work if you’re deploying to GitHub Pages.<br><br>
+ You can still use GitHub Pages to publish your site, but you’ll need to
+ convert the site locally and push the generated static files to your GitHub
+ repository instead of the Jekyll source files.
+ </p>
+</div>
+
+## Installing a plugin
+
+You have 2 options for installing plugins:
+
+1. In your site source root, make a `_plugins` directory. Place your plugins here.
+ Any file ending in `*.rb` inside this directory will be loaded before Jekyll
+ generates your site.
+2. In your `_config.yml` file, add a new array with the key `gems` and the values
+ of the gem names of the plugins you'd like to use. An example:
+
+ gems: [jekyll-test-plugin, jekyll-jsonify, jekyll-assets]
+ # This will require each of these gems automatically.
+
+<div class="note info">
+ <h5>
+ <code>_plugins</code> and <code>gems</code>
+ can be used simultaneously
+ </h5>
+ <p>
+ You may use both of the aforementioned plugin options simultaneously in the
+ same site if you so choose. Use of one does not restrict the use of the other
+ </p>
+</div>
+
+In general, plugins you make will fall into one of three categories:
+
+1. Generators
+2. Converters
+3. Tags
+
+## Generators
+
+You can create a generator when you need Jekyll to create additional content
+based on your own rules.
+
+A generator is a subclass of `Jekyll::Generator` that defines a `generate`
+method, which receives an instance of
+[`Jekyll::Site`]({{ site.repository }}/blob/master/lib/jekyll/site.rb).
+
+Generation is triggered for its side-effects, the return value of `generate` is
+ignored. Jekyll does not assume any particular side-effect to happen, it just
+runs the method.
+
+Generators run after Jekyll has made an inventory of the existing content, and
+before the site is generated. Pages with YAML front-matters are stored as
+instances of
+[`Jekyll::Page`]({{ site.repository }}/blob/master/lib/jekyll/page.rb)
+and are available via `site.pages`. Static files become instances of
+[`Jekyll::StaticFile`]({{ site.repository }}/blob/master/lib/jekyll/static_file.rb)
+and are available via `site.static_files`. See
+[`Jekyll::Site`]({{ site.repository }}/blob/master/lib/jekyll/site.rb)
+for more details.
+
+For instance, a generator can inject values computed at build time for template
+variables. In the following example the template `reading.html` has two
+variables `ongoing` and `done` that we fill in the generator:
+
+{% highlight ruby %}
+module Reading
+ class Generator < Jekyll::Generator
+ def generate(site)
+ ongoing, done = Book.all.partition(&:ongoing?)
+
+ reading = site.pages.detect {|page| page.name == 'reading.html'}
+ reading.data['ongoing'] = ongoing
+ reading.data['done'] = done
+ end
+ end
+end
+{% endhighlight %}
+
+This is a more complex generator that generates new pages:
+
+{% highlight ruby %}
+module Jekyll
+
+ class CategoryPage < Page
+ def initialize(site, base, dir, category)
+ @site = site
+ @base = base
+ @dir = dir
+ @name = 'index.html'
+
+ self.process(@name)
+ self.read_yaml(File.join(base, '_layouts'), 'category_index.html')
+ self.data['category'] = category
+
+ category_title_prefix = site.config['category_title_prefix'] || 'Category: '
+ self.data['title'] = "#{category_title_prefix}#{category}"
+ end
+ end
+
+ class CategoryPageGenerator < Generator
+ safe true
+
+ def generate(site)
+ if site.layouts.key? 'category_index'
+ dir = site.config['category_dir'] || 'categories'
+ site.categories.keys.each do |category|
+ site.pages << CategoryPage.new(site, site.source, File.join(dir, category), category)
+ end
+ end
+ end
+ end
+
+end
+{% endhighlight %}
+
+In this example, our generator will create a series of files under the
+`categories` directory for each category, listing the posts in each category
+using the `category_index.html` layout.
+
+Generators are only required to implement one method:
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>generate</code></p>
+ </td>
+ <td>
+ <p>Generates content as a side-effect.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+## Converters
+
+If you have a new markup language you’d like to use with your site, you can
+include it by implementing your own converter. Both the Markdown and Textile
+markup languages are implemented using this method.
+
+<div class="note info">
+ <h5>Remember your YAML front-matter</h5>
+ <p>
+ Jekyll will only convert files that have a YAML header at the top, even for
+ converters you add using a plugin.
+ </p>
+</div>
+
+Below is a converter that will take all posts ending in `.upcase` and process
+them using the `UpcaseConverter`:
+
+{% highlight ruby %}
+module Jekyll
+ class UpcaseConverter < Converter
+ safe true
+ priority :low
+
+ def matches(ext)
+ ext =~ /^\.upcase$/i
+ end
+
+ def output_ext(ext)
+ ".html"
+ end
+
+ def convert(content)
+ content.upcase
+ end
+ end
+end
+{% endhighlight %}
+
+Converters should implement at a minimum 3 methods:
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>matches</code></p>
+ </td>
+ <td><p>
+ Does the given extension match this converter’s list of acceptable
+ extensions? Takes one argument: the file’s extension (including the
+ dot). Must return <code>true</code> if it matches, <code>false</code>
+ otherwise.
+ </p></td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>output_ext</code></p>
+ </td>
+ <td><p>
+ The extension to be given to the output file (including the dot).
+ Usually this will be <code>".html"</code>.
+ </p></td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>convert</code></p>
+ </td>
+ <td><p>
+ Logic to do the content conversion. Takes one argument: the raw content
+ of the file (without YAML front matter). Must return a String.
+ </p></td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+In our example, `UpcaseConverter#matches` checks if our filename extension is
+`.upcase`, and will render using the converter if it is. It will call
+`UpcaseConverter#convert` to process the content. In our simple converter we’re
+simply uppercasing the entire content string. Finally, when it saves the page,
+it will do so with a `.html` extension.
+
+## Tags
+
+If you’d like to include custom liquid tags in your site, you can do so by
+hooking into the tagging system. Built-in examples added by Jekyll include the
+`highlight` and `include` tags. Below is an example of a custom liquid tag that
+will output the time the page was rendered:
+
+{% highlight ruby %}
+module Jekyll
+ class RenderTimeTag < Liquid::Tag
+
+ def initialize(tag_name, text, tokens)
+ super
+ @text = text
+ end
+
+ def render(context)
+ "#{@text} #{Time.now}"
+ end
+ end
+end
+
+Liquid::Template.register_tag('render_time', Jekyll::RenderTimeTag)
+{% endhighlight %}
+
+At a minimum, liquid tags must implement:
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>render</code></p>
+ </td>
+ <td>
+ <p>Outputs the content of the tag.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+You must also register the custom tag with the Liquid template engine as
+follows:
+
+{% highlight ruby %}
+Liquid::Template.register_tag('render_time', Jekyll::RenderTimeTag)
+{% endhighlight %}
+
+In the example above, we can place the following tag anywhere in one of our
+pages:
+
+{% highlight ruby %}
+{% raw %}
+<p>{% render_time page rendered at: %}</p>
+{% endraw %}
+{% endhighlight %}
+
+And we would get something like this on the page:
+
+{% highlight html %}
+<p>page rendered at: Tue June 22 23:38:47 –0500 2010</p>
+{% endhighlight %}
+
+### Liquid filters
+
+You can add your own filters to the Liquid template system much like you can add
+tags above. Filters are simply modules that export their methods to liquid. All
+methods will have to take at least one parameter which represents the input of
+the filter. The return value will be the output of the filter.
+
+{% highlight ruby %}
+module Jekyll
+ module AssetFilter
+ def asset_url(input)
+ "http://www.example.com/#{input}?#{Time.now.to_i}"
+ end
+ end
+end
+
+Liquid::Template.register_filter(Jekyll::AssetFilter)
+{% endhighlight %}
+
+<div class="note">
+ <h5>ProTip™: Access the site object using Liquid</h5>
+ <p>
+ Jekyll lets you access the <code>site</code> object through the
+ <code>context.registers</code> feature of Liquid. For example, you can
+ access the global configuration file <code>_config.yml</code> using
+ <code>context.registers.config</code>.
+ </p>
+</div>
+
+### Flags
+
+There are two flags to be aware of when writing a plugin:
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Flag</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>safe</code></p>
+ </td>
+ <td>
+ <p>
+ A boolean flag that informs Jekyll whether this plugin may be safely
+ executed in an environment where arbitrary code execution is not
+ allowed. This is used by GitHub Pages to determine which core plugins
+ may be used, and which are unsafe to run. If your plugin does not
+ allow for arbitrary code, execution, set this to <code>true</code>.
+ GitHub Pages still won’t load your plugin, but if you submit it for
+ inclusion in core, it’s best for this to be correct!
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>priority</code></p>
+ </td>
+ <td>
+ <p>
+ This flag determines what order the plugin is loaded in. Valid values
+ are: <code>:lowest</code>, <code>:low</code>, <code>:normal</code>,
+ <code>:high</code>, and <code>:highest</code>. Highest priority
+ matches are applied first, lowest priority are applied last.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+To use one of the example plugins above as an illustration, here is how you’d
+specify these two flags:
+
+{% highlight ruby %}
+module Jekyll
+ class UpcaseConverter < Converter
+ safe true
+ priority :low
+ ...
+ end
+end
+{% endhighlight %}
+
+## Available Plugins
+
+You can find a few useful plugins at the following locations:
+
+#### Generators
+
+- [ArchiveGenerator by Ilkka Laukkanen](https://gist.github.com/707909): Uses [this archive page](https://gist.github.com/707020) to generate archives.
+- [LESS.js Generator by Andy Fowler](https://gist.github.com/642739): Renders LESS.js files during generation.
+- [Version Reporter by Blake Smith](https://gist.github.com/449491): Creates a version.html file containing the Jekyll version.
+- [Sitemap.xml Generator by Michael Levin](https://github.com/kinnetica/jekyll-plugins): Generates a sitemap.xml file by traversing all of the available posts and pages.
+- [Full-text search by Pascal Widdershoven](https://github.com/PascalW/jekyll_indextank): Adds full-text search to your Jekyll site with a plugin and a bit of JavaScript.
+- [AliasGenerator by Thomas Mango](https://github.com/tsmango/jekyll_alias_generator): Generates redirect pages for posts when an alias is specified in the YAML Front Matter.
+- [Pageless Redirect Generator by Nick Quinlan](https://github.com/nquinlan/jekyll-pageless-redirects): Generates redirects based on files in the Jekyll root, with support for htaccess style redirects.
+- [Projectlist by Frederic Hemberger](https://github.com/fhemberger/jekyll-projectlist): Renders files in a directory as a single page instead of separate posts.
+- [RssGenerator by Assaf Gelber](https://github.com/agelber/jekyll-rss): Automatically creates an RSS 2.0 feed from your posts.
+- [Monthly archive generator by Shigeya Suzuki](https://github.com/shigeya/jekyll-monthly-archive-plugin): Generator and template which renders monthly archive like MovableType style, based on the work by Ilkka Laukkanen and others above.
+- [Category archive generator by Shigeya Suzuki](https://github.com/shigeya/jekyll-category-archive-plugin): Generator and template which renders category archive like MovableType style, based on Monthly archive generator.
+- [Emoji for Jekyll](https://github.com/yihangho/emoji-for-jekyll): Seamlessly enable emoji for all posts and pages.
+
+#### Converters
+
+- [Jade plugin by John Papandriopoulos](https://github.com/snappylabs/jade-jekyll-plugin): Jade converter for Jekyll.
+- [HAML plugin by Sam Z](https://gist.github.com/517556): HAML converter for Jekyll.
+- [HAML-Sass Converter by Adam Pearson](https://gist.github.com/481456): Simple HAML-Sass converter for Jekyll. [Fork](https://gist.github.com/528642) by Sam X.
+- [Sass SCSS Converter by Mark Wolfe](https://gist.github.com/960150): Sass converter which uses the new CSS compatible syntax, based Sam X’s fork above.
+- [LESS Converter by Jason Graham](https://gist.github.com/639920): Convert LESS files to CSS.
+- [LESS Converter by Josh Brown](https://gist.github.com/760265): Simple LESS converter.
+- [Upcase Converter by Blake Smith](https://gist.github.com/449463): An example Jekyll converter.
+- [CoffeeScript Converter by phaer](https://gist.github.com/959938): A [CoffeeScript](http://coffeescript.org) to Javascript converter.
+- [Markdown References by Olov Lassus](https://github.com/olov/jekyll-references): Keep all your markdown reference-style link definitions in one \_references.md file.
+- [Stylus Converter](https://gist.github.com/988201): Convert .styl to .css.
+- [ReStructuredText Converter](https://github.com/xdissent/jekyll-rst): Converts ReST documents to HTML with Pygments syntax highlighting.
+- [Jekyll-pandoc-plugin](https://github.com/dsanson/jekyll-pandoc-plugin): Use pandoc for rendering markdown.
+- [Jekyll-pandoc-multiple-formats](https://github.com/fauno/jekyll-pandoc-multiple-formats) by [edsl](https://github.com/edsl): Use pandoc to generate your site in multiple formats. Supports pandoc’s markdown extensions.
+- [ReStructuredText Converter](https://github.com/xdissent/jekyll-rst): Converts ReST documents to HTML with Pygments syntax highlighting.
+- [Transform Layouts](https://gist.github.com/1472645): Allows HAML layouts (you need a HAML Converter plugin for this to work).
+- [Org-mode Converter](https://gist.github.com/abhiyerra/7377603): Org-mode converter for Jekyll.
+
+#### Filters
+
+- [Truncate HTML](https://github.com/MattHall/truncatehtml) by [Matt Hall](http://codebeef.com): A Jekyll filter that truncates HTML while preserving markup structure.
+- [Domain Name Filter by Lawrence Woodman](https://github.com/LawrenceWoodman/domain_name-liquid_filter): Filters the input text so that just the domain name is left.
+- [Summarize Filter by Mathieu Arnold](https://gist.github.com/731597): Remove markup after a `<div id="extended">` tag.
+- [URL encoding by James An](https://gist.github.com/919275): Percent encoding for URIs.
+- [JSON Filter](https://gist.github.com/1850654) by [joelverhagen](https://github.com/joelverhagen): Filter that takes input text and outputs it as JSON. Great for rendering JavaScript.
+- [i18n_filter](https://github.com/gacha/gacha.id.lv/blob/master/_plugins/i18n_filter.rb): Liquid filter to use I18n localization.
+- [Smilify](https://github.com/SaswatPadhi/jekyll_smilify) by [SaswatPadhi](https://github.com/SaswatPadhi): Convert text emoticons in your content to themeable smiley pics ([Demo](http://saswatpadhi.github.com/)).
+- [Read in X Minutes](https://gist.github.com/zachleat/5792681) by [zachleat](https://github.com/zachleat): Estimates the reading time of a string (for blog post content).
+- [Jekyll-timeago](https://github.com/markets/jekyll-timeago): Converts a time value to the time ago in words.
+- [pluralize](https://github.com/bdesham/pluralize): Easily combine a number and a word into a gramatically-correct amount like “1 minute” or “2 minute**s**”.
+- [reading_time](https://github.com/bdesham/reading_time): Count words and estimate reading time for a piece of text, ignoring HTML elements that are unlikely to contain running text.
+- [Table of Content Generator](https://github.com/dafi/jekyll-toc-generator): Generate the HTML code containing a table of content (TOC), the TOC can be customized in many way, for example you can decide which pages can be without TOC.
+
+#### Tags
+
+- [Asset Path Tag](https://github.com/samrayner/jekyll-asset-path-plugin) by [Sam Rayner](http://www.samrayner.com/): Allows organisation of assets into subdirectories by outputting a path for a given file relative to the current post or page.
+- [Delicious Plugin by Christian Hellsten](https://github.com/christianhellsten/jekyll-plugins): Fetches and renders bookmarks from delicious.com.
+- [Ultraviolet Plugin by Steve Alex](https://gist.github.com/480380): Jekyll tag for the [Ultraviolet](http://ultraviolet.rubyforge.org/) code highligher.
+- [Tag Cloud Plugin by Ilkka Laukkanen](https://gist.github.com/710577): Generate a tag cloud that links to tag pages.
+- [GIT Tag by Alexandre Girard](https://gist.github.com/730347): Add Git activity inside a list.
+- [MathJax Liquid Tags by Jessy Cowan-Sharp](https://gist.github.com/834610): Simple liquid tags for Jekyll that convert inline math and block equations to the appropriate MathJax script tags.
+- [Non-JS Gist Tag by Brandon Tilley](https://gist.github.com/1027674) A Liquid tag that embeds Gists and shows code for non-JavaScript enabled browsers and readers.
+- [Render Time Tag by Blake Smith](https://gist.github.com/449509): Displays the time a Jekyll page was generated.
+- [Status.net/OStatus Tag by phaer](https://gist.github.com/912466): Displays the notices in a given status.net/ostatus feed.
+- [Raw Tag by phaer](https://gist.github.com/1020852): Keeps liquid from parsing text betweeen `raw` tags.
+- [Embed.ly client by Robert Böhnke](https://github.com/robb/jekyll-embedly-client): Autogenerate embeds from URLs using oEmbed.
+- [Logarithmic Tag Cloud](https://gist.github.com/2290195): Flexible. Logarithmic distribution. Documentation inline.
+- [oEmbed Tag by Tammo van Lessen](https://gist.github.com/1455726): Enables easy content embedding (e.g. from YouTube, Flickr, Slideshare) via oEmbed.
+- [FlickrSetTag by Thomas Mango](https://github.com/tsmango/jekyll_flickr_set_tag): Generates image galleries from Flickr sets.
+- [Tweet Tag by Scott W. Bradley](https://github.com/scottwb/jekyll-tweet-tag): Liquid tag for [Embedded Tweets](https://dev.twitter.com/docs/embedded-tweets) using Twitter’s shortcodes.
+- [Jekyll-contentblocks](https://github.com/rustygeldmacher/jekyll-contentblocks): Lets you use Rails-like content_for tags in your templates, for passing content from your posts up to your layouts.
+- [Generate YouTube Embed](https://gist.github.com/1805814) by [joelverhagen](https://github.com/joelverhagen): Jekyll plugin which allows you to embed a YouTube video in your page with the YouTube ID. Optionally specify width and height dimensions. Like “oEmbed Tag” but just for YouTube.
+- [Jekyll-beastiepress](https://github.com/okeeblow/jekyll-beastiepress): FreeBSD utility tags for Jekyll sites.
+- [Jsonball](https://gist.github.com/1895282): Reads json files and produces maps for use in Jekyll files.
+- [Bibjekyll](https://github.com/pablooliveira/bibjekyll): Render BibTeX-formatted bibliographies/citations included in posts and pages using bibtex2html.
+- [Jekyll-citation](https://github.com/archome/jekyll-citation): Render BibTeX-formatted bibliographies/citations included in posts and pages (pure Ruby).
+- [Jekyll Dribbble Set Tag](https://github.com/ericdfields/Jekyll-Dribbble-Set-Tag): Builds Dribbble image galleries from any user.
+- [Debbugs](https://gist.github.com/2218470): Allows posting links to Debian BTS easily.
+- [Refheap_tag](https://github.com/aburdette/refheap_tag): Liquid tag that allows embedding pastes from [refheap](https://refheap.com).
+- [Jekyll-devonly_tag](https://gist.github.com/2403522): A block tag for including markup only during development.
+- [JekyllGalleryTag](https://github.com/redwallhp/JekyllGalleryTag) by [redwallhp](https://github.com/redwallhp): Generates thumbnails from a directory of images and displays them in a grid.
+- [Youku and Tudou Embed](https://gist.github.com/Yexiaoxing/5891929): Liquid plugin for embedding Youku and Tudou videos.
+- [Jekyll-swfobject](https://github.com/sectore/jekyll-swfobject): Liquid plugin for embedding Adobe Flash files (.swf) using [SWFObject](http://code.google.com/p/swfobject/).
+- [Jekyll Picture Tag](https://github.com/robwierzbowski/jekyll-picture-tag): Easy responsive images for Jekyll. Based on the proposed [`<picture>`](http://picture.responsiveimages.org/) element, polyfilled with Scott Jehl’s [Picturefill](https://github.com/scottjehl/picturefill).
+- [Jekyll Image Tag](https://github.com/robwierzbowski/jekyll-image-tag): Better images for Jekyll. Save image presets, generate resized images, and add classes, alt text, and other attributes.
+- [Ditaa Tag](https://github.com/matze/jekyll-ditaa) by [matze](https://github.com/matze): Renders ASCII diagram art into PNG images and inserts a figure tag.
+- [Good Include](https://github.com/penibelst/jekyll-good-include) by [Anatol Broder](http://penibelst.de/): Strips newlines and whitespaces from the end of include files before processing.
+- [Jekyll Suggested Tweet](https://github.com/davidensinger/jekyll-suggested-tweet) by [David Ensinger](https://github.com/davidensinger/): A Liquid tag for Jekyll that allows for the embedding of suggested tweets via Twitter’s Web Intents API.
+- [Jekyll Date Chart](https://github.com/GSI/jekyll_date_chart) by [GSI](https://github.com/GSI): Block that renders date line charts based on textile-formatted tables.
+- [Jekyll Image Encode](https://github.com/GSI/jekyll_image_encode) by [GSI](https://github.com/GSI): Tag that renders base64 codes of images fetched from the web.
+- [Jekyll Quick Man](https://github.com/GSI/jekyll_quick_man) by [GSI](https://github.com/GSI): Tag that renders pretty links to man page sources on the internet.
+
+#### Collections
+
+- [Jekyll Plugins by Recursive Design](http://recursive-design.com/projects/jekyll-plugins/): Plugins to generate Project pages from GitHub readmes, a Category page, and a Sitemap generator.
+- [Company website and blog plugins](https://github.com/flatterline/jekyll-plugins) by Flatterline, a [Ruby on Rails development company](http://flatterline.com/): Portfolio/project page generator, team/individual page generator, an author bio liquid tag for use on posts, and a few other smaller plugins.
+- [Jekyll plugins by Aucor](https://github.com/aucor/jekyll-plugins): Plugins for trimming unwanted newlines/whitespace and sorting pages by weight attribute.
+
+#### Other
+
+- [Pygments Cache Path by Raimonds Simanovskis](https://github.com/rsim/blog.rayapps.com/blob/master/_plugins/pygments_cache_patch.rb): Plugin to cache syntax-highlighted code from Pygments.
+- [Draft/Publish Plugin by Michael Ivey](https://gist.github.com/49630): Save posts as drafts.
+- [Growl Notification Generator by Tate Johnson](https://gist.github.com/490101): Send Jekyll notifications to Growl.
+- [Growl Notification Hook by Tate Johnson](https://gist.github.com/525267): Better alternative to the above, but requires his “hook” fork.
+- [Related Posts by Lawrence Woodman](https://github.com/LawrenceWoodman/related_posts-jekyll_plugin): Overrides `site.related_posts` to use categories to assess relationship.
+- [Tiered Archives by Eli Naeher](https://gist.github.com/88cda643aa7e3b0ca1e5): Create tiered template variable that allows you to group archives by year and month.
+- [Jekyll-localization](https://github.com/blackwinter/jekyll-localization): Jekyll plugin that adds localization features to the rendering engine.
+- [Jekyll-rendering](https://github.com/blackwinter/jekyll-rendering): Jekyll plugin to provide alternative rendering engines.
+- [Jekyll-pagination](https://github.com/blackwinter/jekyll-pagination): Jekyll plugin to extend the pagination generator.
+- [Jekyll-tagging](https://github.com/pattex/jekyll-tagging): Jekyll plugin to automatically generate a tag cloud and tag pages.
+- [Jekyll-scholar](https://github.com/inukshuk/jekyll-scholar): Jekyll extensions for the blogging scholar.
+- [Jekyll-asset_bundler](https://github.com/moshen/jekyll-asset_bundler): Bundles and minifies JavaScript and CSS.
+- [Jekyll-assets](http://ixti.net/jekyll-assets/) by [ixti](https://github.com/ixti): Rails-alike assets pipeline (write assets in CoffeeScript, Sass, LESS etc; specify dependencies for automatic bundling using simple declarative comments in assets; minify and compress; use JST templates; cache bust; and many-many more).
+- [File compressor](https://gist.github.com/2758691) by [mytharcher](https://github.com/mytharcher): Compress HTML and JavaScript files on site build.
+- [Jekyll-minibundle](https://github.com/tkareine/jekyll-minibundle): Asset bundling and cache busting using external minification tool of your choice. No gem dependencies.
+- [Singlepage-jekyll](https://github.com/JCB-K/singlepage-jekyll) by [JCB-K](https://github.com/JCB-K): Turns Jekyll into a dynamic one-page website.
+- [generator-jekyllrb](https://github.com/robwierzbowski/generator-jekyllrb): A generator that wraps Jekyll in [Yeoman](http://yeoman.io/), a tool collection and workflow for builing modern web apps.
+- [grunt-jekyll](https://github.com/dannygarcia/grunt-jekyll): A straightforward [Grunt](http://gruntjs.com/) plugin for Jekyll.
+- [jekyll-postfiles](https://github.com/indirect/jekyll-postfiles): Add `_postfiles` directory and {% raw %}`{{ postfile }}`{% endraw %} tag so the files a post refers to will always be right there inside your repo.
+
+<div class="note info">
+ <h5>Jekyll Plugins Wanted</h5>
+ <p>
+ If you have a Jekyll plugin that you would like to see added to this list,
+ you should <a href="../contributing/">read the contributing page</a> to find
+ out how to make that happen.
+ </p>
+</div>
diff --git a/site/docs/posts.md b/site/docs/posts.md
new file mode 100644
index 0000000..88036bd
--- /dev/null
+++ b/site/docs/posts.md
@@ -0,0 +1,181 @@
+---
+layout: docs
+title: Writing posts
+prev_section: frontmatter
+next_section: drafts
+permalink: /docs/posts/
+---
+
+One of Jekyll’s best aspects is that it is “blog aware”. What does this mean,
+exactly? Well, simply put, it means that blogging is baked into Jekyll’s
+functionality. If you write articles and publish them online, this means that
+you can publish and maintain a blog simply by managing a folder of text-files on
+your computer. Compared to the hassle of configuring and maintaining databases
+and web-based CMS systems, this will be a welcome change!
+
+## The Posts Folder
+
+As explained on the [directory structure](../structure/) page, the `_posts`
+folder is where your blog posts will live. These files can be either
+[Markdown](http://daringfireball.net/projects/markdown/) or
+[Textile](http://textile.sitemonks.com/) formatted text files, and as long as
+they have [YAML front-matter](../frontmatter/), they will be converted from their
+source format into an HTML page that is part of your static site.
+
+### Creating Post Files
+
+To create a new post, all you need to do is create a new file in the `_posts`
+directory. How you name files in this folder is important. Jekyll requires blog
+post files to be named according to the following format:
+
+{% highlight bash %}
+YEAR-MONTH-DAY-title.MARKUP
+{% endhighlight %}
+
+Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit
+numbers, and `MARKUP` is the file extension representing the format used in the
+file. For example, the following are examples of valid post filenames:
+
+{% highlight bash %}
+2011-12-31-new-years-eve-is-awesome.md
+2012-09-12-how-to-write-a-blog.textile
+{% endhighlight %}
+
+### Content Formats
+
+All blog post files must begin with [YAML front- matter](../frontmatter/). After
+that, it's simply a matter of deciding which format you prefer. Jekyll supports
+two popular content markup formats:
+[Markdown](http://daringfireball.net/projects/markdown/) and
+[Textile](http://textile.sitemonks.com/). These formats each have their own way
+of marking up different types of content within a post, so you should
+familiarize yourself with these formats and decide which one best suits your
+needs.
+
+## Including images and resources
+
+Chances are, at some point, you'll want to include images, downloads, or other
+digital assets along with your text content. While the syntax for linking to
+these resources differs between Markdown and Textile, the problem of working out
+where to store these files in your site is something everyone will face.
+
+Because of Jekyll’s flexibility, there are many solutions to how to do this. One
+common solution is to create a folder in the root of the project directory
+called something like `assets` or `downloads`, into which any images, downloads
+or other resources are placed. Then, from within any post, they can be linked to
+using the site’s root as the path for the asset to include. Again, this will
+depend on the way your site’s (sub)domain and path are configured, but here some
+examples (in Markdown) of how you could do this using the `site.url` variable in
+a post.
+
+Including an image asset in a post:
+
+{% highlight text %}
+… which is shown in the screenshot below:
+
+{% endhighlight %}
+
+Linking to a PDF for readers to download:
+
+{% highlight text %}
+… you can [get the PDF]({% raw %}{{ site.url }}{% endraw %}/assets/mydoc.pdf) directly.
+{% endhighlight %}
+
+<div class="note">
+ <h5>ProTip™: Link using just the site root URL</h5>
+ <p>
+ You can skip the <code>{% raw %}{{ site.url }}{% endraw %}</code> variable
+ if you <strong>know</strong> your site will only ever be displayed at the
+ root URL of your domain. In this case you can reference assets directly with
+ just <code>/path/file.jpg</code>.
+ </p>
+</div>
+
+## Displaying an index of posts
+
+It’s all well and good to have posts in a folder, but a blog is no use unless
+you have a list of posts somewhere. Creating an index of posts on another page
+(or in a [template](../templates/)) is easy, thanks to the [Liquid template
+language](http://wiki.shopify.com/Liquid) and its tags. Here’s a basic example of how
+to create a list of links to your blog posts:
+
+{% highlight html %}
+<ul>
+ {% raw %}{% for post in site.posts %}{% endraw %}
+ <li>
+ <a href="{% raw %}{{ post.url }}{% endraw %}">{% raw %}{{ post.title }}{% endraw %}</a>
+ </li>
+ {% raw %}{% endfor %}{% endraw %}
+</ul>
+{% endhighlight %}
+
+Of course, you have full control over how (and where) you display your posts,
+and how you structure your site. You should read more about [how templates
+work](../templates/) with Jekyll if you want to know more.
+
+## Post excerpts
+
+Each post automatically takes the first block of text, from the beginning of the content
+to the first occurrence of `excerpt_separator`, and sets it as the `post.excerpt`.
+Take the above example of an index of posts. Perhaps you want to include
+a little hint about the post's content by adding the first paragraph of each of your
+posts:
+
+{% highlight html %}
+<ul>
+ {% raw %}{% for post in site.posts %}{% endraw %}
+ <li>
+ <a href="{% raw %}{{ post.url }}{% endraw %}">{% raw %}{{ post.title }}{% endraw %}</a>
+ <p>{% raw %}{{ post.excerpt }}{% endraw %}</p>
+ </li>
+ {% raw %}{% endfor %}{% endraw %}
+</ul>
+{% endhighlight %}
+
+If you don't like the automatically-generated post excerpt, it can be overridden by adding
+`excerpt` to your post's YAML front-matter. Completely disable it by setting
+your `excerpt_separator` to `""`.
+
+## Highlighting code snippets
+
+Jekyll also has built-in support for syntax highlighting of code snippets using
+Pygments, and including a code snippet in any post is easy. Just use the
+dedicated Liquid tag as follows:
+
+{% highlight text %}
+{% raw %}{% highlight ruby %}{% endraw %}
+def show
+ @widget = Widget(params[:id])
+ respond_to do |format|
+ format.html # show.html.erb
+ format.json { render json: @widget }
+ end
+end
+{% raw %}{% endhighlight %}{% endraw %}
+{% endhighlight %}
+
+And the output will look like this:
+
+{% highlight ruby %}
+def show
+ @widget = Widget(params[:id])
+ respond_to do |format|
+ format.html # show.html.erb
+ format.json { render json: @widget }
+ end
+end
+{% endhighlight %}
+
+<div class="note">
+ <h5>ProTip™: Show line numbers</h5>
+ <p>
+ You can make code snippets include line-numbers by adding the word
+ <code>linenos</code> to the end of the opening highlight tag like this:
+ <code>{% raw %}{% highlight ruby linenos %}{% endraw %}</code>.
+ </p>
+</div>
+
+These basics should be enough to get you started writing your first posts. When
+you’re ready to dig into what else is possible, you might be interested in doing
+things like [customizing post permalinks](../permalinks/) or using [custom
+variables](../variables/) in your posts and elsewhere on your site.
diff --git a/site/docs/quickstart.md b/site/docs/quickstart.md
new file mode 100644
index 0000000..65af42b
--- /dev/null
+++ b/site/docs/quickstart.md
@@ -0,0 +1,32 @@
+---
+layout: docs
+title: Quick-start guide
+prev_section: home
+next_section: installation
+permalink: /docs/quickstart/
+---
+
+For the impatient, here's how to get a boilerplate Jekyll site up and running.
+
+{% highlight bash %}
+~ $ gem install jekyll
+~ $ jekyll new myblog
+~ $ cd myblog
+~/myblog $ jekyll serve
+# => Now browse to http://localhost:4000
+{% endhighlight %}
+
+That's nothing, though. The real magic happens when you start creating blog
+posts, using the front-matter to control templates and layouts, and taking
+advantage of all the awesome configuration options Jekyll makes available.
+
+<div class="note info">
+ <h5>Redcarpet is the default Markdown engine for new sites</h5>
+ <p>In Jekyll 1.1, we switched the default markdown engine for sites
+ generated with <code>jekyll new</code> to Redcarpet</p>
+</div>
+
+If you're running into problems, ensure you have all the [requirements
+installed][Installation].
+
+[Installation]: /docs/installation/
diff --git a/site/docs/resources.md b/site/docs/resources.md
new file mode 100644
index 0000000..afd34b1
--- /dev/null
+++ b/site/docs/resources.md
@@ -0,0 +1,46 @@
+---
+layout: docs
+title: Resources
+prev_section: sites
+next_section: upgrading
+permalink: /docs/resources/
+---
+
+Jekyll’s growing use is producing a wide variety of tutorials, frameworks, extensions, examples, and other resources that can be very helpful. Below is a collection of links to some of the most popular Jekyll resources.
+
+### Jekyll tips & tricks, and examples
+
+- [Tips for working with GitHub Pages Integration](https://gist.github.com/2890453)
+
+ Code example reuse, and keeping documentation up to date.
+
+- [Use Simple Form to integrate a simple contact
+ form](http://getsimpleform.com/)
+- [JekyllBootstrap.com](http://jekyllbootstrap.com)
+
+ Provides detailed explanations, examples, and helper-code to make
+ getting started with Jekyll easier.
+
+### Tutorials
+
+#### Integrating Jekyll with Git
+
+- [Blogging with Git, Emacs and Jekyll](http://metajack.im/2009/01/23/blogging-with-git-emacs-and-jekyll/)
+
+#### Other hacks
+
+- [Integrating Twitter with Jekyll](http://www.justkez.com/integrating-twitter-with-jekyll/)
+ > “Having migrated Justkez.com to be based on Jekyll, I was pondering how I might include my recent twitterings on the front page of the site. In the WordPress world, this would have been done via a plugin which may or may not have hung the loading of the page, might have employed caching, but would certainly have had some overheads. … Not in Jekyll.”
+- [‘My Jekyll Fork’, by Mike West](http://mikewest.org/2009/11/my-jekyll-fork)
+ > “Jekyll is a well-architected throwback to a time before WordPress, when men were men, and HTML was static. I like the ideas it espouses, and have made a few improvements to it’s core. Here, I’ll point out some highlights of my fork in the hopes that they see usage beyond this site.”
+- [‘About this Website’, by Carter Allen](http://cartera.me/2010/08/12/about-this-website/)
+ > “Jekyll is everything that I ever wanted in a blogging engine. Really. It isn’t perfect, but what’s excellent about it is that if there’s something wrong, I know exactly how it works and how to fix it. It runs on the your machine only, and is essentially an added”build" step between you and the browser. I coded this entire site in TextMate using standard HTML5 and CSS3, and then at the end I added just a few little variables to the markup. Presto-chango, my site is built and I am at [...]
+- [Generating a Tag Cloud in Jekyll](http://www.justkez.com/generating-a-tag-cloud-in-jekyll/)
+
+ A guide to implementing a tag cloud and per-tag content pages using Jekyll.
+
+- [Jekyll Extensions -= Pain](http://rfelix.com/2010/01/19/jekyll-extensions-minus-equal-pain/)
+
+ A way to [extend Jekyll](http://github.com/rfelix/jekyll_ext) without forking and modifying the Jekyll gem codebase and some [portable Jekyll extensions](http://wiki.github.com/rfelix/jekyll_ext/extensions) that can be reused and shared.
+
+- [Using your Rails layouts in Jekyll](http://numbers.brighterplanet.com/2010/08/09/sharing-rails-views-with-jekyll)
diff --git a/site/docs/sites.md b/site/docs/sites.md
new file mode 100644
index 0000000..57c927b
--- /dev/null
+++ b/site/docs/sites.md
@@ -0,0 +1,29 @@
+---
+layout: docs
+title: Sites using Jekyll
+prev_section: troubleshooting
+next_section: resources
+permalink: /docs/sites/
+---
+
+It’s interesting to see what designs and features others have come up
+with. Below are some Jekyll-powered blogs which were hand-picked for
+learning purposes.
+
+- [Tom Preston-Werner](http://tom.preston-werner.com/)
+ ([source](http://github.com/mojombo/mojombo.github.com))
+- [Nick Quaranto](http://quaran.to/)
+ ([source](https://github.com/qrush/qrush.github.com))
+- [Roger Chapman](http://rogchap.com/)
+ ([source](https://github.com/rogchap/rogchap.github.com))
+- [GitHub Official Teaching Materials](http://teach.github.com)
+ ([source](https://github.com/github/teach.github.com))
+- [Rasmus Andersson](http://rsms.me/)
+ ([source](https://github.com/rsms/rsms.github.com))
+- [Scott Chacon](http://schacon.github.com)
+ ([source](https://github.com/schacon/schacon.github.com))
+
+If you would like to explore more examples, you can find a list of sites
+and their sources on the ["Sites" page in the Jekyll wiki][jekyll-sites].
+
+[jekyll-sites]: {{ site.repository }}/wiki/Sites
diff --git a/site/docs/structure.md b/site/docs/structure.md
new file mode 100644
index 0000000..d03baee
--- /dev/null
+++ b/site/docs/structure.md
@@ -0,0 +1,190 @@
+---
+layout: docs
+title: Directory structure
+prev_section: usage
+next_section: configuration
+permalink: /docs/structure/
+---
+
+Jekyll is, at its core, a text transformation engine. The concept behind the
+system is this: you give it text written in your favorite markup language, be
+that Markdown, Textile, or just plain HTML, and it churns that through a layout
+or series of layout files. Throughout that process you can tweak how you want
+the site URLs to look, what data gets displayed in the layout, and more. This is
+all done through editing text files, and the static web site is the final
+product.
+
+A basic Jekyll site usually looks something like this:
+
+{% highlight bash %}
+.
+├── _config.yml
+├── _drafts
+| ├── begin-with-the-crazy-ideas.textile
+| └── on-simplicity-in-technology.markdown
+├── _includes
+| ├── footer.html
+| └── header.html
+├── _layouts
+| ├── default.html
+| └── post.html
+├── _posts
+| ├── 2007-10-29-why-every-programmer-should-play-nethack.textile
+| └── 2009-04-26-barcamp-boston-4-roundup.textile
+├── _data
+| └── members.yml
+├── _site
+└── index.html
+{% endhighlight %}
+
+An overview of what each of these does:
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>File / Directory</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>_config.yml</code></p>
+ </td>
+ <td>
+ <p>
+
+ Stores <a href="../configuration/">configuration</a> data. Many of
+ these options can be specified from the command line executable but
+ it’s easier to specify them here so you don’t have to remember them.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>_drafts</code></p>
+ </td>
+ <td>
+ <p>
+
+ Drafts are unpublished posts. The format of these files is without a date: <code>title.MARKUP</code>. Learn how to <a href="../drafts/">work with drafts</a>.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>_includes</code></p>
+ </td>
+ <td>
+ <p>
+
+ These are the partials that can be mixed and matched by your layouts
+ and posts to facilitate reuse. The liquid tag
+ <code>{% raw %}{% include file.ext %}{% endraw %}</code>
+ can be used to include the partial in
+ <code>_includes/file.ext</code>.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>_layouts</code></p>
+ </td>
+ <td>
+ <p>
+
+ These are the templates that wrap posts. Layouts are chosen on a post-
+ by-post basis in the <a href="../frontmatter/">YAML front matter</a>,
+ which is described in the next section. The liquid tag
+ <code>{% raw %}{{ content }}{% endraw %}</code>
+ is used to inject content into the web page.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>_posts</code></p>
+ </td>
+ <td>
+ <p>
+
+ Your dynamic content, so to speak. The format of these files is
+ important, and must follow the format:
+ <code>YEAR-MONTH-DAY-title.MARKUP</code>.
+ The <a href="../permalinks/">permalinks</a> can be customized for each
+ post, but the date and markup language are determined solely by the
+ file name.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>_data</code></p>
+ </td>
+ <td>
+ <p>
+
+ Well-formatted site data should be placed here. The jekyll engine will
+ autoload all yaml files (ends with <code>.yml</code> or <code>.yaml</code>)
+ in this directory. If there's a file <code>members.yml</code> under the directory,
+ then you can access contents of the file through <code>site.data.members</code>.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>_site</code></p>
+ </td>
+ <td>
+ <p>
+
+ This is where the generated site will be placed (by default) once
+ Jekyll is done transforming it. It’s probably a good idea to add this
+ to your <code>.gitignore</code> file.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>index.html</code> and other HTML, Markdown, Textile files</p>
+ </td>
+ <td>
+ <p>
+
+ Provided that the file has a <a href="../frontmatter/">YAML Front
+ Matter</a> section, it will be transformed by Jekyll. The same will
+ happen for any <code>.html</code>, <code>.markdown</code>,
+ <code>.md</code>, or <code>.textile</code> file in your site’s root
+ directory or directories not listed above.
+
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>Other Files/Folders</p>
+ </td>
+ <td>
+ <p>
+
+ Every other directory and file except for those listed above—such as
+ <code>css</code> and <code>images</code> folders,
+ <code>favicon.ico</code> files, and so forth—will be copied verbatim
+ to the generated site. There are plenty of <a href="../sites/">sites
+ already using Jekyll</a> if you’re curious to see how they’re laid
+ out.
+
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
diff --git a/site/docs/templates.md b/site/docs/templates.md
new file mode 100644
index 0000000..7cf2a86
--- /dev/null
+++ b/site/docs/templates.md
@@ -0,0 +1,339 @@
+---
+layout: docs
+title: Templates
+prev_section: migrations
+next_section: permalinks
+permalink: /docs/templates/
+---
+
+Jekyll uses the [Liquid](http://wiki.shopify.com/Liquid) templating language to
+process templates. All of the standard Liquid [tags](http://wiki.shopify.com/Logic) and
+[filters](http://wiki.shopify.com/Filters) are
+supported. Jekyll even adds a few handy filters and tags of its own to make
+common tasks easier.
+
+## Filters
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Description</th>
+ <th><span class="filter">Filter</span> and <span class="output">Output</span></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p class='name'><strong>Date to XML Schema</strong></p>
+ <p>Convert a Date into XML Schema (ISO 8601) format.</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ site.time | date_to_xmlschema }}{% endraw %}</code>
+ </p>
+ <p>
+ <code class='output'>2008-11-07T13:07:54-08:00</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>Date to RFC-822 Format</strong></p>
+ <p>Convert a Date into the RFC-822 format used for RSS feeds.</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ site.time | date_to_rfc822 }}{% endraw %}</code>
+ </p>
+ <p>
+ <code class='output'>Mon, 07 Nov 2008 13:07:54 -0800</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>Date to String</strong></p>
+ <p>Convert a date to short format.</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ site.time | date_to_string }}{% endraw %}</code>
+ </p>
+ <p>
+ <code class='output'>07 Nov 2008</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>Date to Long String</strong></p>
+ <p>Format a date to long format.</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ site.time | date_to_long_string }}{% endraw %}</code>
+ </p>
+ <p>
+ <code class='output'>07 November 2008</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>XML Escape</strong></p>
+ <p>Escape some text for use in XML.</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ page.content | xml_escape }}{% endraw %}</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>CGI Escape</strong></p>
+ <p>
+ CGI escape a string for use in a URL. Replaces any special characters
+ with appropriate %XX replacements.
+ </p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ “foo,bar;baz?” | cgi_escape }}{% endraw %}</code>
+ </p>
+ <p>
+ <code class='output'>foo%2Cbar%3Bbaz%3F</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>URI Escape</strong></p>
+ <p>
+ URI escape a string.
+ </p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ “'foo, bar \\baz?'” | uri_escape }}{% endraw %}</code>
+ </p>
+ <p>
+ <code class='output'>foo,%20bar%20%5Cbaz?</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>Number of Words</strong></p>
+ <p>Count the number of words in some text.</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ page.content | number_of_words }}{% endraw %}</code>
+ </p>
+ <p>
+ <code class='output'>1337</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>Array to Sentence</strong></p>
+ <p>Convert an array into a sentence. Useful for listing tags.</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ page.tags | array_to_sentence_string }}{% endraw %}</code>
+ </p>
+ <p>
+ <code class='output'>foo, bar, and baz</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>Textilize</strong></p>
+ <p>Convert a Textile-formatted string into HTML, formatted via RedCloth</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ page.excerpt | textilize }}{% endraw %}</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>Markdownify</strong></p>
+ <p>Convert a Markdown-formatted string into HTML.</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ page.excerpt | markdownify }}{% endraw %}</code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p class='name'><strong>Data To JSON</strong></p>
+ <p>Convert Hash or Array to JSON.</p>
+ </td>
+ <td class='align-center'>
+ <p>
+ <code class='filter'>{% raw %}{{ site.data.projects | jsonify }}{% endraw %}</code>
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+## Tags
+
+### Includes
+
+If you have small page fragments that you wish to include in multiple places on
+your site, you can use the `include` tag.
+
+{% highlight ruby %}
+{% raw %}{% include footer.html %}{% endraw %}
+{% endhighlight %}
+
+Jekyll expects all include files to be placed in an `_includes` directory at the
+root of your source directory. This will embed the contents of
+`<source>/_includes/footer.html` into the calling file.
+
+<div class="note">
+ <h5>ProTip™: Use variables as file name</h5>
+ <p>
+
+ The name of the file you wish to embed can be literal (as in the example above),
+ or you can use a variable, using liquid-like variable syntax as in
+ <code>{% raw %}{% include {{my_variable}} %}{% endraw %}</code>.
+
+ Note that unlike usual liquid variable syntax, you cannot have spaces inside the curly braces.
+
+ </p>
+</div>
+
+You can also pass parameters to an include:
+
+{% highlight ruby %}
+{% raw %}{% include footer.html param="value" %}{% endraw %}
+{% endhighlight %}
+
+These parameters are available via Liquid in the include:
+
+{% highlight ruby %}
+{% raw %}{{ include.param }}{% endraw %}
+{% endhighlight %}
+
+### Code snippet highlighting
+
+Jekyll has built in support for syntax highlighting of [over 100
+languages](http://pygments.org/languages/) thanks to
+[Pygments](http://pygments.org/). To use Pygments, you must have Python installed on your
+system and set `pygments` to `true` in your site's configuration file.
+
+To render a code block with syntax highlighting, surround your code as follows:
+
+{% highlight text %}
+{% raw %}
+{% highlight ruby %}
+def foo
+ puts 'foo'
+end
+{% endhighlight %}
+{% endraw %}
+{% endhighlight %}
+
+The argument to the `highlight` tag (`ruby` in the example above) is the
+language identifier. To find the appropriate identifier to use for the language
+you want to highlight, look for the “short name” on the [Lexers
+page](http://pygments.org/docs/lexers/).
+
+#### Line numbers
+
+There is a second argument to `highlight` called `linenos` that is optional.
+Including the `linenos` argument will force the highlighted code to include line
+numbers. For instance, the following code block would include line numbers next
+to each line:
+
+{% highlight text %}
+{% raw %}
+{% highlight ruby linenos %}
+def foo
+ puts 'foo'
+end
+{% endhighlight %}
+{% endraw %}
+{% endhighlight %}
+
+#### Stylesheets for syntax highlighting
+
+In order for the highlighting to show up, you’ll need to include a highlighting
+stylesheet. For an example stylesheet you can look at
+[syntax.css](http://github.com/mojombo/tpw/tree/master/css/syntax.css). These
+are the same styles as used by GitHub and you are free to use them for your own
+site. If you use `linenos`, you might want to include an additional CSS class
+definition for the `.lineno` class in `syntax.css` to distinguish the line
+numbers from the highlighted code.
+
+### Post URL
+
+If you would like to include a link to a post on your site, the `post_url` tag
+will generate the correct permalink URL for the post you specify.
+
+{% highlight text %}
+{% raw %}
+{% post_url 2010-07-21-name-of-post %}
+{% endraw %}
+{% endhighlight %}
+
+If you organize your posts in subdirectories, you need to include subdirectory
+path to the post:
+
+{% highlight text %}
+{% raw %}
+{% post_url /subdir/2010-07-21-name-of-post %}
+{% endraw %}
+{% endhighlight %}
+
+There is no need to include the file extension when using the `post_url` tag.
+
+You can also use this tag to create a link to a post in Markdown as follows:
+
+{% highlight text %}
+{% raw %}
+[Name of Link]({% post_url 2010-07-21-name-of-post %})
+{% endraw %}
+{% endhighlight %}
+
+### Gist
+
+Use the `gist` tag to easily embed a GitHub Gist onto your site:
+
+{% highlight text %}
+{% raw %}
+{% gist 5555251 %}
+{% endraw %}
+{% endhighlight %}
+
+You may also optionally specify the filename in the gist to display:
+
+{% highlight text %}
+{% raw %}
+{% gist 5555251 result.md %}
+{% endraw %}
+{% endhighlight %}
+
+The `gist` tag also works with private gists, which require the gist owner's
+github username:
+
+{% highlight text %}
+{% raw %}
+{% gist parkr/931c1c8d465a04042403 %}
+{% endraw %}
+{% endhighlight %}
+
+The private gist syntax also supports filenames.
diff --git a/site/docs/troubleshooting.md b/site/docs/troubleshooting.md
new file mode 100644
index 0000000..836e1ea
--- /dev/null
+++ b/site/docs/troubleshooting.md
@@ -0,0 +1,150 @@
+---
+layout: docs
+title: Troubleshooting
+prev_section: deployment-methods
+next_section: sites
+permalink: /docs/troubleshooting/
+---
+
+If you ever run into problems installing or using Jekyll, here's a few tips
+that might be of help. If the problem you’re experiencing isn’t covered below,
+please [report an issue]({{ site.repository }}/issues/new) so the
+Jekyll community can make everyone’s experience better.
+
+## Installation Problems
+
+If you encounter errors during gem installation, you may need to install
+the header files for compiling extension modules for ruby 1.9.1. This
+can be done on Ubuntu or Debian by running:
+
+{% highlight bash %}
+sudo apt-get install ruby1.9.1-dev
+{% endhighlight %}
+
+On Red Hat, CentOS, and Fedora systems you can do this by running:
+
+{% highlight bash %}
+sudo yum install ruby-devel
+{% endhighlight %}
+
+On [NearlyFreeSpeech](http://nearlyfreespeech.net/) you need to run the
+command with the following environment variable:
+
+{% highlight bash %}
+RB_USER_INSTALL=true gem install jekyll
+{% endhighlight %}
+
+On OSX, you may need to update RubyGems:
+
+{% highlight bash %}
+sudo gem update --system
+{% endhighlight %}
+
+If you still have issues, you may need to [use XCode to install Command Line
+Tools](http://www.zlu.me/blog/2012/02/21/install-native-ruby-gem-in-mountain-lion-preview/)
+that will allow you to install native gems using the following command:
+
+{% highlight bash %}
+sudo gem install jekyll
+{% endhighlight %}
+
+To install RubyGems on Gentoo:
+
+{% highlight bash %}
+sudo emerge -av dev-ruby/rubygems
+{% endhighlight %}
+
+On Windows, you may need to install [RubyInstaller
+DevKit](http://wiki.github.com/oneclick/rubyinstaller/development-kit).
+
+## Problems running Jekyll
+
+On Debian or Ubuntu, you may need to add `/var/lib/gems/1.8/bin/` to your path
+in order to have the `jekyll` executable be available in your Terminal.
+
+## Base-URL Problems
+
+If you are using base-url option like:
+
+{% highlight bash %}
+jekyll serve --baseurl '/blog'
+{% endhighlight %}
+
+… then make sure that you access the site at:
+
+{% highlight bash %}
+http://localhost:4000/blog/index.html
+{% endhighlight %}
+
+It won’t work to just access:
+
+{% highlight bash %}
+http://localhost:4000/blog
+{% endhighlight %}
+
+## Configuration problems
+
+The order of precedence for conflicting [configuration settings](../configuration/)
+is as follows:
+
+1. Command-line flags
+2. Configuration file settings
+3. Defaults
+
+That is: defaults are overridden by options specified in `_config.yml`,
+and flags specified at the command-line will override all other settings
+specified elsewhere.
+
+## Markup Problems
+
+The various markup engines that Jekyll uses may have some issues. This
+page will document them to help others who may run into the same
+problems.
+
+### Maruku
+
+If your link has characters that need to be escaped, you need to use
+this syntax:
+
+{% highlight text %}
+
+{% endhighlight %}
+
+If you have an empty tag, i.e. `<script src="js.js"></script>`, Maruku
+transforms this into `<script src="js.js" />`. This causes problems in
+Firefox and possibly other browsers and is [discouraged in
+XHTML.](http://www.w3.org/TR/xhtml1/#C_3) An easy fix is to put a space
+between the opening and closing tags.
+
+### RedCloth
+
+Versions 4.1.1 and higher do not obey the notextile tag. [This is a known
+bug](http://aaronqian.com/articles/2009/04/07/redcloth-ate-my-notextile.html)
+and will hopefully be fixed for 4.2. You can still use 4.1.9, but the
+test suite requires that 4.1.0 be installed. If you use a version of
+RedCloth that does not have the notextile tag, you may notice that
+syntax highlighted blocks from Pygments are not formatted correctly,
+among other things. If you’re seeing this just install 4.1.0.
+
+### Liquid
+
+The latest version, version 2.0, seems to break the use of `{{ "{{" }}` in
+templates. Unlike previous versions, using `{{ "{{" }}` in 2.0 triggers the
+following error:
+
+{% highlight bash %}
+'{{ "{{" }}' was not properly terminated with regexp: /\}\}/ (Liquid::SyntaxError)
+{% endhighlight %}
+
+### Excerpts
+
+Since v1.0.0, Jekyll has had automatically-generated post excerpts. Since
+v1.1.0, Jekyll also passes these excerpts through Liquid, which can cause
+strange errors where references don't exist or a tag hasn't been closed. If you
+run into these errors, try setting `excerpt_separator: ""` in your
+`_config.yml`, or set it to some nonsense string.
+
+<div class="note">
+ <h5>Please report issues you encounter!</h5>
+ <p>If you come across a bug, please <a href="{{ site.repository }}/issues/new">create an issue</a> on GitHub describing the problem and any work-arounds you find so we can document it here for others.</p>
+</div>
diff --git a/site/docs/upgrading.md b/site/docs/upgrading.md
new file mode 100644
index 0000000..3cf5a1e
--- /dev/null
+++ b/site/docs/upgrading.md
@@ -0,0 +1,146 @@
+---
+layout: docs
+title: Upgrading
+prev_section: resources
+next_section: contributing
+permalink: /docs/upgrading/
+---
+
+Upgrading from an older version of Jekyll? A few things have changed in 1.0
+that you'll want to know about.
+
+Before we dive in, go ahead and fetch the latest version of Jekyll:
+
+{% highlight bash %}
+$ gem update jekyll
+{% endhighlight %}
+
+<div class="note feature">
+ <h5 markdown="1">Diving in</h5>
+ <p markdown="1">Want to get a new Jekyll site up and running quickly? Simply
+ run <code>jekyll new SITENAME</code> to create a new folder with a bare bones
+ Jekyll site.</p>
+</div>
+
+### The Jekyll Command
+
+For better clarity, Jekyll now accepts the commands `build` and `serve`.
+Whereas before you might simply run the command `jekyll` to generate a site
+and `jekyll --server` to view it locally, now use the subcommands `jekyll build`
+and `jekyll serve` to do the same. And if you want Jekyll to automatically
+rebuild each time a file changes, just add the `--watch` flag at the end.
+
+<div class="note info">
+ <h5>Watching and Serving</h5>
+ <p markdown="1">With the new subcommands, the way sites are previewed locally
+ changed a bit. Instead of specifying `server: true` in the site's
+ configuration file, use `jekyll serve`. The same hold's true for
+ `watch: true`. Instead, use the `--watch` flag with either `jekyll serve`
+ or `jekyll build`.</p>
+</div>
+
+### Absolute Permalinks
+
+In Jekyll v1.0, we introduced absolute permalinks for pages in subdirectories.
+Until v2.0, it is **opt-in**. Starting with v2.0, however, absolute permalinks
+will become **opt-out**, meaning Jekyll will default to using absolute permalinks
+instead of relative permalinks.
+
+* To use absolute permalinks, set `relative_permalinks: false` in your configuration file.
+* To continue using relative permalinks, set `relative_permalinks: true` in your configuration file.
+
+<div class="note warning" id="absolute-permalinks-warning">
+ <h5 markdown="1">Absolute permalinks will be default in v2.0 and on</h5>
+ <p markdown="1">
+ Starting with Jekyll v2.0, `relative_permalinks` will default to `false`,
+ meaning all pages will be built using the absolute permalink behaviour.
+ The switch will still exist until v2.0.
+ </p>
+</div>
+
+### Draft Posts
+
+Jekyll now lets you write draft posts, and allows you to easily preview how
+they will look prior to publishing. To start a draft, simply create a folder
+called `_drafts` in your site's source directory (e.g., alongside `_posts`),
+and add a new markdown file to it. To preview your new post, simply run the
+`jekyll serve` command with the `--drafts` flag.
+
+<div class="note info">
+ <h5 markdown="1">Drafts don't have dates</h5>
+ <p markdown="1">
+ Unlike posts, drafts don't have a date, since they haven't
+ been published yet. Rather than naming your draft something like
+ `2013-07-01-my-draft-post.md`, simply name the file what you'd like your
+ post to eventually be titled, here `my-draft-post.md`.</p>
+</div>
+
+### Custom Config File
+
+Rather than passing individual flags via the command line, you can now pass an
+entire custom Jekyll config file. This helps to distinguish between
+environments, or lets you programmatically override user-specified defaults.
+Simply add the `--config` flag to the `jekyll` command, followed by the path
+to one or more config files (comma-delimited, no spaces).
+
+#### As a result, the following command line flags are now deprecated:
+
+* `--no-server`
+* `--no-auto`
+* `--auto` (now `--watch`)
+* `--server`
+* `--url=`
+* `--maruku`, `--rdiscount`, and `--redcarpet`
+* `--pygments`
+* `--permalink=`
+* `--paginate`
+
+<div class="note info">
+ <h5>The config flag explicitly specifies your configuration file(s)</h5>
+ <p markdown="1">If you use the `--config` flag, Jekyll will ignore your
+ `_config.yml` file. Want to merge a custom configuration with the normal
+ configuration? No problem. Jekyll will accept more than one custom config
+ file via the command line. Config files cascade from right to left, such
+ that if I run `jekyll serve --config _config.yml,_config-dev.yml`,
+ the values in the config files on the right (`_config-dev.yml`) overwrite
+ those on the left (`_config.yml`) when both contain the same key.</p>
+</div>
+
+### New Config File Options
+
+Jekyll 1.0 introduced several new config file options. Before you upgrade, you
+should check to see if any of these are present in your pre-1.0 config file, and
+if so, make sure that you're using them properly:
+
+* `excerpt_separator`
+* `host`
+* `include`
+* `keep_files`
+* `layouts`
+* `show_drafts`
+* `timezone`
+* `url`
+
+### Baseurl
+
+Often, you'll want the ability to run a Jekyll site in multiple places, such as
+previewing locally before pushing to GitHub Pages. Jekyll 1.0 makes that
+easier with the new `--baseurl` flag. To take advantage of this feature, first
+add the production `baseurl` to your site's `_config.yml` file. Then,
+throughout the site, simply prefix relative URLs with `{% raw %}{{ site.baseurl }}{% endraw %}`.
+When you're ready to preview your site locally, pass along the `--baseurl` flag
+with your local baseurl (most likely `/`) to `jekyll serve` and Jekyll will
+swap in whatever you've passed along, ensuring all your links work as you'd
+expect in both environments.
+
+
+<div class="note warning">
+ <h5 markdown="1">All page and post URLs contain leading slashes</h5>
+ <p markdown="1">If you use the method described above, please remember
+ that the URLs for all posts and pages contain a leading slash. Therefore,
+ concatenating the site baseurl and the post/page url where
+ `site.baseurl = /` and `post.url = /2013/06/05/my-fun-post/` will
+ result in two leading slashes, which will break links. It is thus
+ suggested that prefixing with `site.baseurl` only be used when the
+ `baseurl` is something other than the default of `/`.</p>
+</div>
diff --git a/site/docs/usage.md b/site/docs/usage.md
new file mode 100644
index 0000000..6db3a11
--- /dev/null
+++ b/site/docs/usage.md
@@ -0,0 +1,63 @@
+---
+layout: docs
+title: Basic Usage
+prev_section: installation
+next_section: structure
+permalink: /docs/usage/
+---
+
+The Jekyll gem makes a `jekyll` executable available to you in your Terminal
+window. You can use this command in a number of ways:
+
+{% highlight bash %}
+$ jekyll build
+# => The current folder will be generated into ./_site
+
+$ jekyll build --destination <destination>
+# => The current folder will be generated into <destination>
+
+$ jekyll build --source <source> --destination <destination>
+# => The <source> folder will be generated into <destination>
+
+$ jekyll build --watch
+# => The current folder will be generated into ./_site,
+# watched for changes, and regenerated automatically.
+{% endhighlight %}
+
+Jekyll also comes with a built-in development server that will allow you to
+preview what the generated site will look like in your browser locally.
+
+{% highlight bash %}
+$ jekyll serve
+# => A development server will run at http://localhost:4000/
+
+$ jekyll serve --detach
+# => Same as `jekyll serve` but will detach from the current terminal.
+# If you need to kill the server, you can `kill -9 1234` where "1234" is the PID.
+# If you cannot find the PID, then do, `ps aux | grep jekyll` and kill the instance. [Read more](http://unixhelp.ed.ac.uk/shell/jobz5.html).
+
+$ jekyll serve --watch
+# => Same as `jekyll serve`, but watch for changes and regenerate automatically.
+{% endhighlight %}
+
+These are just a few of the available [configuration options](../configuration/).
+Many configuration options can either be specified as flags on the command line,
+or alternatively (and more commonly) they can be specified in a `_config.yml`
+file at the root of the source directory. Jekyll will automatically use the
+options from this file when run. For example, if you place the following lines
+in your `_config.yml` file:
+
+{% highlight yaml %}
+source: _source
+destination: _deploy
+{% endhighlight %}
+
+Then the following two commands will be equivalent:
+
+{% highlight bash %}
+$ jekyll build
+$ jekyll build --source _source --destination _deploy
+{% endhighlight %}
+
+For more about the possible configuration options, see the
+[configuration](../configuration/) page.
diff --git a/site/docs/variables.md b/site/docs/variables.md
new file mode 100644
index 0000000..89e11a5
--- /dev/null
+++ b/site/docs/variables.md
@@ -0,0 +1,322 @@
+---
+layout: docs
+title: Variables
+prev_section: pages
+next_section: datafiles
+permalink: /docs/variables/
+---
+
+Jekyll traverses your site looking for files to process. Any files with [YAML
+Front Matter](../frontmatter/) are subject to processing. For each of these
+files, Jekyll makes a variety of data available via the [Liquid templating
+system](http://wiki.shopify.com/Liquid). The
+following is a reference of the available data.
+
+## Global Variables
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Variable</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><p><code>site</code></p></td>
+ <td><p>
+
+ Sitewide information + configuration settings from
+ <code>_config.yml</code>. See below for details.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>page</code></p></td>
+ <td><p>
+
+ Page specific information + the <a href="../frontmatter/">YAML Front
+ Matter</a>. Custom variables set via the YAML front matter will be
+ available here. See below for details.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>content</code></p></td>
+ <td><p>
+
+ In layout files, the rendered content of the Post or Page being wrapped.
+ Not defined in Post or Page files.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>paginator</code></p></td>
+ <td><p>
+
+ When the <code>paginate</code> configuration option is set, this
+ variable becomes available for use. See <a
+ href="../pagination/">Pagination</a> for details.
+
+ </p></td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+## Site Variables
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Variable</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><p><code>site.time</code></p></td>
+ <td><p>
+
+ The current time (when you run the <code>jekyll</code> command).
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>site.pages</code></p></td>
+ <td><p>
+
+ A list of all Pages.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>site.posts</code></p></td>
+ <td><p>
+
+ A reverse chronological list of all Posts.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>site.related_posts</code></p></td>
+ <td><p>
+
+ If the page being processed is a Post, this contains a list of up to ten
+ related Posts. By default, these are low quality but fast to compute.
+ For high quality but slow to compute results, run the
+ <code>jekyll</code> command with the <code>--lsi</code> (latent semantic
+ indexing) option.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>site.categories.CATEGORY</code></p></td>
+ <td><p>
+
+ The list of all Posts in category <code>CATEGORY</code>.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>site.tags.TAG</code></p></td>
+ <td><p>
+
+ The list of all Posts with tag <code>TAG</code>.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>site.[CONFIGURATION_DATA]</code></p></td>
+ <td><p>
+
+ All the variables set via the command line and your
+ <code>_config.yml</code> are available through the <code>site</code>
+ variable. For example, if you have <code>url: http://mysite.com</code>
+ in your configuration file, then in your Posts and Pages it will be
+ stored in <code>site.url</code>. Jekyll does not parse changes to
+ <code>_config.yml</code> in <code>watch</code> mode, you must restart
+ Jekyll to see changes to variables.
+
+ </p></td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+## Page Variables
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Variable</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><p><code>page.content</code></p></td>
+ <td><p>
+
+ The un-rendered content of the Page.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>page.title</code></p></td>
+ <td><p>
+
+ The title of the Page.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>page.excerpt</code></p></td>
+ <td><p>
+
+ The un-rendered excerpt of the Page.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>page.url</code></p></td>
+ <td><p>
+
+ The URL of the Post without the domain, but
+ with a leading slash, e.g.
+ <code>/2008/12/14/my-post.html</code>
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>page.date</code></p></td>
+ <td><p>
+
+ The Date assigned to the Post. This can be overridden in a Post’s front
+ matter by specifying a new date/time in the format
+ <code>YYYY-MM-DD HH:MM:SS</code> (assuming UTC), or
+ <code>YYYY-MM-DD HH:MM:SS +/-TTTT</code> (to specify a time zone using
+ an offset from UTC. e.g. <code>2008-12-14 10:30:00 +0900</code>).
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>page.id</code></p></td>
+ <td><p>
+
+ An identifier unique to the Post (useful in RSS feeds). e.g.
+ <code>/2008/12/14/my-post</code>
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>page.categories</code></p></td>
+ <td><p>
+
+ The list of categories to which this post belongs. Categories are
+ derived from the directory structure above the <code>_posts</code>
+ directory. For example, a post at
+ <code>/work/code/_posts/2008-12-24-closures.md</code> would have this
+ field set to <code>['work', 'code']</code>. These can also be specified
+ in the <a href="../frontmatter/">YAML Front Matter</a>.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>page.tags</code></p></td>
+ <td><p>
+
+ The list of tags to which this post belongs. These can be specified in
+ the <a href="../frontmatter/">YAML Front Matter</a>.
+
+ </p></td>
+ </tr>
+ <tr>
+ <td><p><code>page.path</code></p></td>
+ <td><p>
+
+ The path to the raw post or page. Example usage: Linking back to the
+ page or post’s source on GitHub. This can be overridden in the
+ <a href="../frontmatter/">YAML Front Matter</a>.
+
+ </p></td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<div class="note">
+ <h5>ProTip™: Use custom front-matter</h5>
+ <p>
+
+ Any custom front matter that you specify will be available under
+ <code>page</code>. For example, if you specify <code>custom_css: true</code>
+ in a page’s front matter, that value will be available as
+ <code>page.custom_css</code>.
+
+ </p>
+</div>
+
+## Paginator
+
+<div class="mobile-side-scroller">
+<table>
+ <thead>
+ <tr>
+ <th>Variable</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><p><code>paginator.per_page</code></p></td>
+ <td><p>Number of Posts per page.</p></td>
+ </tr>
+ <tr>
+ <td><p><code>paginator.posts</code></p></td>
+ <td><p>Posts available for that page.</p></td>
+ </tr>
+ <tr>
+ <td><p><code>paginator.total_posts</code></p></td>
+ <td><p>Total number of Posts.</p></td>
+ </tr>
+ <tr>
+ <td><p><code>paginator.total_pages</code></p></td>
+ <td><p>Total number of Pages.</p></td>
+ </tr>
+ <tr>
+ <td><p><code>paginator.page</code></p></td>
+ <td><p>The number of the current page.</p></td>
+ </tr>
+ <tr>
+ <td><p><code>paginator.previous_page</code></p></td>
+ <td><p>The number of the previous page.</p></td>
+ </tr>
+ <tr>
+ <td><p><code>paginator.previous_page_path</code></p></td>
+ <td><p>The path to the previous page.</p></td>
+ </tr>
+ <tr>
+ <td><p><code>paginator.next_page</code></p></td>
+ <td><p>The number of the next page.</p></td>
+ </tr>
+ <tr>
+ <td><p><code>paginator.next_page_path</code></p></td>
+ <td><p>The path to the next page.</p></td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<div class="note info">
+ <h5>Paginator variable availability</h5>
+ <p>
+
+ These are only available in index files, however they can be located in a
+ subdirectory, such as <code>/blog/index.html</code>.
+
+ </p>
+</div>
diff --git a/site/favicon.png b/site/favicon.png
new file mode 100644
index 0000000..4443b67
Binary files /dev/null and b/site/favicon.png differ
diff --git a/site/feed.xml b/site/feed.xml
new file mode 100644
index 0000000..2f4dfcf
--- /dev/null
+++ b/site/feed.xml
@@ -0,0 +1,36 @@
+---
+layout: none
+permalink: /feed.xml
+---
+
+<?xml version="1.0" encoding="utf-8"?>
+<rss version="2.0"
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
+ xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
+ >
+<channel>
+ <title xml:lang="en">Jekyll • Simple, blog-aware, static sites</title>
+ <atom:link type="application/atom+xml" href="http://jekyllrb.com/feed/" rel="self"/>
+ <link>http://jekyllrb.com</link>
+ <pubDate>{{ site.time | date: "%a, %d %b %Y %H:%M:%S %z" }}</pubDate>
+ <lastBuildDate>{{ site.time | date: "%a, %d %b %Y %H:%M:%S %z" }}</lastBuildDate>
+ <language>en-US</language>
+ <description>Transform your plain text into static websites and blogs.</description>
+ {% for post in site.posts %}
+ <item>
+ <title>{{ post.title | xml_escape}}</title>
+ <link>http://jekyllrb.com{{ post.url }}</link>
+ <pubDate>{{ post.date | date: "%a, %d %b %Y %H:%M:%S %z" }}</pubDate>
+ <dc:creator>{{ post.author }}</dc:creator>
+ {% for tag in post.tags %}<category>{{ tag | xml_escape }}</category>
+ {% endfor %}{% for cat in post.categories %}<category>{{ cat | xml_escape }}</category>
+ {% endfor %}<guid isPermaLink="false">{{ post.id }}</guid>
+ <description><![CDATA[ {{ post.content }} ]]></description>
+ </item>
+ {% endfor %}
+</channel>
+</rss>
diff --git a/site/freenode.txt b/site/freenode.txt
new file mode 100644
index 0000000..898ed72
--- /dev/null
+++ b/site/freenode.txt
@@ -0,0 +1 @@
+aS3gAc4g
diff --git a/site/img/article-footer.png b/site/img/article-footer.png
new file mode 100644
index 0000000..3f97403
Binary files /dev/null and b/site/img/article-footer.png differ
diff --git a/site/img/footer-arrow.png b/site/img/footer-arrow.png
new file mode 100644
index 0000000..048e37d
Binary files /dev/null and b/site/img/footer-arrow.png differ
diff --git a/site/img/footer-logo.png b/site/img/footer-logo.png
new file mode 100644
index 0000000..210babb
Binary files /dev/null and b/site/img/footer-logo.png differ
diff --git a/site/img/logo-2x.png b/site/img/logo-2x.png
new file mode 100644
index 0000000..bc84a9e
Binary files /dev/null and b/site/img/logo-2x.png differ
diff --git a/site/img/octojekyll.png b/site/img/octojekyll.png
new file mode 100644
index 0000000..dad6dbd
Binary files /dev/null and b/site/img/octojekyll.png differ
diff --git a/site/img/tube.png b/site/img/tube.png
new file mode 100644
index 0000000..bb0ba9c
Binary files /dev/null and b/site/img/tube.png differ
diff --git a/site/img/tube1x.png b/site/img/tube1x.png
new file mode 100644
index 0000000..104c28b
Binary files /dev/null and b/site/img/tube1x.png differ
diff --git a/site/index.html b/site/index.html
new file mode 100644
index 0000000..fb8e802
--- /dev/null
+++ b/site/index.html
@@ -0,0 +1,90 @@
+---
+layout: default
+title: Jekyll • Simple, blog-aware, static sites
+overview: true
+---
+
+<section class="intro">
+ <div class="grid">
+ <div class="unit whole center-on-mobiles">
+ <p class="first">Transform your plain text into static websites and blogs.</p>
+ </div>
+ </div>
+</section>
+<section class="features">
+ <div class="grid">
+ <div class="unit one-third">
+ <h2>Simple</h2>
+ <p>
+ No more databases, comment moderation, or pesky updates to install—just <em>your content</em>.
+ </p>
+ <a href="/docs/usage/" class="">How Jekyll works →</a>
+ </div>
+ <div class="unit one-third">
+ <h2>Static</h2>
+ <p><a href="http://daringfireball.net/projects/markdown/">Markdown</a> (or <a href="http://textile.sitemonks.com/">Textile</a>), <a href="http://wiki.shopify.com/Liquid">Liquid</a>, HTML <span class="amp">&</span> CSS go in. Static sites come out ready for deployment.</p>
+ <a href="/docs/templates/" class="">Jekyll template guide →</a>
+ </div>
+ <div class="unit one-third">
+ <h2>Blog-aware</h2>
+ <p>
+ Permalinks, categories, pages, posts, and custom layouts are all first-class citizens here.
+ </p>
+ <a href="/docs/migrations/" class="">Migrate your blog →</a>
+ </div>
+ <div class="clear"></div>
+ </div>
+</section>
+<section class="quickstart">
+ <div class="grid">
+ <div class="unit golden-small center-on-mobiles">
+ <h4>Get up and running <em>in seconds</em>.</h4>
+ </div>
+ <div class="unit golden-large code">
+ <p class="title">Quick-start Instructions</p>
+ <div class="shell">
+ <p class="line">
+ <span class="path">~</span>
+ <span class="prompt">$</span>
+ <span class="command">gem install jekyll</span>
+ </p>
+ <p class="line">
+ <span class="path">~</span>
+ <span class="prompt">$</span>
+ <span class="command">jekyll new my-awesome-site</span>
+ </p>
+ <p class="line">
+ <span class="path">~</span>
+ <span class="prompt">$</span>
+ <span class="command">cd my-awesome-site</span>
+ </p>
+ <p class="line">
+ <span class="path">~/my-awesome-site</span>
+ <span class="prompt">$</span>
+ <span class="command">jekyll serve</span>
+ </p>
+ <p class="line">
+ <span class="output"># => Now browse to http://localhost:4000</span>
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+</section>
+<section class="free-hosting">
+ <div class="grid">
+ <div class="unit whole">
+ <div class="grid pane">
+ <div class="unit whole center-on-mobiles">
+ <img src="img/octojekyll.png" alt="Free Jekyll hosting on GitHub Pages">
+ <div class="pane-content">
+ <h2 class="center-on-mobiles"><strong>Free hosting</strong> with GitHub Pages</h2>
+ <p>Sick of dealing with hosting companies? <a href="http://pages.github.com/">GitHub Pages</a> are <em>powered by Jekyll</em>, so you can easily deploy your site using GitHub for free—<a href="https://help.github.com/articles/setting-up-a-custom-domain-with-pages">custom domain name</a> and all.</p>
+ <a href="http://pages.github.com/" class="">Learn more about GitHub Pages →</a>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ </div>
+</section>
diff --git a/site/js/modernizr-2.5.3.min.js b/site/js/modernizr-2.5.3.min.js
new file mode 100755
index 0000000..27fcdae
--- /dev/null
+++ b/site/js/modernizr-2.5.3.min.js
@@ -0,0 +1,4 @@
+/* Modernizr 2.5.3 (Custom Build) | MIT & BSD
+ * Build: http://www.modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippat [...]
+ */
+;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a)if(j[a[d]]!==c)return b=="pfx"?a[d]:!0;return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.substr(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b, [...]
diff --git a/site/news/index.html b/site/news/index.html
new file mode 100644
index 0000000..94139fc
--- /dev/null
+++ b/site/news/index.html
@@ -0,0 +1,10 @@
+---
+layout: news
+title: News
+permalink: /news/
+author: all
+---
+
+{% for post in site.posts %}
+ {% include news_item.html %}
+{% endfor %}
diff --git a/site/news/releases/index.html b/site/news/releases/index.html
new file mode 100644
index 0000000..153d022
--- /dev/null
+++ b/site/news/releases/index.html
@@ -0,0 +1,10 @@
+---
+layout: news
+title: Releases
+permalink: /news/releases/
+author: all
+---
+
+{% for post in site.categories.release %}
+ {% include news_item.html %}
+{% endfor %}
diff --git a/test/fixtures/broken_front_matter1.erb b/test/fixtures/broken_front_matter1.erb
new file mode 100644
index 0000000..c18befb
--- /dev/null
+++ b/test/fixtures/broken_front_matter1.erb
@@ -0,0 +1,5 @@
+# Some stuff on the first line
+---
+test: good
+---
+Real content starts here
diff --git a/test/fixtures/broken_front_matter2.erb b/test/fixtures/broken_front_matter2.erb
new file mode 100644
index 0000000..f895dd2
--- /dev/null
+++ b/test/fixtures/broken_front_matter2.erb
@@ -0,0 +1,4 @@
+---
+bad yaml: [
+---
+Real content starts here
diff --git a/test/fixtures/broken_front_matter3.erb b/test/fixtures/broken_front_matter3.erb
new file mode 100644
index 0000000..5fff53b
--- /dev/null
+++ b/test/fixtures/broken_front_matter3.erb
@@ -0,0 +1,7 @@
+---
+test: good
+---
+Real content starts here
+
+������� �����
+
diff --git a/test/fixtures/exploit_front_matter.erb b/test/fixtures/exploit_front_matter.erb
new file mode 100644
index 0000000..604a7ae
--- /dev/null
+++ b/test/fixtures/exploit_front_matter.erb
@@ -0,0 +1,4 @@
+---
+test: !ruby/hash:DoesNotExist {}
+---
+Real content starts here
diff --git a/test/fixtures/front_matter.erb b/test/fixtures/front_matter.erb
new file mode 100644
index 0000000..96e46a0
--- /dev/null
+++ b/test/fixtures/front_matter.erb
@@ -0,0 +1,4 @@
+---
+test: good
+---
+Real content starts here
diff --git a/test/helper.rb b/test/helper.rb
index c6a8a76..5eb4193 100644
--- a/test/helper.rb
+++ b/test/helper.rb
@@ -1,4 +1,15 @@
+if RUBY_VERSION > '1.9'
+ require 'simplecov'
+ require 'simplecov-gem-adapter'
+ SimpleCov.start('gem')
+
+ require 'coveralls'
+ Coveralls.wear_merged!
+end
+
require 'rubygems'
+require 'test/unit'
+require 'ostruct'
gem 'RedCloth', '>= 4.2.1'
require 'jekyll'
@@ -21,14 +32,34 @@ class Test::Unit::TestCase
include RR::Adapters::TestUnit
def dest_dir(*subdirs)
- File.join(File.dirname(__FILE__), 'dest', *subdirs)
+ test_dir('dest', *subdirs)
end
def source_dir(*subdirs)
- File.join(File.dirname(__FILE__), 'source', *subdirs)
+ test_dir('source', *subdirs)
end
def clear_dest
FileUtils.rm_rf(dest_dir)
end
+
+ def test_dir(*subdirs)
+ File.join(File.dirname(__FILE__), *subdirs)
+ end
+
+ def directory_with_contents(path)
+ FileUtils.rm_rf(path)
+ FileUtils.mkdir(path)
+ File.open("#{path}/index.html", "w"){ |f| f.write("I was previously generated.") }
+ end
+
+ def capture_stdout
+ $old_stdout = $stdout
+ $stdout = StringIO.new
+ yield
+ $stdout.rewind
+ return $stdout.string
+ ensure
+ $stdout = $old_stdout
+ end
end
diff --git a/test/source/+/foo.md b/test/source/+/foo.md
new file mode 100644
index 0000000..cb4f8ce
--- /dev/null
+++ b/test/source/+/foo.md
@@ -0,0 +1,7 @@
+---
+layout: default
+title : Page inside +
+permalink: plus+in+url
+---
+Line 1
+{{ page.title }}
diff --git a/test/source/_config.dev.toml b/test/source/_config.dev.toml
new file mode 100644
index 0000000..7ac863f
--- /dev/null
+++ b/test/source/_config.dev.toml
@@ -0,0 +1,2 @@
+baseurl = "/you-beautiful-blog-you"
+title = "My magnificent site, wut"
diff --git a/test/source/_data/languages.yml b/test/source/_data/languages.yml
new file mode 100644
index 0000000..6b0a250
--- /dev/null
+++ b/test/source/_data/languages.yml
@@ -0,0 +1,2 @@
+- java
+- ruby
diff --git a/test/source/_data/members.yaml b/test/source/_data/members.yaml
new file mode 100644
index 0000000..22e29a9
--- /dev/null
+++ b/test/source/_data/members.yaml
@@ -0,0 +1,7 @@
+- name: Jack
+ age: 27
+ blog: http://example.com/jack
+
+- name: John
+ age: 32
+ blog: http://example.com/john
diff --git a/test/source/_data/products.yml b/test/source/_data/products.yml
new file mode 100644
index 0000000..21828a0
--- /dev/null
+++ b/test/source/_data/products.yml
@@ -0,0 +1,4 @@
+- name: sugar
+ price: 5.3
+- name: salt
+ price: 2.5
diff --git a/test/source/_includes/params.html b/test/source/_includes/params.html
new file mode 100644
index 0000000..65a0001
--- /dev/null
+++ b/test/source/_includes/params.html
@@ -0,0 +1,7 @@
+<span id='include-param'>{{include.param}}</span>
+
+<ul id='param-list'>
+ {% for param in include %}
+ <li>{{param[0]}} = {{param[1]}}</li>
+ {% endfor %}
+</ul>
\ No newline at end of file
diff --git a/test/source/_layouts/default.html b/test/source/_layouts/default.html
index f3422d3..1d51c49 100644
--- a/test/source/_layouts/default.html
+++ b/test/source/_layouts/default.html
@@ -19,7 +19,7 @@
<div class="title">
Tom Preston-Werner
</div>
-
+
{{ content }}
</div>
diff --git a/test/source/_layouts/post/simple.html b/test/source/_layouts/post/simple.html
new file mode 100644
index 0000000..cd4f599
--- /dev/null
+++ b/test/source/_layouts/post/simple.html
@@ -0,0 +1 @@
+<<< {{ content }} >>>
diff --git a/test/source/_plugins/dummy.rb b/test/source/_plugins/dummy.rb
new file mode 100644
index 0000000..bfd46e1
--- /dev/null
+++ b/test/source/_plugins/dummy.rb
@@ -0,0 +1,8 @@
+module Jekyll
+ class Dummy < Generator
+ priority :high
+
+ def generate(site)
+ end
+ end
+end
diff --git a/test/source/_posts/2013-01-02-post-excerpt.markdown b/test/source/_posts/2013-01-02-post-excerpt.markdown
new file mode 100644
index 0000000..5cac6eb
--- /dev/null
+++ b/test/source/_posts/2013-01-02-post-excerpt.markdown
@@ -0,0 +1,14 @@
+---
+layout: ~
+title: Post Excerpt
+---
+
+First paragraph with [link ref][link].
+
+Second paragraph
+
+---
+
+Third paragraph
+
+[link]: http://www.jekyllrb.com/
diff --git a/test/source/_posts/2013-01-12-nil-layout.textile b/test/source/_posts/2013-01-12-nil-layout.textile
new file mode 100644
index 0000000..1e12fa9
--- /dev/null
+++ b/test/source/_posts/2013-01-12-nil-layout.textile
@@ -0,0 +1,6 @@
+---
+layout: nil
+title: No layout
+---
+
+This post has no layout.
diff --git a/test/source/_posts/2013-01-12-no-layout.textile b/test/source/_posts/2013-01-12-no-layout.textile
new file mode 100644
index 0000000..1c745ae
--- /dev/null
+++ b/test/source/_posts/2013-01-12-no-layout.textile
@@ -0,0 +1,5 @@
+---
+title: I have no layout
+---
+
+This post will be rendered with the "post" layout.
diff --git a/test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep b/test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/test/source/_posts/2013-04-11-custom-excerpt.markdown b/test/source/_posts/2013-04-11-custom-excerpt.markdown
new file mode 100644
index 0000000..023251f
--- /dev/null
+++ b/test/source/_posts/2013-04-11-custom-excerpt.markdown
@@ -0,0 +1,10 @@
+---
+layout: ~
+excerpt: 'I can set a custom excerpt'
+---
+
+This is not my excerpt.
+
+Neither is this.
+
+I can use the excerpt: <quote>{{page.excerpt}}</quote>
\ No newline at end of file
diff --git a/test/source/_posts/2013-05-10-number-category.textile b/test/source/_posts/2013-05-10-number-category.textile
new file mode 100644
index 0000000..1a490a8
--- /dev/null
+++ b/test/source/_posts/2013-05-10-number-category.textile
@@ -0,0 +1,7 @@
+---
+layout: default
+title: Number Category in YAML
+category: 2013
+---
+
+Please make me pass
\ No newline at end of file
diff --git a/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown b/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown
new file mode 100644
index 0000000..07b0e5f
--- /dev/null
+++ b/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown
@@ -0,0 +1,23 @@
+---
+layout: post
+title: Post Excerpt with Layout
+categories:
+- bar
+- baz
+- z_category
+tags:
+- first
+- second
+- third
+- jekyllrb.com
+---
+
+First paragraph with [link ref][link].
+
+Second paragraph
+
+---
+
+Third paragraph
+
+[link]: http://www.jekyllrb.com/
diff --git a/test/source/_posts/2013-08-01-mkdn-extension.mkdn b/test/source/_posts/2013-08-01-mkdn-extension.mkdn
new file mode 100644
index 0000000..e69de29
diff --git a/test/source/_posts/es/2008-11-21-nested.textile b/test/source/_posts/es/2008-11-21-nested.textile
new file mode 100644
index 0000000..a0209ab
--- /dev/null
+++ b/test/source/_posts/es/2008-11-21-nested.textile
@@ -0,0 +1,8 @@
+---
+layout: default
+title: Nested
+---
+
+url: {{ page.url }}
+date: {{ page.date }}
+id: {{ page.id }}
diff --git a/test/source/contacts/bar.html b/test/source/contacts/bar.html
new file mode 100644
index 0000000..1615afe
--- /dev/null
+++ b/test/source/contacts/bar.html
@@ -0,0 +1,5 @@
+---
+title: Contact Information
+---
+
+Contact Information
diff --git a/test/source/contacts/index.html b/test/source/contacts/index.html
new file mode 100644
index 0000000..1615afe
--- /dev/null
+++ b/test/source/contacts/index.html
@@ -0,0 +1,5 @@
+---
+title: Contact Information
+---
+
+Contact Information
diff --git a/test/source/products.yml b/test/source/products.yml
new file mode 100644
index 0000000..21828a0
--- /dev/null
+++ b/test/source/products.yml
@@ -0,0 +1,4 @@
+- name: sugar
+ price: 5.3
+- name: salt
+ price: 2.5
diff --git a/test/source/symlink-test/symlinked-file b/test/source/symlink-test/symlinked-file
new file mode 100644
index 0000000..493fce7
--- /dev/null
+++ b/test/source/symlink-test/symlinked-file
@@ -0,0 +1,22 @@
+---
+layout: default
+title: Tom Preston-Werner
+---
+
+h1. Welcome to my site
+
+h2. Please read our {{ site.posts | size }} Posts
+
+<ul>
+ {% for post in site.posts %}
+ <li>{{ post.date }} <a href="{{ post.url }}">{{ post.title }}</a></li>
+ {% endfor %}
+</ul>
+
+{% assign first_post = site.posts.first %}
+<div id="first_post">
+ <h1>{{ first_post.title }}</h1>
+ <div>
+ {{ first_post.content }}
+ </div>
+</div>
diff --git a/test/suite.rb b/test/suite.rb
index 98923ca..81b6171 100644
--- a/test/suite.rb
+++ b/test/suite.rb
@@ -8,4 +8,4 @@ require 'test/unit'
tests = Dir[File.expand_path("#{File.dirname(__FILE__)}/test_*.rb")]
tests.each do |file|
require file
-end
\ No newline at end of file
+end
diff --git a/test/test_command.rb b/test/test_command.rb
new file mode 100644
index 0000000..860c0c3
--- /dev/null
+++ b/test/test_command.rb
@@ -0,0 +1,39 @@
+require 'helper'
+
+class TestCommand < Test::Unit::TestCase
+ context "when calling .globs" do
+ context "when non-default dest & source dirs" do
+ setup do
+ @source = source_dir
+ @dest = dest_dir
+ directory_with_contents(@dest)
+ @globs = Command.globs(@source, @dest)
+ end
+ should "return an array without the destination dir" do
+ assert @globs.is_a?(Array)
+ assert !@globs.include?(@dest)
+ end
+ teardown do
+ clear_dest
+ end
+ end
+ context "when using default dest dir" do
+ setup do
+ @source = test_dir
+ @dest = test_dir('_site')
+ directory_with_contents(@dest)
+ @globs = Command.globs(@source, @dest)
+ end
+ should "return an array without the destination dir" do
+ assert @globs.is_a?(Array)
+ assert !@globs.include?(@dest)
+ @globs.each do |glob|
+ assert !glob.include?(File.basename(@dest))
+ end
+ end
+ teardown do
+ FileUtils.rm_r(@dest)
+ end
+ end
+ end
+end
diff --git a/test/test_configuration.rb b/test/test_configuration.rb
index 76e8a81..d911b77 100644
--- a/test/test_configuration.rb
+++ b/test/test_configuration.rb
@@ -1,29 +1,181 @@
require 'helper'
class TestConfiguration < Test::Unit::TestCase
+ context "#stringify_keys" do
+ setup do
+ @mixed_keys = Configuration[{
+ 'markdown' => 'maruku',
+ :permalink => 'date',
+ 'baseurl' => '/',
+ :include => ['.htaccess'],
+ :source => './'
+ }]
+ @string_keys = Configuration[{
+ 'markdown' => 'maruku',
+ 'permalink' => 'date',
+ 'baseurl' => '/',
+ 'include' => ['.htaccess'],
+ 'source' => './'
+ }]
+ end
+ should "stringify symbol keys" do
+ assert_equal @string_keys, @mixed_keys.stringify_keys
+ end
+ should "not mess with keys already strings" do
+ assert_equal @string_keys, @string_keys.stringify_keys
+ end
+ end
+ context "#config_files" do
+ setup do
+ @config = Configuration[{"source" => source_dir}]
+ @no_override = {}
+ @one_config_file = {"config" => "config.yml"}
+ @multiple_files = {"config" => %w[config/site.yml config/deploy.toml configuration.yml]}
+ end
+
+ should "always return an array" do
+ assert @config.config_files(@no_override).is_a?(Array)
+ assert @config.config_files(@one_config_file).is_a?(Array)
+ assert @config.config_files(@multiple_files).is_a?(Array)
+ end
+ should "return the default config path if no config files are specified" do
+ assert_equal [File.join(source_dir, "_config.yml")], @config.config_files(@no_override)
+ end
+ should "return the config if given one config file" do
+ assert_equal %w[config.yml], @config.config_files(@one_config_file)
+ end
+ should "return an array of the config files if given many config files" do
+ assert_equal %w[config/site.yml config/deploy.toml configuration.yml], @config.config_files(@multiple_files)
+ end
+ end
+ context "#backwards_compatibilize" do
+ setup do
+ @config = Configuration[{
+ "auto" => true,
+ "watch" => true,
+ "server" => true,
+ "exclude" => "READ-ME.md, Gemfile,CONTRIBUTING.hello.markdown",
+ "include" => "STOP_THE_PRESSES.txt,.heloses, .git"
+ }]
+ end
+ should "unset 'auto' and 'watch'" do
+ assert @config.has_key?("auto")
+ assert @config.has_key?("watch")
+ assert !@config.backwards_compatibilize.has_key?("auto")
+ assert !@config.backwards_compatibilize.has_key?("watch")
+ end
+ should "unset 'server'" do
+ assert @config.has_key?("server")
+ assert !@config.backwards_compatibilize.has_key?("server")
+ end
+ should "transform string exclude into an array" do
+ assert @config.has_key?("exclude")
+ assert @config.backwards_compatibilize.has_key?("exclude")
+ assert_equal @config.backwards_compatibilize["exclude"], %w[READ-ME.md Gemfile CONTRIBUTING.hello.markdown]
+ end
+ should "transform string include into an array" do
+ assert @config.has_key?("include")
+ assert @config.backwards_compatibilize.has_key?("include")
+ assert_equal @config.backwards_compatibilize["include"], %w[STOP_THE_PRESSES.txt .heloses .git]
+ end
+ end
+ context "#fix_common_issues" do
+ setup do
+ @config = Proc.new do |val|
+ Configuration[{
+ 'paginate' => val
+ }]
+ end
+ end
+ should "sets an invalid 'paginate' value to nil" do
+ assert_nil @config.call(0).fix_common_issues['paginate']
+ assert_nil @config.call(-1).fix_common_issues['paginate']
+ assert_nil @config.call(true).fix_common_issues['paginate']
+ end
+ end
context "loading configuration" do
setup do
@path = File.join(Dir.pwd, '_config.yml')
+ @user_config = File.join(Dir.pwd, "my_config_file.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({})
+ mock(YAML).safe_load_file(@path) { raise SystemCallError, "No such file or directory - #{@path}" }
+ mock($stderr).puts("Configuration file: none".yellow)
+ assert_equal Jekyll::Configuration::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({})
+ mock(YAML).safe_load_file(@path) { Hash.new }
+ mock($stdout).puts("Configuration file: #{@path}")
+ assert_equal Jekyll::Configuration::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({})
+ mock(YAML).safe_load_file(@path) { Array.new }
+ mock($stderr).puts(("WARNING: ".rjust(20) + "Error reading configuration. Using defaults (and options).").yellow)
+ mock($stderr).puts("Configuration file: (INVALID) #{@path}".yellow)
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({})
+ end
+
+ should "fire warning when user-specified config file isn't there" do
+ mock(YAML).safe_load_file(@user_config) { raise SystemCallError, "No such file or directory - #{@user_config}" }
+ mock($stderr).puts(("Fatal: ".rjust(20) + "The configuration file '#{@user_config}' could not be found.").red)
+ assert_raises LoadError do
+ Jekyll.configuration({'config' => [@user_config]})
+ end
+ end
+ end
+ context "loading config from external file" do
+ setup do
+ @paths = {
+ :default => File.join(Dir.pwd, '_config.yml'),
+ :other => File.join(Dir.pwd, '_config.live.yml'),
+ :toml => source_dir('_config.dev.toml'),
+ :empty => ""
+ }
+ end
+
+ should "load default config if no config_file is set" do
+ mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({})
+ end
+
+ should "load different config if specified" do
+ mock(YAML).safe_load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} }
+ mock($stdout).puts("Configuration file: #{@paths[:other]}")
+ assert_equal Jekyll::Configuration::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => @paths[:other] })
+ end
+
+ should "load default config if path passed is empty" do
+ mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({ "config" => @paths[:empty] })
+ end
+
+ should "successfully load a TOML file" do
+ Jekyll.logger.log_level = Jekyll::Stevenson::WARN
+ assert_equal Jekyll::Configuration::DEFAULTS.merge({ "baseurl" => "/you-beautiful-blog-you", "title" => "My magnificent site, wut" }), Jekyll.configuration({ "config" => [@paths[:toml]] })
+ Jekyll.logger.log_level = Jekyll::Stevenson::INFO
+ end
+
+ should "load multiple config files" do
+ mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
+ mock(YAML).safe_load_file(@paths[:other]) { Hash.new }
+ mock(TOML).load_file(@paths[:toml]) { Hash.new }
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
+ mock($stdout).puts("Configuration file: #{@paths[:other]}")
+ mock($stdout).puts("Configuration file: #{@paths[:toml]}")
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({ "config" => [@paths[:default], @paths[:other], @paths[:toml]] })
+ end
+
+ should "load multiple config files and last config should win" do
+ mock(YAML).safe_load_file(@paths[:default]) { {"baseurl" => "http://example.dev"} }
+ mock(YAML).safe_load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} }
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
+ mock($stdout).puts("Configuration file: #{@paths[:other]}")
+ assert_equal Jekyll::Configuration::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => [@paths[:default], @paths[:other]] })
end
end
end
diff --git a/test/test_convertible.rb b/test/test_convertible.rb
new file mode 100644
index 0000000..694c152
--- /dev/null
+++ b/test/test_convertible.rb
@@ -0,0 +1,51 @@
+require 'helper'
+require 'ostruct'
+
+class TestConvertible < Test::Unit::TestCase
+ context "yaml front-matter" do
+ setup do
+ @convertible = OpenStruct.new
+ @convertible.extend Jekyll::Convertible
+ @base = File.expand_path('../fixtures', __FILE__)
+ end
+
+ should "parse the front-matter correctly" do
+ ret = @convertible.read_yaml(@base, 'front_matter.erb')
+ assert_equal({'test' => 'good'}, ret)
+ end
+
+ should "not parse if the front-matter is not at the start of the file" do
+ ret = @convertible.read_yaml(@base, 'broken_front_matter1.erb')
+ assert_equal({}, ret)
+ end
+
+ should "not parse if there is syntax error in front-matter" do
+ name = 'broken_front_matter2.erb'
+ out = capture_stdout do
+ ret = @convertible.read_yaml(@base, name)
+ assert_equal({}, ret)
+ end
+ assert_match(/YAML Exception|syntax error|Error reading file/, out)
+ assert_match(/#{File.join(@base, name)}/, out)
+ end
+
+ should "not allow ruby objects in yaml" do
+ out = capture_stdout do
+ @convertible.read_yaml(@base, 'exploit_front_matter.erb')
+ end
+ assert_no_match /undefined class\/module DoesNotExist/, out
+ end
+
+ if RUBY_VERSION >= '1.9.2'
+ should "not parse if there is encoding error in file" do
+ name = 'broken_front_matter3.erb'
+ out = capture_stdout do
+ ret = @convertible.read_yaml(@base, name, :encoding => 'utf-8')
+ assert_equal({}, ret)
+ end
+ assert_match(/invalid byte sequence in UTF-8/, out)
+ assert_match(/#{File.join(@base, name)}/, out)
+ end
+ end
+ end
+end
diff --git a/test/test_core_ext.rb b/test/test_core_ext.rb
index c3e62cb..0b79f33 100644
--- a/test/test_core_ext.rb
+++ b/test/test_core_ext.rb
@@ -63,4 +63,26 @@ class TestCoreExt < Test::Unit::TestCase
end
end
+
+ context "enumerable" do
+ context "glob_include?" do
+ should "return false with no glob patterns" do
+ assert ![].glob_include?("a.txt")
+ end
+
+ should "return false with all not match path" do
+ data = ["a*", "b?"]
+ assert !data.glob_include?("ca.txt")
+ assert !data.glob_include?("ba.txt")
+ end
+
+ should "return true with match path" do
+ data = ["a*", "b?", "**/a*"]
+ assert data.glob_include?("a.txt")
+ assert data.glob_include?("ba")
+ assert data.glob_include?("c/a/a.txt")
+ assert data.glob_include?("c/a/b/a.txt")
+ end
+ end
+ end
end
diff --git a/test/test_entry_filter.rb b/test/test_entry_filter.rb
new file mode 100644
index 0000000..c295a57
--- /dev/null
+++ b/test/test_entry_filter.rb
@@ -0,0 +1,74 @@
+require 'helper'
+
+class TestEntryFilter < Test::Unit::TestCase
+ context "Filtering entries" do
+ setup do
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir})
+ end
+ @site = Site.new(Jekyll.configuration)
+ end
+
+ should "filter entries" do
+ ent1 = %w[foo.markdown bar.markdown baz.markdown #baz.markdown#
+ .baz.markdow foo.markdown~ .htaccess _posts _pages]
+
+ entries = EntryFilter.new(@site).filter(ent1)
+ assert_equal %w[foo.markdown bar.markdown baz.markdown .htaccess], entries
+ end
+
+ should "filter entries with exclude" do
+ excludes = %w[README TODO]
+ files = %w[index.html site.css .htaccess]
+
+ @site.exclude = excludes + ["exclude*"]
+ assert_equal files, @site.filter_entries(excludes + files + ["excludeA"])
+ end
+
+ should "not filter entries within include" do
+ includes = %w[_index.html .htaccess include*]
+ files = %w[index.html _index.html .htaccess includeA]
+
+ @site.include = includes
+ assert_equal files, @site.filter_entries(files)
+ end
+
+ should "filter symlink entries when safe mode enabled" do
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'safe' => true})
+ end
+ site = Site.new(Jekyll.configuration)
+ stub(File).symlink?('symlink.js') {true}
+ files = %w[symlink.js]
+ assert_equal [], site.filter_entries(files)
+ end
+
+ should "not filter symlink entries when safe mode disabled" do
+ stub(File).symlink?('symlink.js') {true}
+ files = %w[symlink.js]
+ assert_equal files, @site.filter_entries(files)
+ end
+
+ should "not include symlinks in safe mode" do
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'safe' => true})
+ end
+ site = Site.new(Jekyll.configuration)
+
+ site.read_directories("symlink-test")
+ assert_equal [], site.pages
+ assert_equal [], site.static_files
+ end
+
+ should "include symlinks in unsafe mode" do
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'safe' => false})
+ end
+ site = Site.new(Jekyll.configuration)
+
+ site.read_directories("symlink-test")
+ assert_not_equal [], site.pages
+ assert_not_equal [], site.static_files
+ end
+ end
+end
diff --git a/test/test_excerpt.rb b/test/test_excerpt.rb
new file mode 100644
index 0000000..410e9e7
--- /dev/null
+++ b/test/test_excerpt.rb
@@ -0,0 +1,78 @@
+require 'helper'
+
+class TestExcerpt < 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 "With extraction disabled" do
+ setup do
+ clear_dest
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'excerpt_separator' => ''})
+ end
+ @site = Site.new(Jekyll.configuration)
+ @post = setup_post("2013-07-22-post-excerpt-with-layout.markdown")
+ end
+
+ should "not be generated" do
+ excerpt = @post.send(:extract_excerpt)
+ assert_equal true, excerpt.empty?
+ end
+ end
+
+ context "An extracted excerpt" do
+ setup do
+ clear_dest
+ stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS }
+ @site = Site.new(Jekyll.configuration)
+ @post = setup_post("2013-07-22-post-excerpt-with-layout.markdown")
+ @excerpt = @post.send :extract_excerpt
+ end
+
+ context "#to_liquid" do
+ should "contain the proper page data to mimick the post liquid" do
+ assert_equal "Post Excerpt with Layout", @excerpt.to_liquid["title"]
+ assert_equal "/bar/baz/z_category/2013/07/22/post-excerpt-with-layout.html", @excerpt.to_liquid["url"]
+ assert_equal Time.parse("2013-07-22"), @excerpt.to_liquid["date"]
+ assert_equal %w[bar baz z_category], @excerpt.to_liquid["categories"]
+ assert_equal %w[first second third jekyllrb.com], @excerpt.to_liquid["tags"]
+ assert_equal "_posts/2013-07-22-post-excerpt-with-layout.markdown", @excerpt.to_liquid["path"]
+ end
+ end
+
+ context "#content" do
+
+ context "before render" do
+ should "be the first paragraph of the page" do
+ assert_equal "First paragraph with [link ref][link].\n\n[link]: http://www.jekyllrb.com/", @excerpt.content
+ end
+
+ should "contain any refs at the bottom of the page" do
+ assert @excerpt.content.include?("[link]: http://www.jekyllrb.com/")
+ end
+ end
+
+ context "after render" do
+ setup do
+ @rendered_post = @post.dup
+ do_render(@rendered_post)
+ @extracted_excerpt = @rendered_post.send :extracted_excerpt
+ end
+
+ should "be the first paragraph of the page" do
+ assert_equal "<p>First paragraph with <a href=\"http://www.jekyllrb.com/\">link ref</a>.</p>", @extracted_excerpt.content
+ end
+
+ should "link properly" do
+ assert @extracted_excerpt.content.include?("http://www.jekyllrb.com/")
+ end
+ end
+ end
+ end
+end
diff --git a/test/test_filters.rb b/test/test_filters.rb
index 205d4bc..28e9612 100644
--- a/test/test_filters.rb
+++ b/test/test_filters.rb
@@ -13,6 +13,8 @@ class TestFilters < Test::Unit::TestCase
context "filters" do
setup do
@filter = JekyllFilter.new
+ @sample_time = Time.utc(2013, 03, 27, 11, 22, 33)
+ @time_as_string = "September 11, 2001 12:46:30 -0000"
end
should "textilize with simple string" do
@@ -42,6 +44,44 @@ class TestFilters < Test::Unit::TestCase
assert_equal "chunky, bacon, bits, and pieces", @filter.array_to_sentence_string(["chunky", "bacon", "bits", "pieces"])
end
+ context "date filters" do
+ context "with Time object" do
+ should "format a date with short format" do
+ assert_equal "27 Mar 2013", @filter.date_to_string(@sample_time)
+ end
+
+ should "format a date with long format" do
+ assert_equal "27 March 2013", @filter.date_to_long_string(@sample_time)
+ end
+
+ should "format a time with xmlschema" do
+ assert_equal "2013-03-27T11:22:33Z", @filter.date_to_xmlschema(@sample_time)
+ end
+
+ should "format a time according to RFC-822" do
+ assert_equal "Wed, 27 Mar 2013 11:22:33 -0000", @filter.date_to_rfc822(@sample_time)
+ end
+ end
+
+ context "with String object" do
+ should "format a date with short format" do
+ assert_equal "11 Sep 2001", @filter.date_to_string(@time_as_string)
+ end
+
+ should "format a date with long format" do
+ assert_equal "11 September 2001", @filter.date_to_long_string(@time_as_string)
+ end
+
+ should "format a time with xmlschema" do
+ assert_equal "2001-09-11T12:46:30Z", @filter.date_to_xmlschema(@time_as_string)
+ end
+
+ should "format a time according to RFC-822" do
+ assert_equal "Tue, 11 Sep 2001 12:46:30 -0000", @filter.date_to_rfc822(@time_as_string)
+ end
+ end
+ end
+
should "escape xml with ampersands" do
assert_equal "AT&T", @filter.xml_escape("AT&T")
assert_equal "<code>command <filename></code>", @filter.xml_escape("<code>command <filename></code>")
@@ -58,5 +98,16 @@ class TestFilters < Test::Unit::TestCase
should "escape space as %20" do
assert_equal "my%20things", @filter.uri_escape("my things")
end
+
+ context "jsonify filter" do
+ should "convert hash to json" do
+ assert_equal "{\"age\":18}", @filter.jsonify({:age => 18})
+ end
+
+ should "convert array to json" do
+ assert_equal "[1,2]", @filter.jsonify([1, 2])
+ assert_equal "[{\"name\":\"Jack\"},{\"name\":\"Smith\"}]", @filter.jsonify([{:name => 'Jack'}, {:name => 'Smith'}])
+ end
+ end
end
end
diff --git a/test/test_generated_site.rb b/test/test_generated_site.rb
index 9fb7a40..801675b 100644
--- a/test/test_generated_site.rb
+++ b/test/test_generated_site.rb
@@ -5,7 +5,7 @@ class TestGeneratedSite < Test::Unit::TestCase
setup do
clear_dest
stub(Jekyll).configuration do
- Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir})
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir})
end
@site = Site.new(Jekyll.configuration)
@@ -14,7 +14,7 @@ class TestGeneratedSite < Test::Unit::TestCase
end
should "ensure post count is as expected" do
- assert_equal 28, @site.posts.size
+ assert_equal 36, @site.posts.size
end
should "insert site.posts into the index" do
@@ -46,7 +46,7 @@ class TestGeneratedSite < Test::Unit::TestCase
setup do
clear_dest
stub(Jekyll).configuration do
- Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'limit_posts' => 5})
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'limit_posts' => 5})
end
@site = Site.new(Jekyll.configuration)
@@ -58,11 +58,22 @@ class TestGeneratedSite < Test::Unit::TestCase
assert_equal 5, @site.posts.size
end
- should "ensure limit posts is 1 or more" do
+ should "ensure limit posts is 0 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})
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'limit_posts' => -1})
+ end
+
+ @site = Site.new(Jekyll.configuration)
+ end
+ end
+
+ should "acceptable limit post is 0" do
+ assert_nothing_raised ArgumentError do
+ clear_dest
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'limit_posts' => 0})
end
@site = Site.new(Jekyll.configuration)
diff --git a/test/test_kramdown.rb b/test/test_kramdown.rb
index 99a7b45..1d4c09f 100644
--- a/test/test_kramdown.rb
+++ b/test/test_kramdown.rb
@@ -1,23 +1,62 @@
+# encoding: UTF-8
+
require 'helper'
class TestKramdown < Test::Unit::TestCase
context "kramdown" do
setup do
- config = {
+ @config = {
'markdown' => 'kramdown',
'kramdown' => {
'auto_ids' => false,
'footnote_nr' => 1,
'entity_output' => 'as_char',
- 'toc_levels' => '1..6'
+ 'toc_levels' => '1..6',
+ 'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
+
+ 'use_coderay' => true,
+ 'coderay_bold_every'=> 12,
+ 'coderay' => {
+ 'coderay_css' => :style,
+ 'coderay_bold_every' => 8
+ }
}
}
- @markdown = MarkdownConverter.new config
+ @config = Jekyll.configuration(@config)
+ @markdown = Converters::Markdown.new(@config)
end
# http://kramdown.rubyforge.org/converter/html.html#options
should "pass kramdown options" do
assert_equal "<h1>Some Header</h1>", @markdown.convert('# Some Header #').strip
end
+
+ should "convert quotes to smart quotes" do
+ assert_match /<p>(“|“)Pit(’|’)hy(”|”)<\/p>/, @markdown.convert(%{"Pit'hy"}).strip
+
+ override = { 'kramdown' => { 'smart_quotes' => 'lsaquo,rsaquo,laquo,raquo' } }
+ markdown = Converters::Markdown.new(@config.deep_merge(override))
+ assert_match /<p>(«|«)Pit(›|›)hy(»|»)<\/p>/, markdown.convert(%{"Pit'hy"}).strip
+ end
+
+ context "moving up nested coderay options" do
+ setup do
+ @markdown.convert('some markup')
+ @converter_config = @markdown.instance_variable_get(:@config)['kramdown']
+ end
+
+ should "work correctly" do
+ assert_equal :style, @converter_config['coderay_css']
+ end
+
+ should "also work for defaults" do
+ default = Jekyll::Configuration::DEFAULTS['kramdown']['coderay']['coderay_tab_width']
+ assert_equal default, @converter_config['coderay_tab_width']
+ end
+
+ should "not overwrite" do
+ assert_equal 12, @converter_config['coderay_bold_every']
+ end
+ end
end
end
diff --git a/test/test_new_command.rb b/test/test_new_command.rb
new file mode 100644
index 0000000..bc9e658
--- /dev/null
+++ b/test/test_new_command.rb
@@ -0,0 +1,104 @@
+require 'helper'
+require 'jekyll/commands/new'
+
+class TestNewCommand < Test::Unit::TestCase
+ def dir_contents(path)
+ Dir["#{path}/**/*"].each do |file|
+ file.gsub! path, ''
+ end
+ end
+
+ def site_template
+ File.expand_path("../lib/site_template", File.dirname(__FILE__))
+ end
+
+ context 'when args contains a path' do
+ setup do
+ @path = 'new-site'
+ @args = [@path]
+ @full_path = File.expand_path(@path, Dir.pwd)
+ end
+
+ teardown do
+ FileUtils.rm_r @full_path
+ end
+
+ should 'create a new directory' do
+ assert !File.exists?(@full_path)
+ capture_stdout { Jekyll::Commands::New.process(@args) }
+ assert File.exists?(@full_path)
+ end
+
+ should 'display a success message' do
+ output = capture_stdout { Jekyll::Commands::New.process(@args) }
+ success_message = "New jekyll site installed in #{@full_path}.\n"
+ assert_equal success_message, output
+ end
+
+ should 'copy the static files in site template to the new directory' do
+ static_template_files = dir_contents(site_template).reject do |f|
+ File.extname(f) == '.erb'
+ end
+
+ capture_stdout { Jekyll::Commands::New.process(@args) }
+
+ new_site_files = dir_contents(@full_path).reject do |f|
+ File.extname(f) == '.markdown'
+ end
+
+ assert_same_elements static_template_files, new_site_files
+ end
+
+ should 'process any ERB files' do
+ erb_template_files = dir_contents(site_template).select do |f|
+ File.extname(f) == '.erb'
+ end
+
+ stubbed_date = '2013-01-01'
+ stub.instance_of(Time).strftime { stubbed_date }
+
+ erb_template_files.each do |f|
+ f.chomp! '.erb'
+ f.gsub! '0000-00-00', stubbed_date
+ end
+
+ capture_stdout { Jekyll::Commands::New.process(@args) }
+
+ new_site_files = dir_contents(@full_path).select do |f|
+ erb_template_files.include? f
+ end
+
+ assert_same_elements erb_template_files, new_site_files
+ end
+ end
+
+ context 'when multiple args are given' do
+ setup do
+ @site_name_with_spaces = 'new site name'
+ @multiple_args = @site_name_with_spaces.split
+ end
+
+ teardown do
+ FileUtils.rm_r File.expand_path(@site_name_with_spaces, Dir.pwd)
+ end
+
+ should 'create a new directory' do
+ assert !File.exists?(@site_name_with_spaces)
+ capture_stdout { Jekyll::Commands::New.process(@multiple_args) }
+ assert File.exists?(@site_name_with_spaces)
+ end
+ end
+
+ context 'when no args are given' do
+ setup do
+ @empty_args = []
+ end
+
+ should 'raise an ArgumentError' do
+ exception = assert_raise ArgumentError do
+ Jekyll::Commands::New.process(@empty_args)
+ end
+ assert_equal 'You must specify a path.', exception.message
+ end
+ end
+end
diff --git a/test/test_page.rb b/test/test_page.rb
index 6127899..e319056 100644
--- a/test/test_page.rb
+++ b/test/test_page.rb
@@ -1,8 +1,10 @@
require 'helper'
class TestPage < Test::Unit::TestCase
- def setup_page(file)
- @page = Page.new(@site, source_dir, '', file)
+ def setup_page(*args)
+ dir, file = args
+ dir, file = ['', dir] if file.nil?
+ @page = Page.new(@site, source_dir, dir, file)
end
def do_render(page)
@@ -13,7 +15,7 @@ class TestPage < Test::Unit::TestCase
context "A Page" do
setup do
clear_dest
- stub(Jekyll).configuration { Jekyll::DEFAULTS }
+ stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS }
@site = Site.new(Jekyll.configuration)
end
@@ -23,6 +25,18 @@ class TestPage < Test::Unit::TestCase
assert_equal "/contacts.html", @page.url
end
+ context "in a directory hierarchy" do
+ should "create url based on filename" do
+ @page = setup_page('/contacts', 'bar.html')
+ assert_equal "/contacts/bar.html", @page.url
+ end
+
+ should "create index url based on filename" do
+ @page = setup_page('/contacts', 'index.html')
+ assert_equal "/contacts/index.html", @page.url
+ end
+ end
+
should "deal properly with extensions" do
@page = setup_page('deal.with.dots.html')
assert_equal ".html", @page.ext
@@ -47,6 +61,28 @@ class TestPage < Test::Unit::TestCase
@page = setup_page('index.html')
assert_equal '/', @page.dir
end
+
+ context "in a directory hierarchy" do
+ should "create url based on filename" do
+ @page = setup_page('/contacts', 'bar.html')
+ assert_equal "/contacts/bar/", @page.url
+ end
+
+ should "create index url based on filename" do
+ @page = setup_page('/contacts', 'index.html')
+ assert_equal "/contacts/", @page.url
+ end
+
+ should "return dir correctly" do
+ @page = setup_page('/contacts', 'bar.html')
+ assert_equal '/contacts/bar/', @page.dir
+ end
+
+ should "return dir correctly for index page" do
+ @page = setup_page('/contacts', 'index.html')
+ assert_equal '/contacts/', @page.dir
+ end
+ end
end
context "with any other url style" do
@@ -67,6 +103,16 @@ class TestPage < Test::Unit::TestCase
end
end
+ context "with specified layout of nil" do
+ setup do
+ @page = setup_page('sitemap.xml')
+ end
+
+ should "layout of nil is respected" do
+ assert_equal "nil", @page.data["layout"]
+ end
+ end
+
context "rendering" do
setup do
clear_dest
@@ -81,6 +127,15 @@ class TestPage < Test::Unit::TestCase
assert File.exists?(File.join(dest_dir, 'contacts.html'))
end
+ should "write even when the folder name is plus and permalink has +" do
+ page = setup_page('+', 'foo.md')
+ do_render(page)
+ page.write(dest_dir)
+
+ assert File.directory?(dest_dir)
+ assert File.exists?(File.join(dest_dir, '+', 'plus+in+url'))
+ end
+
should "write properly without html extension" do
page = setup_page('contacts.html')
page.site.permalink_style = :pretty
@@ -111,6 +166,36 @@ class TestPage < Test::Unit::TestCase
assert File.directory?(dest_dir)
assert File.exists?(File.join(dest_dir, '.htaccess'))
end
+
+ context "in a directory hierarchy" do
+ should "write properly the index" do
+ page = setup_page('/contacts', 'index.html')
+ 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" do
+ page = setup_page('/contacts', 'bar.html')
+ do_render(page)
+ page.write(dest_dir)
+
+ assert File.directory?(dest_dir)
+ assert File.exists?(File.join(dest_dir, 'contacts', 'bar.html'))
+ end
+
+ should "write properly without html extension" do
+ page = setup_page('/contacts', 'bar.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', 'bar', 'index.html'))
+ end
+ end
end
end
diff --git a/test/test_pager.rb b/test/test_pager.rb
index 4d420f7..b066b9a 100644
--- a/test/test_pager.rb
+++ b/test/test_pager.rb
@@ -2,6 +2,17 @@ require 'helper'
class TestPager < Test::Unit::TestCase
+ def build_site(config = {})
+ base = Jekyll::Configuration::DEFAULTS.deep_merge({
+ 'source' => source_dir,
+ 'destination' => dest_dir,
+ 'paginate' => 1
+ })
+ site = Jekyll::Site.new(base.deep_merge(config))
+ site.process
+ site
+ end
+
should "calculate number of pages" do
assert_equal(0, Pager.calculate_pages([], '2'))
assert_equal(1, Pager.calculate_pages([1], '2'))
@@ -11,41 +22,33 @@ class TestPager < Test::Unit::TestCase
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 "determine the pagination path" do
+ assert_equal("/index.html", Pager.paginate_path(build_site, 1))
+ assert_equal("/page2", Pager.paginate_path(build_site, 2))
+ assert_equal("/index.html", Pager.paginate_path(build_site({'paginate_path' => '/blog/page-:num'}), 1))
+ assert_equal("/blog/page-2", Pager.paginate_path(build_site({'paginate_path' => '/blog/page-:num'}), 2))
+ assert_equal("/index.html", Pager.paginate_path(build_site({'paginate_path' => '/blog/page/:num'}), 1))
+ assert_equal("/blog/page/2", Pager.paginate_path(build_site({'paginate_path' => '/blog/page/:num'}), 2))
+ assert_equal("/contacts/index.html", Pager.paginate_path(build_site({'paginate_path' => '/contacts/page:num'}), 1))
+ assert_equal("/contacts/page2", Pager.paginate_path(build_site({'paginate_path' => '/contacts/page:num'}), 2))
+ assert_equal("/contacts/index.html", Pager.paginate_path(build_site({'paginate_path' => '/contacts/page/:num'}), 1))
+ assert_equal("/contacts/page/2", Pager.paginate_path(build_site({'paginate_path' => '/contacts/page/:num'}), 2))
+ end
+ context "pagination disabled" do
should "report that pagination is disabled" do
- assert !Pager.pagination_enabled?(@config, 'index.html')
+ assert !Pager.pagination_enabled?(build_site('paginate' => nil))
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
+ @site = build_site('paginate' => 2)
@posts = @site.posts
end
should "report that pagination is enabled" do
- assert Pager.pagination_enabled?(@config, 'index.html')
+ assert Pager.pagination_enabled?(@site)
end
context "with 4 posts" do
@@ -54,7 +57,7 @@ class TestPager < Test::Unit::TestCase
end
should "create first pager" do
- pager = Pager.new(@config, 1, @posts)
+ pager = Pager.new(@site, 1, @posts)
assert_equal(2, pager.posts.size)
assert_equal(2, pager.total_pages)
assert_nil(pager.previous_page)
@@ -62,7 +65,7 @@ class TestPager < Test::Unit::TestCase
end
should "create second pager" do
- pager = Pager.new(@config, 2, @posts)
+ pager = Pager.new(@site, 2, @posts)
assert_equal(2, pager.posts.size)
assert_equal(2, pager.total_pages)
assert_equal(1, pager.previous_page)
@@ -70,7 +73,7 @@ class TestPager < Test::Unit::TestCase
end
should "not create third pager" do
- assert_raise(RuntimeError) { Pager.new(@config, 3, @posts) }
+ assert_raise(RuntimeError) { Pager.new(@site, 3, @posts) }
end
end
@@ -81,7 +84,7 @@ class TestPager < Test::Unit::TestCase
end
should "create first pager" do
- pager = Pager.new(@config, 1, @posts)
+ pager = Pager.new(@site, 1, @posts)
assert_equal(2, pager.posts.size)
assert_equal(3, pager.total_pages)
assert_nil(pager.previous_page)
@@ -89,7 +92,7 @@ class TestPager < Test::Unit::TestCase
end
should "create second pager" do
- pager = Pager.new(@config, 2, @posts)
+ pager = Pager.new(@site, 2, @posts)
assert_equal(2, pager.posts.size)
assert_equal(3, pager.total_pages)
assert_equal(1, pager.previous_page)
@@ -97,7 +100,7 @@ class TestPager < Test::Unit::TestCase
end
should "create third pager" do
- pager = Pager.new(@config, 3, @posts)
+ pager = Pager.new(@site, 3, @posts)
assert_equal(1, pager.posts.size)
assert_equal(3, pager.total_pages)
assert_equal(2, pager.previous_page)
@@ -105,7 +108,7 @@ class TestPager < Test::Unit::TestCase
end
should "not create fourth pager" do
- assert_raise(RuntimeError) { Pager.new(@config, 4, @posts) }
+ assert_raise(RuntimeError) { Pager.new(@site, 4, @posts) }
end
end
diff --git a/test/test_post.rb b/test/test_post.rb
index 1c3ea64..a61fc67 100644
--- a/test/test_post.rb
+++ b/test/test_post.rb
@@ -13,7 +13,7 @@ class TestPost < Test::Unit::TestCase
context "A Post" do
setup do
clear_dest
- stub(Jekyll).configuration { Jekyll::DEFAULTS }
+ stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS }
@site = Site.new(Jekyll.configuration)
end
@@ -71,8 +71,8 @@ class TestPost < Test::Unit::TestCase
@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
+ assert_equal "/my_category", @post.dir
+ assert_equal "/my_category/permalinked-post", @post.url
end
context "with CRLF linebreaks" do
@@ -128,6 +128,30 @@ class TestPost < Test::Unit::TestCase
end
end
+ context "with unspecified (date) style and a numeric category" do
+ setup do
+ @post.categories << 2013
+ @post.process(@fake_file)
+ end
+
+ should "process the url correctly" do
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
+ assert_equal "/2013/2008/09/09/foo-bar.html", @post.url
+ end
+ end
+
+ context "with specified layout of nil" do
+ setup do
+ file = '2013-01-12-nil-layout.textile'
+ @post = setup_post(file)
+ @post.process(file)
+ end
+
+ should "layout of nil is respected" do
+ assert_equal "nil", @post.data["layout"]
+ end
+ end
+
context "with unspecified (date) style and categories" do
setup do
@post.categories << "food"
@@ -141,6 +165,19 @@ class TestPost < Test::Unit::TestCase
end
end
+ context "with space (categories)" do
+ setup do
+ @post.categories << "French cuisine"
+ @post.categories << "Belgian beer"
+ @post.process(@fake_file)
+ end
+
+ should "process the url correctly" do
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
+ assert_equal "/French%20cuisine/Belgian%20beer/2008/09/09/foo-bar.html", @post.url
+ end
+ end
+
context "with none style" do
setup do
@post.site.permalink_style = :none
@@ -165,6 +202,18 @@ class TestPost < Test::Unit::TestCase
end
end
+ context "with ordinal style" do
+ setup do
+ @post.site.permalink_style = :ordinal
+ @post.process(@fake_file)
+ end
+
+ should "process the url correctly" do
+ assert_equal "/:categories/:year/:y_day/:title.html", @post.template
+ assert_equal "/2008/253/foo-bar.html", @post.url
+ end
+ end
+
context "with custom date permalink" do
setup do
@post.site.permalink_style = '/:categories/:year/:i_month/:i_day/:title/'
@@ -176,6 +225,17 @@ class TestPost < Test::Unit::TestCase
end
end
+ context "with custom abbreviated month date permalink" do
+ setup do
+ @post.site.permalink_style = '/:categories/:year/:short_month/:day/:title/'
+ @post.process(@fake_file)
+ end
+
+ should "process the url correctly" do
+ assert_equal "/2008/Sep/09/foo-bar/", @post.url
+ end
+ end
+
context "with prefix style and no extension" do
setup do
@post.site.permalink_style = "/prefix/:title"
@@ -203,12 +263,77 @@ class TestPost < Test::Unit::TestCase
assert_equal "<h1>{{ page.title }}</h1>\n<p>Best <strong>post</strong> ever</p>", @post.content
end
+
+ context "#excerpt" do
+ setup do
+ file = "2013-01-02-post-excerpt.markdown"
+ @post = setup_post(file)
+ @post.process(file)
+ @post.read_yaml(@source, file)
+ do_render(@post)
+ end
+
+ should "return first paragraph by default" do
+ assert @post.excerpt.include?("First paragraph"), "contains first paragraph"
+ assert !@post.excerpt.include?("Second paragraph"), "does not contains second paragraph"
+ assert !@post.excerpt.include?("Third paragraph"), "does not contains third paragraph"
+ end
+
+ should "correctly resolve link references" do
+ assert @post.excerpt.include?("www.jekyllrb.com"), "contains referenced link URL"
+ end
+
+ should "return rendered HTML" do
+ assert_equal "<p>First paragraph with <a href=\"http://www.jekyllrb.com/\">link ref</a>.</p>",
+ @post.excerpt
+ end
+
+ context "with excerpt_separator setting" do
+ setup do
+ file = "2013-01-02-post-excerpt.markdown"
+
+ @post.site.config['excerpt_separator'] = "\n---\n"
+
+ @post.process(file)
+ @post.read_yaml(@source, file)
+ @post.transform
+ end
+
+ should "respect given separator" do
+ assert @post.excerpt.include?("First paragraph"), "contains first paragraph"
+ assert @post.excerpt.include?("Second paragraph"), "contains second paragraph"
+ assert !@post.excerpt.include?("Third paragraph"), "does not contains third paragraph"
+ end
+
+ should "replace separator with new-lines" do
+ assert !@post.excerpt.include?("---"), "does not contains separator"
+ end
+ end
+
+ context "with custom excerpt" do
+ setup do
+ file = "2013-04-11-custom-excerpt.markdown"
+ @post = setup_post(file)
+ do_render(@post)
+ end
+
+ should "use custom excerpt" do
+ assert_equal("I can set a custom excerpt", @post.excerpt)
+ end
+
+ should "expose custom excerpt to liquid" do
+ assert @post.content.include?("I can use the excerpt: <quote>I can set a custom excerpt</quote>"), "Exposes incorrect excerpt to liquid."
+ end
+
+ end
+
+ end
end
context "when in a site" do
setup do
clear_dest
- stub(Jekyll).configuration { Jekyll::DEFAULTS }
+ stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS }
@site = Site.new(Jekyll.configuration)
@site.posts = [setup_post('2008-02-02-published.textile'),
setup_post('2009-01-27-categories.textile')]
@@ -299,6 +424,12 @@ class TestPost < Test::Unit::TestCase
assert_equal [], post.categories
end
+ should "recognize number category in yaml" do
+ post = setup_post("2013-05-10-number-category.textile")
+ assert post.categories.include?('2013')
+ assert !post.categories.include?(2013)
+ end
+
should "recognize tag in yaml" do
post = setup_post("2009-05-18-tag.textile")
assert post.tags.include?('code')
@@ -310,7 +441,7 @@ class TestPost < Test::Unit::TestCase
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
@@ -398,46 +529,53 @@ class TestPost < Test::Unit::TestCase
assert_equal ['foo'], post.categories
end
end
-
+
context "converter file extension settings" do
setup do
- stub(Jekyll).configuration { Jekyll::DEFAULTS }
+ stub(Jekyll).configuration { Jekyll::Configuration::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
+ assert conv.kind_of? Jekyll::Converters::Markdown
end
-
- should "process .text as indentity under default configuration" do
+
+ should "process .text as identity under default configuration" do
post = setup_post '2011-04-12-text-extension.text'
conv = post.converter
- assert conv.kind_of? Jekyll::IdentityConverter
+ assert conv.kind_of? Jekyll::Converters::Identity
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
+ assert conv.kind_of? Jekyll::Converters::Markdown
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
+ assert conv.kind_of? Jekyll::Converters::Markdown
+ end
+
+ should "process .mkdn under text if it is not in the markdown config" do
+ @site.config['markdown_ext'] = 'markdown,mkd,md,text'
+ post = setup_post '2013-08-01-mkdn-extension.mkdn'
+ conv = post.converter
+ assert conv.kind_of? Jekyll::Converters::Identity
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
+ assert conv.kind_of? Jekyll::Converters::Textile
end
-
+
end
-
+
end
diff --git a/test/test_rdiscount.rb b/test/test_rdiscount.rb
index 894ea18..ed2c6f9 100644
--- a/test/test_rdiscount.rb
+++ b/test/test_rdiscount.rb
@@ -5,14 +5,18 @@ class TestRdiscount < Test::Unit::TestCase
context "rdiscount" do
setup do
config = {
- 'rdiscount' => { 'extensions' => ['smart'] },
- 'markdown' => 'rdiscount'
+ 'markdown' => 'rdiscount',
+ 'rdiscount' => { 'extensions' => ['smart', 'generate_toc'], 'toc_token' => '{:toc}' }
}
- @markdown = MarkdownConverter.new config
+ @markdown = Converters::Markdown.new config
end
should "pass rdiscount extensions" do
assert_equal "<p>“smart”</p>", @markdown.convert('"smart"').strip
end
+
+ should "render toc" do
+ assert_equal "<h1 id=\"Header+1\">Header 1</h1>\n\n<h2 id=\"Header+2\">Header 2</h2>\n\n<p>\n <ul>\n <li><a href=\"#Header+1\">Header 1</a>\n <ul>\n <li><a href=\"#Header+2\">Header 2</a> </li>\n </ul>\n </li>\n </ul>\n\n</p>", @markdown.convert("# Header 1\n\n## Header 2\n\n{:toc}").strip
+ end
end
end
diff --git a/test/test_redcarpet.rb b/test/test_redcarpet.rb
index 1359c44..c6e8b92 100644
--- a/test/test_redcarpet.rb
+++ b/test/test_redcarpet.rb
@@ -1,21 +1,61 @@
-require File.dirname(__FILE__) + '/helper'
+require 'helper'
class TestRedcarpet < Test::Unit::TestCase
context "redcarpet" do
setup do
- config = {
- 'redcarpet' => { 'extensions' => ['smart'] },
+ @config = {
+ 'redcarpet' => { 'extensions' => ['smart', 'strikethrough', 'filter_html'] },
'markdown' => 'redcarpet'
}
- @markdown = MarkdownConverter.new config
+ @markdown = Converters::Markdown.new @config
end
should "pass redcarpet options" do
assert_equal "<h1>Some Header</h1>", @markdown.convert('# Some Header #').strip
end
-
- should "pass redcarpet extensions" do
+
+ should "pass redcarpet SmartyPants options" do
assert_equal "<p>“smart”</p>", @markdown.convert('"smart"').strip
end
+
+ should "pass redcarpet extensions" do
+ assert_equal "<p><del>deleted</del></p>", @markdown.convert('~~deleted~~').strip
+ end
+
+ should "pass redcarpet render options" do
+ assert_equal "<p><strong>bad code not here</strong>: i am bad</p>", @markdown.convert('**bad code not here**: <script>i am bad</script>').strip
+ end
+
+ context "with pygments enabled" do
+ setup do
+ @markdown = Converters::Markdown.new @config.merge({ 'pygments' => true })
+ end
+
+ should "render fenced code blocks with syntax highlighting" do
+ assert_equal "<div class=\"highlight\"><pre><code class=\"ruby language-ruby\" data-lang=\"ruby\"><span class=\"nb\">puts</span> <span class=\"s2\">"Hello world"</span>\n</code></pre></div>", @markdown.convert(
+ <<-EOS
+```ruby
+puts "Hello world"
+```
+ EOS
+ ).strip
+ end
+ end
+
+ context "with pygments disabled" do
+ setup do
+ @markdown = Converters::Markdown.new @config.merge({ 'pygments' => false })
+ end
+
+ should "render fenced code blocks without syntax highlighting" do
+ assert_equal "<div class=\"highlight\"><pre><code class=\"ruby language-ruby\" data-lang=\"ruby\">puts "Hello world"\n</code></pre></div>", @markdown.convert(
+ <<-EOS
+```ruby
+puts "Hello world"
+```
+ EOS
+ ).strip
+ end
+ end
end
end
diff --git a/test/test_redcloth.rb b/test/test_redcloth.rb
new file mode 100644
index 0000000..964591b
--- /dev/null
+++ b/test/test_redcloth.rb
@@ -0,0 +1,86 @@
+require File.dirname(__FILE__) + '/helper'
+
+class TestRedCloth < Test::Unit::TestCase
+
+ context "RedCloth default (no explicit config) hard_breaks enabled" do
+ setup do
+ @textile = Converters::Textile.new
+ end
+
+ should "preserve single line breaks in HTML output" do
+ assert_equal "<p>line1<br />\nline2</p>", @textile.convert("p. line1\nline2").strip
+ end
+ end
+
+ context "Default hard_breaks enabled w/ redcloth section, no hard_breaks value" do
+ setup do
+ config = {
+ 'redcloth' => {}
+ }
+ @textile = Converters::Textile.new config
+ end
+
+ should "preserve single line breaks in HTML output" do
+ assert_equal "<p>line1<br />\nline2</p>", @textile.convert("p. line1\nline2").strip
+ end
+ end
+
+ context "RedCloth with hard_breaks enabled" do
+ setup do
+ config = {
+ 'redcloth' => {
+ 'hard_breaks' => true # default
+ }
+ }
+ @textile = Converters::Textile.new config
+ end
+
+ should "preserve single line breaks in HTML output" do
+ assert_equal "<p>line1<br />\nline2</p>", @textile.convert("p. line1\nline2").strip
+ end
+ end
+
+ context "RedCloth with hard_breaks disabled" do
+ setup do
+ config = {
+ 'redcloth' => {
+ 'hard_breaks' => false
+ }
+ }
+ @textile = Converters::Textile.new config
+ end
+
+ should "not generate break tags in HTML output" do
+ assert_equal "<p>line1\nline2</p>", @textile.convert("p. line1\nline2").strip
+ end
+ end
+
+ context "RedCloth w/no_span_caps set to false" do
+ setup do
+ config = {
+ 'redcloth' => {
+ 'no_span_caps' => false
+ }
+ }
+ @textile = Converters::Textile.new config
+ end
+ should "generate span tags around capitalized words" do
+ assert_equal "<p><span class=\"caps\">NSC</span></p>", @textile.convert("NSC").strip
+ end
+ end
+
+ context "RedCloth w/no_span_caps set to true" do
+ setup do
+ config = {
+ 'redcloth' => {
+ 'no_span_caps' => true
+ }
+ }
+ @textile = Converters::Textile.new config
+ end
+
+ should "not generate span tags around capitalized words" do
+ assert_equal "<p>NSC</p>", @textile.convert("NSC").strip
+ end
+ end
+end
diff --git a/test/test_related_posts.rb b/test/test_related_posts.rb
new file mode 100644
index 0000000..79409f8
--- /dev/null
+++ b/test/test_related_posts.rb
@@ -0,0 +1,47 @@
+require 'helper'
+
+class TestRelatedPosts < Test::Unit::TestCase
+ context "building related posts without lsi" do
+ setup do
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir,
+ 'destination' => dest_dir})
+ end
+ @site = Site.new(Jekyll.configuration)
+ end
+
+ should "use the most recent posts for related posts" do
+ @site.reset
+ @site.read
+
+ last_post = @site.posts.last
+ related_posts = Jekyll::RelatedPosts.new(last_post).build
+
+ last_10_recent_posts = (@site.posts.reverse - [last_post]).first(10)
+ assert_equal last_10_recent_posts, related_posts
+ end
+ end
+
+ context "building related posts with lsi" do
+ setup do
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir,
+ 'destination' => dest_dir,
+ 'lsi' => true})
+ end
+ any_instance_of(Jekyll::RelatedPosts) { |i| stub(i).display }
+ @site = Site.new(Jekyll.configuration)
+ end
+
+ should "use lsi for the related posts" do
+ @site.reset
+ @site.read
+ require 'classifier'
+ any_instance_of(::Classifier::LSI) do |c|
+ stub(c).find_related { @site.posts[-1..-9] }
+ stub(c).build_index
+ end
+ assert_equal @site.posts[-1..-9], Jekyll::RelatedPosts.new(@site.posts.last).build
+ end
+ end
+end
diff --git a/test/test_site.rb b/test/test_site.rb
index c9b991b..35359a2 100644
--- a/test/test_site.rb
+++ b/test/test_site.rb
@@ -1,18 +1,75 @@
require 'helper'
class TestSite < Test::Unit::TestCase
+ context "configuring sites" do
+ should "have an array for plugins by default" do
+ site = Site.new(Jekyll::Configuration::DEFAULTS)
+ assert_equal [File.join(Dir.pwd, '_plugins')], site.plugins
+ end
+
+ should "look for plugins under the site directory by default" do
+ site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'source' => File.expand_path(source_dir)}))
+ assert_equal [File.join(source_dir, '_plugins')], site.plugins
+ end
+
+ should "have an array for plugins if passed as a string" do
+ site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins' => '/tmp/plugins'}))
+ assert_equal ['/tmp/plugins'], site.plugins
+ end
+
+ should "have an array for plugins if passed as an array" do
+ site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins' => ['/tmp/plugins', '/tmp/otherplugins']}))
+ assert_equal ['/tmp/plugins', '/tmp/otherplugins'], site.plugins
+ end
+
+ should "have an empty array for plugins if nothing is passed" do
+ site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins' => []}))
+ assert_equal [], site.plugins
+ end
+
+ should "have an empty array for plugins if nil is passed" do
+ site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins' => nil}))
+ assert_equal [], site.plugins
+ end
+
+ should "expose default baseurl" do
+ site = Site.new(Jekyll::Configuration::DEFAULTS)
+ assert_equal Jekyll::Configuration::DEFAULTS['baseurl'], site.baseurl
+ end
+
+ should "expose baseurl passed in from config" do
+ site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'baseurl' => '/blog'}))
+ assert_equal '/blog', site.baseurl
+ end
+ end
context "creating sites" do
setup do
stub(Jekyll).configuration do
- Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir})
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir})
end
@site = Site.new(Jekyll.configuration)
+ @num_invalid_posts = 2
end
should "have an empty tag hash by default" do
assert_equal Hash.new, @site.tags
end
+ should "give site with parsed pages and posts to generators" do
+ @site.reset
+ @site.read
+ class MyGenerator < Generator
+ def generate(site)
+ site.pages.dup.each do |page|
+ raise "#{page} isn't a page" unless page.is_a?(Page)
+ raise "#{page} doesn't respond to :name" unless page.respond_to?(:name)
+ end
+ end
+ end
+ @site.generate
+ assert_not_equal 0, @site.pages.size
+ end
+
should "reset data before processing" do
clear_dest
@site.process
@@ -92,53 +149,63 @@ class TestSite < Test::Unit::TestCase
assert_equal mtime3, mtime4 # no modifications, so must be the same
end
+ should "setup plugins in priority order" do
+ assert_equal @site.converters.sort_by(&:class).map{|c|c.class.priority}, @site.converters.map{|c|c.class.priority}
+ assert_equal @site.generators.sort_by(&:class).map{|g|g.class.priority}, @site.generators.map{|g|g.class.priority}
+ end
+
should "read layouts" do
@site.read_layouts
- assert_equal ["default", "simple"].sort, @site.layouts.keys.sort
+ assert_equal ["default", "simple", "post/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
+ posts = Dir[source_dir('_posts', '**', '*')]
+ posts.delete_if { |post| File.directory?(post) && !Post.valid?(post) }
+ assert_equal posts.size - @num_invalid_posts, @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
+ posts = Dir[source_dir("**", "_posts", "**", "*")]
+ posts.delete_if { |post| File.directory?(post) && !Post.valid?(post) }
+ categories = %w(2013 bar baz category foo z_category publish_test win).sort
- assert_equal posts.size - 1, @site.posts.size
+ assert_equal posts.size - @num_invalid_posts, @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]
+ context 'error handling' do
+ should "raise if destination is included in source" do
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => source_dir})
+ end
- assert_equal %w[foo.markdown bar.markdown baz.markdown], @site.filter_entries(ent1)
- assert_equal %w[.htaccess bla.bla], @site.filter_entries(ent2)
- end
+ assert_raise Jekyll::FatalException do
+ site = Site.new(Jekyll.configuration)
+ end
+ end
- should "filter entries with exclude" do
- excludes = %w[README TODO]
- includes = %w[index.html site.css]
+ should "raise if destination is source" do
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => File.join(source_dir, "..")})
+ end
- @site.exclude = excludes
- assert_equal includes, @site.filter_entries(excludes + includes)
+ assert_raise Jekyll::FatalException do
+ site = Site.new(Jekyll.configuration)
+ end
+ end
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
@@ -146,25 +213,48 @@ class TestSite < Test::Unit::TestCase
File.open(dest_dir('qux/obsolete.html'), 'w')
# empty directory
FileUtils.mkdir(dest_dir('quux'))
+ FileUtils.mkdir(dest_dir('.git'))
+ FileUtils.mkdir(dest_dir('.svn'))
+ FileUtils.mkdir(dest_dir('.hg'))
+ # single file in repository
+ File.open(dest_dir('.git/HEAD'), 'w')
+ File.open(dest_dir('.svn/HEAD'), 'w')
+ File.open(dest_dir('.hg/HEAD'), 'w')
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'))
+ FileUtils.rm_rf(dest_dir('.git'))
+ FileUtils.rm_rf(dest_dir('.svn'))
+ FileUtils.rm_rf(dest_dir('.hg'))
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'))
+ assert File.exist?(dest_dir('.git'))
+ assert File.exist?(dest_dir('.git/HEAD'))
end
+ should 'remove orphaned files in destination - keep_files .svn' do
+ config = Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'keep_files' => ['.svn']})
+ @site = Site.new(config)
+ @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'))
+ assert !File.exist?(dest_dir('.git'))
+ assert !File.exist?(dest_dir('.git/HEAD'))
+ assert File.exist?(dest_dir('.svn'))
+ assert File.exist?(dest_dir('.svn/HEAD'))
+ 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'
@@ -172,7 +262,7 @@ class TestSite < Test::Unit::TestCase
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 }))
@@ -181,6 +271,63 @@ class TestSite < Test::Unit::TestCase
end
end
end
-
+
+ context 'data directory' do
+ should 'auto load yaml files' do
+ site = Site.new(Jekyll.configuration)
+ site.process
+
+ file_content = YAML.safe_load_file(File.join(source_dir, '_data', 'members.yaml'))
+
+ assert_equal site.data['members'], file_content
+ assert_equal site.site_payload['site']['data']['members'], file_content
+ end
+
+ should 'auto load yml files' do
+ site = Site.new(Jekyll.configuration)
+ site.process
+
+ file_content = YAML.safe_load_file(File.join(source_dir, '_data', 'languages.yml'))
+
+ assert_equal site.data['languages'], file_content
+ assert_equal site.site_payload['site']['data']['languages'], file_content
+ end
+
+ should "load symlink files in unsafe mode" do
+ site = Site.new(Jekyll.configuration.merge({'safe' => false}))
+ site.process
+
+ file_content = YAML.safe_load_file(File.join(source_dir, '_data', 'products.yml'))
+
+ assert_equal site.data['products'], file_content
+ assert_equal site.site_payload['site']['data']['products'], file_content
+ end
+
+ should "not load symlink files in safe mode" do
+ site = Site.new(Jekyll.configuration.merge({'safe' => true}))
+ site.process
+
+ assert_nil site.data['products']
+ assert_nil site.site_payload['site']['data']['products']
+ end
+
+ should "load symlink directory in unsafe mode" do
+ site = Site.new(Jekyll.configuration.merge({'safe' => false, 'data_source' => File.join('symlink-test', '_data')}))
+ site.process
+
+ assert_not_nil site.data['products']
+ assert_not_nil site.data['languages']
+ assert_not_nil site.data['members']
+ end
+
+ should "not load symlink directory in safe mode" do
+ site = Site.new(Jekyll.configuration.merge({'safe' => true, 'data_source' => File.join('symlink-test', '_data')}))
+ site.process
+
+ assert_nil site.data['products']
+ assert_nil site.data['languages']
+ assert_nil site.data['members']
+ end
+ end
end
end
diff --git a/test/test_tags.rb b/test/test_tags.rb
index 5075075..0368c6d 100644
--- a/test/test_tags.rb
+++ b/test/test_tags.rb
@@ -4,17 +4,22 @@ require 'helper'
class TestTags < Test::Unit::TestCase
- def create_post(content, override = {}, converter_class = Jekyll::MarkdownConverter)
+ def create_post(content, override = {}, converter_class = Jekyll::Converters::Markdown)
stub(Jekyll).configuration do
- Jekyll::DEFAULTS.merge({'pygments' => true}).merge(override)
+ Jekyll::Configuration::DEFAULTS.deep_merge({'pygments' => true}).deep_merge(override)
end
site = Site.new(Jekyll.configuration)
+
+ if override['read_posts']
+ site.read_posts('')
+ end
+
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 = Liquid::Template.parse(content).render!(payload, info)
@result = @converter.convert(@result)
end
@@ -27,10 +32,49 @@ title: This is a test
This document results in a markdown error with maruku
{% highlight text %}#{code}{% endhighlight %}
+{% highlight text linenos %}#{code}{% endhighlight %}
CONTENT
create_post(content, override)
end
+ context "language name" do
+ should "match only the required set of chars" do
+ r = Jekyll::Tags::HighlightBlock::SYNTAX
+ assert_match r, "ruby"
+ assert_match r, "c#"
+ assert_match r, "xml+cheetah"
+ assert_match r, "x.y"
+ assert_match r, "coffee-script"
+
+ assert_no_match r, "blah^"
+
+ assert_match r, "ruby key=val"
+ assert_match r, "ruby a=b c=d"
+ end
+ end
+
+ context "initialized tag" do
+ should "work" do
+ tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby ', ["test", "{% endhighlight %}", "\n"])
+ assert_equal({}, tag.instance_variable_get(:@options))
+
+ tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos ', ["test", "{% endhighlight %}", "\n"])
+ assert_equal({ 'linenos' => 'inline' }, tag.instance_variable_get(:@options))
+
+ tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table ', ["test", "{% endhighlight %}", "\n"])
+ assert_equal({ 'linenos' => 'table' }, tag.instance_variable_get(:@options))
+
+ tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table nowrap', ["test", "{% endhighlight %}", "\n"])
+ assert_equal({ 'linenos' => 'table', 'nowrap' => true }, tag.instance_variable_get(:@options))
+
+ tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table cssclass=hl', ["test", "{% endhighlight %}", "\n"])
+ assert_equal({ 'cssclass' => 'hl', 'linenos' => 'table' }, tag.instance_variable_get(:@options))
+
+ tag = Jekyll::Tags::HighlightBlock.new('highlight', 'Ruby ', ["test", "{% endhighlight %}", "\n"])
+ assert_equal "ruby", tag.instance_variable_get(:@lang), "lexers should be case insensitive"
+ end
+ end
+
context "post content has highlight tag" do
setup do
fill_post("test")
@@ -40,9 +84,13 @@ CONTENT
assert_no_match /markdown\-html\-error/, @result
end
- should "render markdown with pygments line handling" do
+ should "render markdown with pygments" do
assert_match %{<pre><code class='text'>test\n</code></pre>}, @result
end
+
+ should "render markdown with pygments with line numbers" do
+ assert_match %{<pre><code class='text'><span class='lineno'>1</span> test\n</code></pre>}, @result
+ end
end
context "post content has highlight with file reference" do
@@ -84,7 +132,7 @@ CONTENT
context "using Textile" do
setup do
- create_post(@content, {}, Jekyll::TextileConverter)
+ create_post(@content, {}, Jekyll::Converters::Textile)
end
# Broken in RedCloth 4.1.9
@@ -125,7 +173,7 @@ CONTENT
assert_match %r{<em>FINISH HIM</em>}, @result
end
end
-
+
context "using Redcarpet" do
setup do
create_post(@content, 'markdown' => 'redcarpet')
@@ -137,4 +185,271 @@ CONTENT
end
end
end
+
+ context "simple page with post linking" do
+ setup do
+ content = <<CONTENT
+---
+title: Post linking
+---
+
+{% post_url 2008-11-21-complex %}
+CONTENT
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ should "not cause an error" do
+ assert_no_match /markdown\-html\-error/, @result
+ end
+
+ should "have the url to the \"complex\" post from 2008-11-21" do
+ assert_match %r{/2008/11/21/complex/}, @result
+ end
+ end
+
+ context "simple page with nested post linking" do
+ setup do
+ content = <<CONTENT
+---
+title: Post linking
+---
+
+- 1 {% post_url 2008-11-21-complex %}
+- 2 {% post_url /2008-11-21-complex %}
+- 3 {% post_url es/2008-11-21-nested %}
+- 4 {% post_url /es/2008-11-21-nested %}
+CONTENT
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ should "not cause an error" do
+ assert_no_match /markdown\-html\-error/, @result
+ end
+
+ should "have the url to the \"complex\" post from 2008-11-21" do
+ assert_match %r{1\s/2008/11/21/complex/}, @result
+ assert_match %r{2\s/2008/11/21/complex/}, @result
+ end
+
+ should "have the url to the \"nested\" post from 2008-11-21" do
+ assert_match %r{3\s/2008/11/21/nested/}, @result
+ assert_match %r{4\s/2008/11/21/nested/}, @result
+ end
+ end
+
+ context "gist tag" do
+ context "simple" do
+ setup do
+ @gist = 358471
+ content = <<CONTENT
+---
+title: My Cool Gist
+---
+
+{% gist #{@gist} %}
+CONTENT
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ should "write script tag" do
+ assert_match "<script src='https://gist.github.com/#{@gist}.js'><![CDATA[\s]]></script>", @result
+ end
+ end
+
+ context "for private gist" do
+ context "when valid" do
+ setup do
+ @gist = "mattr-/24081a1d93d2898ecf0f"
+ @filename = "myfile.ext"
+ content = <<CONTENT
+ ---
+ title: My Cool Gist
+ ---
+
+ {% gist #{@gist} #{@filename} %}
+CONTENT
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ should "write script tag with specific file in gist" do
+ assert_match "<script src='https://gist.github.com/#{@gist}.js?file=#{@filename}'><![CDATA[\s]]></script>", @result
+ end
+ end
+
+ should "raise ArgumentError when invalid" do
+ @gist = "mattr-24081a1d93d2898ecf0f"
+ @filename = "myfile.ext"
+ content = <<CONTENT
+ ---
+ title: My Cool Gist
+ ---
+
+ {% gist #{@gist} #{@filename} %}
+CONTENT
+
+ assert_raise ArgumentError do
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+ end
+ end
+
+ context "with specific file" do
+ setup do
+ @gist = 358471
+ @filename = 'somefile.rb'
+ content = <<CONTENT
+---
+title: My Cool Gist
+---
+
+{% gist #{@gist} #{@filename} %}
+CONTENT
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ should "write script tag with specific file in gist" do
+ assert_match "<script src='https://gist.github.com/#{@gist}.js?file=#{@filename}'><![CDATA[\s]]></script>", @result
+ end
+ end
+
+ context "with blank gist id" do
+ should "raise ArgumentError" do
+ content = <<CONTENT
+---
+title: My Cool Gist
+---
+
+{% gist %}
+CONTENT
+
+ assert_raise ArgumentError do
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+ end
+ end
+
+ context "with invalid gist id" do
+ should "raise ArgumentError" do
+ invalid_gist = 'invalid'
+ content = <<CONTENT
+---
+title: My Cool Gist
+---
+
+{% gist #{invalid_gist} %}
+CONTENT
+
+ assert_raise ArgumentError do
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+ end
+ end
+ end
+
+ context "include tag with parameters" do
+ context "with one parameter" do
+ setup do
+ content = <<CONTENT
+---
+title: Include tag parameters
+---
+
+{% include sig.markdown myparam="test" %}
+
+{% include params.html param="value" %}
+CONTENT
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ should "correctly output include variable" do
+ assert_match "<span id='include-param'>value</span>", @result.strip
+ end
+
+ should "ignore parameters if unused" do
+ assert_match "<hr />\n<p>Tom Preston-Werner github.com/mojombo</p>\n", @result
+ end
+ end
+
+ context "with invalid parameter syntax" do
+ should "throw a ArgumentError" do
+ content = <<CONTENT
+---
+title: Invalid parameter syntax
+---
+
+{% include params.html param s="value" %}
+CONTENT
+ assert_raise ArgumentError, 'Did not raise exception on invalid "include" syntax' do
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ content = <<CONTENT
+---
+title: Invalid parameter syntax
+---
+
+{% include params.html params="value %}
+CONTENT
+ assert_raise ArgumentError, 'Did not raise exception on invalid "include" syntax' do
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+ end
+ end
+
+ context "with several parameters" do
+ setup do
+ content = <<CONTENT
+---
+title: multiple include parameters
+---
+
+{% include params.html param1="new_value" param2="another" %}
+CONTENT
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ should "list all parameters" do
+ assert_match '<li>param1 = new_value</li>', @result
+ assert_match '<li>param2 = another</li>', @result
+ end
+
+ should "not include previously used parameters" do
+ assert_match "<span id='include-param' />", @result
+ end
+ end
+
+ context "without parameters" do
+ setup do
+ content = <<CONTENT
+---
+title: without parameters
+---
+
+{% include params.html %}
+CONTENT
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ should "include file with empty parameters" do
+ assert_match "<span id='include-param' />", @result
+ end
+ end
+
+ context "without parameters within if statement" do
+ setup do
+ content = <<CONTENT
+---
+title: without parameters within if statement
+---
+
+{% if true %}{% include params.html %}{% endif %}
+CONTENT
+ create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
+ end
+
+ should "include file with empty parameters within if statement" do
+ assert_match "<span id='include-param' />", @result
+ end
+ end
+ end
end
diff --git a/test/test_url.rb b/test/test_url.rb
new file mode 100644
index 0000000..0576eda
--- /dev/null
+++ b/test/test_url.rb
@@ -0,0 +1,28 @@
+require 'helper'
+
+class TestURL < Test::Unit::TestCase
+ context "The URL class" do
+
+ should "throw an exception if neither permalink or template is specified" do
+ assert_raises ArgumentError do
+ URL.new(:placeholders => {})
+ end
+ end
+
+ should "replace placeholders in templates" do
+ assert_equal "/foo/bar", URL.new(
+ :template => "/:x/:y",
+ :placeholders => {:x => "foo", :y => "bar"}
+ ).to_s
+ end
+
+ should "return permalink if given" do
+ assert_equal "/le/perma/link", URL.new(
+ :template => "/:x/:y",
+ :placeholders => {:x => "foo", :y => "bar"},
+ :permalink => "/le/perma/link"
+ ).to_s
+ end
+
+ end
+end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/jekyll.git
More information about the Pkg-ruby-extras-commits
mailing list