diff --git a/.codeclimate.yml b/.codeclimate.yml
new file mode 100644
index 00000000..6e860b75
--- /dev/null
+++ b/.codeclimate.yml
@@ -0,0 +1,29 @@
+engines:
+ rubocop: { enabled: true }
+ fixme: { enabled: false }
+exclude_paths:
+- .rubocop.yml
+- .codeclimate.yml
+- .travis.yml
+- .gitignore
+- .rspec
+
+- Gemfile.lock
+- CHANGELOG.{md,markdown,txt,textile}
+- CONTRIBUTING.{md,markdown,txt,textile}
+- readme.{md,markdown,txt,textile}
+- README.{md,markdown,txt,textile}
+- Readme.{md,markdown,txt,textile}
+- ReadMe.{md,markdown,txt,textile}
+- COPYING
+- LICENSE
+
+- site/**/*
+- test/**/*
+- vendor/**/*
+- features/**/*
+- script/**/*
+- spec/**/*
+ratings:
+ paths:
+ - lib/**/*.rb
diff --git a/.github/CONTRIBUTING.markdown b/.github/CONTRIBUTING.markdown
new file mode 100644
index 00000000..8181037a
--- /dev/null
+++ b/.github/CONTRIBUTING.markdown
@@ -0,0 +1,122 @@
+# Contributing to Jekyll
+
+Hi there! Interested in contributing to Jekyll? We'd love your help. Jekyll is an open source project, built one contribution at a time by users like you.
+
+## Where to get help or report a problem
+
+* If you have a question about using Jekyll, start a discussion on [Jekyll Talk](https://talk.jekyllrb.com).
+* If you think you've found a bug within a Jekyll plugin, open an issue in that plugin's repository.
+* If you think you've found a bug within Jekyll itself, [open an issue](https://github.com/jekyll/jekyll/issues/new)
+* More resources are listed on our [Help page](https://jekyllrb.com/help/)
+
+## Ways to contribute
+
+Whether you're a developer, a designer, or just a Jekyll devotee, there are lots of ways to contribute. Here's a few ideas:
+
+* [Install Jekyll on your computer](https://jekyllrb.com/docs/installation/) and kick the tires. Does it work? Does it do what you'd expect? If not, [open an issue](https://github.com/jekyll/jekyll/issues/new) and let us know.
+* Comment on some of the project's [open issues](https://github.com/jekyll/jekyll/issues). Have you experienced the same problem? Know a work around? Do you have a suggestion for how the feature could be better?
+* Read through [the documentation](https://jekyllrb.com/docs/home/), and click the "improve this page" button, any time you see something confusing, or have a suggestion for something that could be improved.
+* Browse through [the Jekyll discussion forum](https://talk.jekyllrb.com/), and lend a hand answering questions. There's a good chance you've already experienced what another user is experiencing.
+* Find [an open issue](https://github.com/jekyll/jekyll/issues) (especially [those labeled `help-wanted`](https://github.com/jekyll/jekyll/issues?q=is%3Aopen+is%3Aissue+label%3Ahelp-wanted)), and submit a proposed fix. If it's your first pull request, we promise we won't bite, and are glad to answer any questions.
+* Help evaluate [open pull requests](https://github.com/jekyll/jekyll/pulls), by testing the changes locally and reviewing what's proposed.
+
+## Submitting a pull request
+
+### Pull requests generally
+
+* The smaller the proposed change, the better. If you'd like to propose two unrelated changes, submit two pull requests.
+
+* The more information, the better. Make judicious use of the pull request body. Describe what changes were made, why you made them, and what impact they will have for users.
+
+* Pull request are easy and fun. If this is your first pull request, it may help to [understand GitHub Flow](https://guides.github.com/introduction/flow/)
+
+* If you're submitting a code contribution, be sure to read the [code contributions](#code-contributions) section below.
+
+### Submitting a pull request via github.com
+
+Many small changes can be made entirely through the github.com web interface.
+
+1. Navigate to the file within [`jekyll/jekyll`](https://github.com/jekyll/jekyll) that you'd like to edit
+2. Click the pencil icon in the top right corner to edit the file
+3. Make your proposed changes
+4. Click "Propose file change"
+5. Click "Create pull request"
+6. Add a descriptive title and detailed description for your proposed change. The more information the better.
+7. Click "Create pull request"
+
+That's it! You'll be automatically subscribed to receive updates as others review your proposed change and provide feedback.
+
+### Submitting a pull request via Git command line
+
+1. Fork the project by clicking "Fork" in the top right corner of [`jekyll/jekyll`](https://github.com/jekyll/jekyll)
+2. Clone the repository lcoally `git clone https://github.com//jekyll`
+3. Create a new, descriptively named branch to contain your change ( `git checkout -b my-awesome-feature` ).
+4. Hack away, add tests. Not necessarily in that order.
+5. Make sure everything still passes by running `script/cibuild` (see [the tests section](#running-tests-locally) below)
+6. Push the branch up ( `git push origin my-awesome-feature` ).
+7. Create a pull request by visiting https://github.com//jekyll/ and following the instructions at the top of the screen.
+
+## Proposing updates to the 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.
+
+### How to submit changes
+
+You can find the documentation for jekyllrb.com in the [site](https://github.com/jekyll/jekyll/tree/master/site) directory. See the section above, [submitting a pull request](#submitting-a-pull-request) for information on how to propose a change.
+
+One gotcha, all pull requests should be directed at the `master` branch (the default branch).
+
+### Adding plugins
+
+If you want to add your plugin to the [list of plugins](https://jekyllrb.com/docs/plugins/#available-plugins), please submit a pull request modifying the [plugins page source file](site/_docs/plugins.md) by adding a link to your plugin under the proper subheading depending upon its type.
+
+## Code Contributions
+
+Interesting in submitting a pull request? Awesome. Read on. There's a few common gotchas that we'd love to help you avoid.
+
+### Tests and documentation
+
+Any time you propose a code change, you should also include updates to the documentation and tests within the same pull request.
+
+#### Documentation
+
+If your contribution changes any Jekyll behavior, make sure to update the documentation. Documentation lives in the `site/_docs` folder (spoiler alert: it's a Jekyll site!). If the docs are missing information, please feel free to add it in. Great docs make a great project. Include changes to the documentation within your pull request, and once merged, `jekyllrb.com` will be updated.
+
+#### Tests
+
+* If you're creating a small fix or patch to an existing feature, a simple test if more than enough. You can usually copy/paste from an existing example in the `tests` folder, but if you need to can find out about our tests suites [Shoulda](https://github.com/thoughtbot/shoulda/tree/master) and [RSpec-Mocks](https://github.com/rspec/rspec-mocks).
+
+* If it's a brand new feature, create a new [Cucumber](https://github.com/cucumber/cucumber/) feature, reusing existing steps where appropriate.
+
+### Code contributions generally
+
+* Jekyll follows the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby).
+
+* Don't bump the Gem version in your pull request (if you don't know what that means, you probably didn't).
+
+## Running tests locally
+
+### Test Dependencies
+
+To run the test suite and build the gem you'll need to install Jekyll's dependencies by running the following command:
+
+ $ script/bootstrap
+
+Before you make any changes, run the tests and make sure that they pass (to confirm your environment is configured properly):
+
+ $ script/cibuild
+
+If you are only updating a file in `test/`, you can use the command:
+
+ $ script/test test/blah_test.rb
+
+If you are only updating a `.feature` file, you can use the command:
+
+ $ script/cucumber features/blah.feature
+
+Both `script/test` and `script/cucumber` can be run without arguments to
+run its entire respective suite.
+
+## A thank you
+
+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/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000..614de1c9
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,20 @@
+###### What version of Jekyll are you using (`jekyll -v`)?
+
+
+
+###### What operating system are you using?
+
+
+
+###### What did you do?
+(Please include the content causing the issue, any relevant configuration settings, and the command you ran)
+
+
+
+###### What did you expect to see?
+
+
+
+###### What did you see instead?
+
+
diff --git a/.gitignore b/.gitignore
index d75a4982..1d62ecc3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,20 +1,22 @@
-Gemfile.lock
-test/dest
*.gem
-pkg/
*.swp
*~
-_site/
-.bundle/
.DS_Store
-bbin/
-gh-pages/
-site/_site/
-coverage
-.ruby-version
-.ruby-gemset
-.sass-cache
-tmp/*
+.analysis
+.bundle/
+.byebug_history
.jekyll-metadata
-/vendor
+.ruby-gemset
+.ruby-version
+.sass-cache
/test/source/file_name.txt
+/vendor
+Gemfile.lock
+_site/
+bbin/
+coverage
+gh-pages/
+pkg/
+site/_site/
+test/dest
+tmp/*
diff --git a/.jrubyrc b/.jrubyrc
index c4f93701..39aa437d 100644
--- a/.jrubyrc
+++ b/.jrubyrc
@@ -1,6 +1,3 @@
backtrace.mask=true
-compile.invokedynamic=true
-objectspace.enabled=true
backtrace.color=true
-compat.version=2.2
backtrace.style=mri
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 00000000..1f0ffeb2
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,80 @@
+Metrics/MethodLength: { Max: 24 }
+Metrics/ClassLength: { Max: 240 }
+Metrics/ModuleLength: { Max: 240 }
+Metrics/LineLength: { Max: 112 }
+Metrics/CyclomaticComplexity: { Max: 8 }
+Metrics/PerceivedComplexity: { Max: 8 }
+Metrics/ParameterLists: { Max: 4 }
+Metrics/MethodLength: { Max: 24 }
+Metrics/AbcSize: { Max: 20 }
+
+Style/IndentHash: { EnforcedStyle: consistent }
+Style/HashSyntax: { EnforcedStyle: hash_rockets }
+Style/SignalException: { EnforcedStyle: only_raise }
+Style/AlignParameters: { EnforcedStyle: with_fixed_indentation }
+Style/StringLiteralsInInterpolation: { EnforcedStyle: double_quotes }
+Style/MultilineMethodCallIndentation: { EnforcedStyle: indented }
+Style/MultilineOperationIndentation: { EnforcedStyle: indented }
+Style/FirstParameterIndentation: { EnforcedStyle: consistent }
+Style/StringLiterals: { EnforcedStyle: double_quotes }
+Style/RegexpLiteral: { EnforcedStyle: slashes }
+Style/IndentArray: { EnforcedStyle: consistent }
+Style/ExtraSpacing: { AllowForAlignment: true }
+
+Style/PercentLiteralDelimiters:
+ PreferredDelimiters:
+ '%q': '{}'
+ '%Q': '{}'
+ '%r': '!!'
+ '%s': '()'
+ '%w': '()'
+ '%W': '()'
+ '%x': '()'
+
+Style/AlignArray: { Enabled: false }
+Style/StringLiterals: { Enabled: false }
+Style/Documentation: { Enabled: false }
+Style/DoubleNegation: { Enabled: false }
+Style/UnneededCapitalW: { Enabled: false }
+Style/EmptyLinesAroundModuleBody: { Enabled: false }
+Style/EmptyLinesAroundAccessModifier: { Enabled: false }
+Style/BracesAroundHashParameters: { Enabled: false }
+Style/SpaceInsideBrackets: { Enabled: false }
+Style/IfUnlessModifier: { Enabled: false }
+Style/ModuleFunction: { Enabled: false }
+Style/RescueModifier: { Enabled: false }
+Style/GuardClause: { Enabled: false }
+Style/FileName: { Enabled: false }
+Lint/UselessAccessModifier: { Enabled: false }
+Style/SpaceAroundOperators: { Enabled: false }
+Style/RedundantReturn: { Enabled: false }
+Style/SingleLineMethods: { Enabled: false }
+
+AllCops:
+ TargetRubyVersion: 2.0
+ Include:
+ - lib/**/*.rb
+
+ Exclude:
+ - .rubocop.yml
+ - .codeclimate.yml
+ - .travis.yml
+ - .gitignore
+ - .rspec
+
+ - Gemfile.lock
+ - CHANGELOG.{md,markdown,txt,textile}
+ - CONTRIBUTING.{md,markdown,txt,textile}
+ - readme.{md,markdown,txt,textile}
+ - README.{md,markdown,txt,textile}
+ - Readme.{md,markdown,txt,textile}
+ - ReadMe.{md,markdown,txt,textile}
+ - COPYING
+ - LICENSE
+
+ - site/**/*
+ - test/**/*
+ - vendor/**/*
+ - features/**/*
+ - script/**/*
+ - spec/**/*
diff --git a/.travis.yml b/.travis.yml
index 1b25cf93..842bfa90 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,30 +1,52 @@
-language: ruby
+before_script: bundle update
+bundler_args: --without benchmark:site:development
+script: script/cibuild
cache: bundler
+language: ruby
sudo: false
+
rvm:
-- 2.2
-- 2.1
-- 2.0
-- jruby-head
+ - &ruby1 2.3.0
+ - &ruby2 2.2.4
+ - &ruby3 2.1.8
+ - &jruby jruby-9.0.4.0
+ - &rhead ruby-head
+
matrix:
+ fast_finish: true
allow_failures:
- - rvm: jruby-head
+ - rvm: *jruby
+ - rvm: *rhead
env:
matrix:
- TEST_SUITE=test
- TEST_SUITE=cucumber
-before_script: bundle update
-script: script/cibuild
+
+branches:
+ only:
+ - master
+
notifications:
irc:
- on_success: change
- on_failure: change
- channels:
- - irc.freenode.org#jekyll
- template:
- - "%{repository}#%{build_number} (%{branch}) %{message} %{build_url}"
+ template: "%{repository}#%{build_number} (%{branch}) %{message} %{build_url}"
+ channels: irc.freenode.org#jekyll
+
email:
- on_success: never
- on_failure: never
+ recipients:
+ - jordon@envygeeks.io
+
slack:
- secure: dNdKk6nahNURIUbO3ULhA09/vTEQjK0fNbgjVjeYPEvROHgQBP1cIP3AJy8aWs8rl5Yyow4YGEilNRzKPz18AsFptVXofpwyqcBxaCfmHP809NX5PHBaadydveLm+TNVao2XeLXSWu+HUNAYO1AanCUbJSEyJTju347xCBGzESU=
+ secure: "\
+ dNdKk6nahNURIUbO3ULhA09/vTEQjK0fNbgjVjeYPEvROHgQBP1cIP3AJy8aWs8rl5Yyow4Y\
+ GEilNRzKPz18AsFptVXofpwyqcBxaCfmHP809NX5PHBaadydveLm+TNVao2XeLXSWu+HUNAY\
+ O1AanCUbJSEyJTju347xCBGzESU=\
+ "
+
+addons:
+ code_climate:
+ repo_token:
+ secure: "\
+ mAuvDu+nrzB8dOaLqsublDGt423mGRyZYM3vsrXh4Tf1sT+L1PxsRzU4gLmcV27HtX2Oq9\
+ DA4vsRURfABU0fIhwYkQuZqEcA3d8TL36BZcGEshG6MQ2AmnYsmFiTcxqV5bmlElHEqQuT\
+ 5SUFXLafgZPBnL0qDwujQcHukID41sE=\
+ "
diff --git a/CONDUCT.markdown b/CONDUCT.markdown
new file mode 100644
index 00000000..8425dfc7
--- /dev/null
+++ b/CONDUCT.markdown
@@ -0,0 +1,49 @@
+# Code of Conduct
+
+As contributors and maintainers of this project, and in the interest of
+fostering an open and welcoming community, we pledge to respect all people who
+contribute through reporting issues, posting feature requests, updating
+documentation, submitting pull requests or patches, and other activities.
+
+We are committed to making participation in this project a harassment-free
+experience for everyone, regardless of level of experience, gender, gender
+identity and expression, sexual orientation, disability, personal appearance,
+body size, race, ethnicity, age, religion, or nationality.
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery
+* Personal attacks
+* Trolling or insulting/derogatory comments
+* Public or private harassment
+* Publishing other's private information, such as physical or electronic
+ addresses, without explicit permission
+* Other unethical or unprofessional conduct
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+By adopting this Code of Conduct, project maintainers commit themselves to
+fairly and consistently applying these principles to every aspect of managing
+this project. Project maintainers who do not follow or enforce the Code of
+Conduct may be permanently removed from the project team.
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community.
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by opening an issue or contacting a project maintainer. All complaints
+will be reviewed and investigated and will result in a response that is deemed
+necessary and appropriate to the circumstances. Maintainers are obligated to
+maintain confidentiality with regard to the reporter of an incident.
+
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 1.3.0, available at
+[http://contributor-covenant.org/version/1/3/0/][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/3/0/
diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown
deleted file mode 100644
index 0f5be303..00000000
--- a/CONTRIBUTING.markdown
+++ /dev/null
@@ -1,92 +0,0 @@
-Contribute
-==========
-
-So you've got an awesome idea to throw into Jekyll. Great! Please keep the
-following in mind:
-
-* **Use https://talk.jekyllrb.com for non-technical or indirect Jekyll questions that are not bugs.**
-* **Contributions will not be accepted without tests or necessary documentation updates.**
-* 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](https://github.com/thoughtbot/shoulda/tree/master) and
- [RSpec-Mocks](https://github.com/rspec/rspec-mocks).
-* 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@github.com:/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 jekyll/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/jekyll/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/jekyll/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 jekyll/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 1d0caa3b..b27211cb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,47 +1,88 @@
-source 'https://rubygems.org'
-gemspec
+source "https://rubygems.org"
+gemspec :name => "jekyll"
-gem 'pry'
-gem 'toml', '~> 0.1.0'
-gem 'jekyll-paginate', '~> 1.0'
-gem 'jekyll-gist', '~> 1.0'
-gem 'jekyll-coffeescript', '~> 1.0'
+gem "rake", "~> 10.1"
+group :development do
+ gem "launchy", "~> 2.3"
+ gem "rubocop", :branch => :master, :github => "bbatsov/rubocop"
+ gem "pry"
-platform :ruby, :mswin, :mingw do
- gem 'pygments.rb', '~> 0.6.0'
- gem 'rdiscount', '~> 2.0'
- gem 'classifier-reborn', '~> 2.0'
- gem 'redcarpet', '~> 3.2', '>= 3.2.3'
- gem 'liquid-c', '~> 3.0'
+ unless RUBY_ENGINE == "jruby"
+ gem "pry-byebug"
+ end
end
-if RUBY_PLATFORM =~ /cygwin/ || RUBY_VERSION.start_with?("2.2")
- gem 'test-unit'
+#
+
+group :test do
+ gem "cucumber", "~> 2.1"
+ gem "jekyll_test_plugin"
+ gem "jekyll_test_plugin_malicious"
+ gem "codeclimate-test-reporter"
+ gem "rspec-mocks"
+ gem "nokogiri"
+ gem "rspec"
end
-gem 'rake', '~> 10.1'
-gem 'rdoc', '~> 4.2'
-gem 'redgreen', '~> 1.2'
-gem 'shoulda', '~> 3.5'
-gem 'cucumber', '~> 2.0'
-gem 'launchy', '~> 2.3'
-gem 'simplecov', '~> 0.9'
-gem 'mime-types', '~> 2.6'
-gem 'kramdown', '~> 1.7.0'
-gem 'jekyll_test_plugin'
-gem 'jekyll_test_plugin_malicious'
-gem 'minitest-reporters'
-gem 'minitest-profile'
-gem 'minitest'
-gem 'rspec-mocks'
+#
-if ENV['BENCHMARK']
- gem 'ruby-prof'
- gem 'rbtrace'
- gem 'stackprof'
- gem 'benchmark-ips'
+group :test_legacy do
+ if RUBY_PLATFORM =~ /cygwin/ || RUBY_VERSION.start_with?("2.2")
+ gem 'test-unit'
+ end
+
+ gem "redgreen"
+ gem "simplecov"
+ gem "minitest-reporters"
+ gem "minitest-profile"
+ gem "minitest"
+ gem "shoulda"
end
-if ENV['PROOF']
- gem 'html-proofer', '~> 2.0'
+#
+
+group :benchmark do
+ if ENV["BENCHMARK"]
+ gem "ruby-prof"
+ gem "benchmark-ips"
+ gem "stackprof"
+ gem "rbtrace"
+ end
+end
+
+#
+
+group :jekyll_optional_dependencies do
+ gem "toml", "~> 0.1.0"
+ gem "coderay", "~> 1.1.0"
+ gem "jekyll-docs", :path => '../docs' if Dir.exist?('../docs') && ENV['JEKYLL_VERSION']
+ gem "jekyll-gist", "~> 1.0"
+ gem "jekyll-feed", "~> 0.1.3"
+ gem "jekyll-coffeescript", "~> 1.0"
+ gem "jekyll-redirect-from", "~> 0.9.1"
+ gem "jekyll-paginate", "~> 1.0"
+ gem "mime-types", "~> 3.0"
+ gem "kramdown", "~> 1.9"
+ gem "rdoc", "~> 4.2"
+
+ platform :ruby, :mswin, :mingw do
+ gem "rdiscount", "~> 2.0"
+ gem "pygments.rb", "~> 0.6.0"
+ gem "redcarpet", "~> 3.2", ">= 3.2.3"
+ gem "classifier-reborn", "~> 2.0"
+ gem "liquid-c", "~> 3.0"
+ end
+end
+
+#
+
+group :site do
+ if ENV["PROOF"]
+ gem "html-proofer", "~> 2.0"
+ end
+
+ gem "jemoji", "0.5.1"
+ gem "jekyll-sitemap"
+ gem "jekyll-seo-tag", "~> 1.1"
+ gem "jekyll-avatar"
end
diff --git a/History.markdown b/History.markdown
index d0738c09..ad1a7345 100644
--- a/History.markdown
+++ b/History.markdown
@@ -1,11 +1,258 @@
## HEAD
+### Minor Enhancements
+
+ * Stop testing with Ruby 2.0.x, which is EOL'd. (#4381)
+ * Allow collections to have documents that have no file extension (#4545)
+ * Add size property to group_by result (#4557)
+ * Site Template: Removed unnecessary nesting from `_base.scss` (#4637)
+ * Adding a debug log statment for skipped future documents. (#4558)
+ * Site Template: Changed main `
` to `` and added accessibility info (#4636)
+ * Add array support to `where` filter (#4555)
+ * 'jekyll clean': also remove .sass-cache (#4652)
+ * Clean up Tags::PostUrl a bit, including better errors and date parsing (#4670)
+ * Use String#encode for xml_escape filter instead of CGI.escapeHTML (#4694)
+ * Add show_dir_listing option for serve command and fix index file names (#4533)
+
+### Bug Fixes
+
+ * Site Template: Added a default lang attribute (#4633)
+ * Site template: Escape title and description where it is used in HTML (#4606)
+ * Document#date: drafts which have no date should use source file mtime (#4611)
+ * Filters#time: clone an input Time so as to be non-destructive (#4590)
+ * Doctor: fix issue where `--config` wasn't a recognized flag (#4598)
+ * Ensures related_posts are only set for a post (#4620)
+ * EntryFilter#special?: ignore filenames which begin with '~' (#4491)
+
+### Development Fixes
+
+ * Add project maintainer profile links (#4591)
+ * Fix state leakage in Kramdown test (#4618)
+ * Unify method for copying special files from repo to site (#4601)
+ * Refresh the contributing file (#4596)
+ * change smartify doc from copy/paste of mardownify doc (#4653)
+
+### Site Enhancements
+
+ * Add jekyll-seo-tag, jekyll-avatar, and jekyll-sitemap to the site (#4553)
+ * Add Google search query to /docs/help/ (#4589)
+ * Upgrading, documentation (#4597)
+ * Add 'view source' entry (#4602)
+ * Add jekyll-video-embed to list of third-party plugins. (#4621)
+ * Adding Aerobatic to list of deployment options (#4630)
+ * Update documentation: HTMLProofer CLI command (#4641)
+ * Document that subdirectories of `_posts` are no longer categories (#4639)
+ * Update continuous-integration docs with sudo: false information (#4628)
+ * Blog post on refreshed contributing file and new affinity teams (#4645)
+ * Fixes typo on collections (#4647)
+ * Documentation: future option also works for collections (#4682)
+ * Additional package needed for Fedora 23 Workspace (#4685)
+ * Fix typo on Chocolatey name in Windows documentation (#4686)
+ * Use the correct URL, Fixes #4698 (#4699)
+ * Add jekyll-paspagon plugin (#4700)
+
+## 3.1.2 / 2016-02-19
+
+### Minor Enhancements
+
+ * Include `.rubocop.yml` in Gem (#4437)
+ * `LiquidRenderer#parse`: parse with line numbers. (#4452)
+ * Add consistency to the no-subcommand deprecation message (#4505)
+
+### Bug Fixes
+
+ * Fix syntax highlighting in kramdown by making `@config` accessible in the Markdown converter. (#4428)
+ * `Jekyll.sanitized_path`: sanitizing a questionable path should handle tildes (#4492)
+ * Fix `titleize` so already capitalized words are not dropped (#4525)
+ * Permalinks which end in a slash should always output HTML (#4546)
+
+### Development Fixes
+
+ * Require at least cucumber version 2.1.0 (#4514)
+
+### Site Enhancements
+
+ * Add jekyll-toc plugin (#4429)
+ * Docs: Quickstart - added documentation about the `--force` option (#4410)
+ * Fix broken links to the Code of Conduct (#4436)
+ * Upgrade notes: mention trailing slash in permalink; fixes #4440 (#4455)
+ * Add hooks to the plugin categories toc (#4463)
+ * [add note] Jekyll 3 requires newer version of Ruby. (#4461)
+ * Fix typo in upgrading docs (#4473)
+ * Add note about upgrading documentation on jekyllrb.com/help/ (#4484)
+ * Update Rake link (#4496)
+ * Update & prune the short list of example sites (#4374)
+ * Added amp-jekyll plugin to plugins docs (#4517)
+ * A few grammar fixes (#4512)
+ * Correct a couple mistakes in structure.md (#4522)
+
+## 3.1.1 / 2016-01-29
+
+### Meta
+
+ * Update the Code of Conduct to the latest version (#4402)
+
+### Bug Fixes
+
+ * `Page#dir`: ensure it ends in a slash (#4403)
+ * Add `Utils.merged_file_read_opts` to unify reading & strip the BOM (#4404)
+ * `Renderer#output_ext`: honor folders when looking for ext (#4401)
+
+### Development Fixes
+
+ * Suppress stdout in liquid profiling test (#4409)
+
+## 3.1.0 / 2016-01-23
+
+### Minor Enhancements
+
+ * Use `Liquid::Drop`s instead of `Hash`es in `#to_liquid` (#4277)
+ * Add 'sample' Liquid filter Equivalent to Array#sample functionality (#4223)
+ * Cache parsed include file to save liquid parsing time. (#4120)
+ * Slightly speed up url sanitization and handle multiples of ///. (#4168)
+ * Print debug message when a document is skipped from reading (#4180)
+ * Include tag should accept multiple variables in the include name (#4183)
+ * Add `-o` option to serve command which opens server URL (#4144)
+ * Add CodeClimate platform for better code quality. (#4220)
+ * General improvements for WEBrick via jekyll serve such as SSL & custom headers (#4224, #4228)
+ * Add a default charset to content-type on webrick. (#4231)
+ * Switch `PluginManager` to use `require_with_graceful_fail` for better UX (#4233)
+ * Allow quoted date in front matter defaults (#4184)
+ * Add a Jekyll doctor warning for URLs that only differ by case (#3171)
+ * drops: create one base Drop class which can be set as mutable or not (#4285)
+ * drops: provide `#to_h` to allow for hash introspection (#4281)
+ * Shim subcommands with indication of gem possibly required so users know how to use them (#4254)
+ * Add smartify Liquid filter for SmartyPants (#4323)
+ * Raise error on empty permalink (#4361)
+ * Refactor Page#permalink method (#4389)
+
+### Bug Fixes
+
+ * Pass build options into `clean` command (#4177)
+ * Allow users to use .htm and .xhtml (XHTML5.) (#4160)
+ * Prevent Shell Injection. (#4200)
+ * Convertible should make layout data accessible via `layout` instead of `page` (#4205)
+ * Avoid using `Dir.glob` with absolute path to allow special characters in the path (#4150)
+ * Handle empty config files (#4052)
+ * Rename `@options` so that it does not impact Liquid. (#4173)
+ * utils/drops: update Drop to support `Utils.deep_merge_hashes` (#4289)
+ * Make sure jekyll/drops/drop is loaded first. (#4292)
+ * Convertible/Page/Renderer: use payload hash accessor & setter syntax for backwards-compatibility (#4311)
+ * Drop: fix hash setter precendence (#4312)
+ * utils: `has_yaml_header?` should accept files with extraneous spaces (#4290)
+ * Escape html from site.title and page.title in site template (#4307)
+ * Allow custom file extensions if defined in `permalink` YAML front matter (#4314)
+ * Fix deep_merge_hashes! handling of drops and hashes (#4359)
+ * Page should respect output extension of its permalink (#4373)
+ * Disable auto-regeneration when running server detached (#4376)
+ * Drop#[]: only use public_send for keys in the content_methods array (#4388)
+ * Extract title from filename successfully when no date. (#4195)
+
+### Development Fixes
+
+ * `jekyll-docs` should be easily release-able (#4152)
+ * Allow use of Cucumber 2.1 or greater (#4181)
+ * Modernize Kramdown for Markdown converter. (#4109)
+ * Change TestDoctorCommand to JekyllUnitTest... (#4263)
+ * Create namespaced rake tasks in separate `.rake` files under `lib/tasks` (#4282)
+ * markdown: refactor for greater readability & efficiency (#3771)
+ * Fix many Rubocop style errors (#4301)
+ * Fix spelling of "GitHub" in docs and history (#4322)
+ * Reorganize and cleanup the Gemfile, shorten required depends. (#4318)
+ * Remove script/rebund. (#4341)
+ * Implement codeclimate platform (#4340)
+ * Remove ObectSpace dumping and start using inherited, it's faster. (#4342)
+ * Add script/travis so all people can play with Travis-CI images. (#4338)
+ * Move Cucumber to using RSpec-Expections and furthering JRuby support. (#4343)
+ * Rearrange Cucumber and add some flair. (#4347)
+ * Remove old FIXME (#4349)
+ * Clean up the Gemfile (and keep all the necessary dependencies) (#4350)
+
+### Site Enhancements
+
+ * Add three plugins to directory (#4163)
+ * Add upgrading docs from 2.x to 3.x (#4157)
+ * Add `protect_email` to the plugins index. (#4169)
+ * Add `jekyll-deploy` to list of third-party plugins (#4179)
+ * Clarify plugin docs (#4154)
+ * Add Kickster to deployment methods in documentation (#4190)
+ * Add DavidBurela's tutorial for Windows to Windows docs page (#4210)
+ * Change GitHub code block to highlight tag to avoid it overlaps parent div (#4121)
+ * Update FormKeep link to be something more specific to Jekyll (#4243)
+ * Remove example Roger Chapman site, as the domain doesn't exist (#4249)
+ * Added configuration options for `draft_posts` to configuration docs (#4251)
+ * Fix checklist in `_assets.md` (#4259)
+ * Add Markdown examples to Pages docs (#4275)
+ * Add jekyll-paginate-category to list of third-party plugins (#4273)
+ * Add `jekyll-responsive_image` to list of third-party plugins (#4286)
+ * Add `jekyll-commonmark` to list of third-party plugins (#4299)
+ * Add documentation for incremental regeneration (#4293)
+ * Add note about removal of relative permalink support in upgrading docs (#4303)
+ * Add Pro Tip to use front matter variable to create clean URLs (#4296)
+ * Fix grammar in the documentation for posts. (#4330)
+ * Add documentation for smartify Liquid filter (#4333)
+ * Fixed broken link to blog on using mathjax with jekyll (#4344)
+ * Documentation: correct reference in Precedence section of Configuration docs (#4355)
+ * Add @jmcglone's guide to github-pages doc page (#4364)
+ * Added the Wordpress2Jekyll Wordpress plugin (#4377)
+ * Add Contentful Extension to list of third-party plugins (#4390)
+ * Correct Minor spelling error (#4394)
+
+## 3.0.3 / 2016-02-08
+
+### Bug Fixes
+
+ * Fix extension weirdness with folders (#4493)
+ * EntryFilter: only include 'excluded' log on excluded files (#4479)
+ * `Jekyll.sanitized_path`: escape tildes before sanitizing a questionable path (#4468)
+ * `LiquidRenderer#parse`: parse with line numbers (#4453)
+ * `Document#<=>`: protect against nil comparison in dates. (#4446)
+
+## 3.0.2 / 2016-01-20
+
+### Bug Fixes
+
+ * Document: throw a useful error when an invalid date is given (#4378)
+
+## 3.0.1 / 2015-11-17
+
+### Bug Fixes
+
+ * Document: only superdirectories of the collection are categories (#4110)
+ * `Convertible#render_liquid` should use `render!` to cause failure on bad Liquid (#4077)
+ * Don't generate `.jekyll-metadata` in non-incremental build (#4079)
+ * Set `highlighter` config val to `kramdown.syntax_highlighter` (#4090)
+ * Align hooks implementation with documentation (#4104)
+ * Fix the deprecation warning in the doctor command (#4114)
+ * Fix case in `:title` and add `:slug` which is downcased (#4100)
+
+### Development Fixes
+
+ * Fix test warnings when doing rake {test,spec} or script/test (#4078)
+
+### Site Enhancements
+
+ * Update normalize.css to v3.0.3. (#4085)
+ * Update Font Awesome to v4.4.0. (#4086)
+ * Adds a note about installing the jekyll-gist gem to make gist tag work (#4101)
+ * Align hooks documentation with implementation (#4104)
+ * Add Jekyll Flickr Plugin to the list of third party plugins (#4111)
+ * Remove link to now-deleted blog post (#4125)
+ * Update the liquid syntax in the pagination docs (#4130)
+ * Add jekyll-language-plugin to plugins.md (#4134)
+ * Updated to reflect feedback in #4129 (#4137)
+ * Clarify assets.md based on feedback of #4129 (#4142)
+ * Re-correct the liquid syntax in the pagination docs (#4140)
+
+## 3.0.0 / 2015-10-26
+
### Major Enhancements
* Liquid profiler (i.e. know how fast or slow your templates render) (#3762)
* Incremental regeneration (#3116)
* Add Hooks: a new kind of plugin (#3553)
* Upgrade to Liquid 3.0.0 (#3002)
+ * `site.posts` is now a Collection instead of an Array (#4055)
* Add basic support for JRuby (commit: 0f4477)
* Drop support for Ruby 1.9.3. (#3235)
* Support Ruby v2.2 (#3234)
@@ -19,9 +266,13 @@
* Remove support for relative permalinks (#3679)
* Iterate over `site.collections` as an array instead of a hash. (#3670)
* Adapt StaticFile for collections, config defaults (#3823)
+ * Add a Code of Conduct for the Jekyll project (#3925)
+ * Added permalink time variables (#3990)
+ * Add `--incremental` flag to enable incremental regen (disabled by default) (#4059)
### Minor Enhancements
+ * Deprecate access to Document#data properties and Collection#docs methods (#4058)
* Sort static files just once, and call `site_payload` once for all collections (#3204)
* Separate `jekyll docs` and optimize external gem handling (#3241)
* Improve `Site#getConverterImpl` and call it `Site#find_converter_instance` (#3240)
@@ -38,8 +289,7 @@
* Perf: `Markdown#matches` should avoid regexp (#3321)
* Perf: Use frozen regular expressions for `Utils#slugify` (#3321)
* Split off Textile support into jekyll-textile-converter (#3319)
- * Improve the navigation menu alignment in the site template on small
- screens (#3331)
+ * Improve the navigation menu alignment in the site template on small screens (#3331)
* Show the regeneration time after the initial generation (#3378)
* Site template: Switch default font to Helvetica Neue (#3376)
* Make the `include` tag a teensy bit faster. (#3391)
@@ -57,7 +307,6 @@
* Added build --destination and --source flags (#3418)
* Site template: remove unused `page.meta` attribute (#3537)
* Improve the error message when sorting null objects (#3520)
- * Add jekyll-smartify plugin (#3572)
* Added liquid-md5 plugin (#3598)
* Documentation: RR replaced with RSpec Mocks (#3600)
* Documentation: Fix subpath. (#3599)
@@ -72,8 +321,7 @@
* Set log level to debug when verbose flag is set (#3665)
* Added a mention on the Gemfile to complete the instructions (#3671)
* Perf: Cache `Document#to_liquid` and invalidate where necessary (#3693)
- * Perf: `Jekyll::Cleaner#existing_files`: Call `keep_file_regex` and
- `keep_dirs` only once, not once per iteration (#3696)
+ * Perf: `Jekyll::Cleaner#existing_files`: Call `keep_file_regex` and `keep_dirs` only once, not once per iteration (#3696)
* Omit jekyll/jekyll-help from list of resources. (#3698)
* Add basic `jekyll doctor` test to detect fsnotify (OSX) anomalies. (#3704)
* Added talk.jekyllrb.com to "Have questions?" (#3694)
@@ -82,9 +330,19 @@
* Upgrade highlight wrapper from `div` to `figure` (#3779)
* Upgrade mime-types to `~> 2.6` (#3795)
* Update windows.md with Ruby version info (#3818)
+ * Make the directory for includes configurable (#3782)
+ * Rename directory configurations to match `*_dir` convention for consistency (#3782)
+ * Internal: trigger hooks by owner symbol (#3871)
+ * Update MIME types from mime-db (#3933)
+ * Add header to site template `_config.yml` for clarity & direction (#3997)
+ * Site template: add timezone offset to post date frontmatter (#4001)
+ * Make a constant for the regex to find hidden files (#4032)
+ * Site template: refactor github & twitter icons into includes (#4049)
+ * Site template: add background to Kramdown Rouge-ified backtick code blocks (#4053)
### Bug Fixes
+ * `post_url`: fix access deprecation warning & fix deprecation msg (#4060)
* Perform jekyll-paginate deprecation warning correctly. (#3580)
* Make permalink parsing consistent with pages (#3014)
* `time()`pre-filter method should accept a `Date` object (#3299)
@@ -120,6 +378,21 @@
* Fix it so that 'blog.html' matches 'blog.html' (#3732)
* Remove occasionally-problematic `ensure` in `LiquidRenderer` (#3811)
* Fixed an unclear code comment in site template SCSS (#3837)
+ * Fix reading of binary metadata file (#3845)
+ * Remove var collision with site template header menu iteration variable (#3838)
+ * Change non-existent `hl_linenos` to `hl_lines` to allow passthrough in safe mode (#3787)
+ * Add missing flag to disable the watcher (#3820)
+ * Update CI guide to include more direct explanations of the flow (#3891)
+ * Set `future` to `false` in the default config (#3892)
+ * filters: `where` should compare stringified versions of input & comparator (#3935)
+ * Read build options for `jekyll clean` command (#3828)
+ * Fix #3970: Use Gem::Version to compare versions, not `>`.
+ * Abort if no subcommand. Fixes confusing message. (#3992)
+ * Whole-post excerpts should match the post content (#4004)
+ * Change default font weight to 400 to fix bold/strong text issues (#4050)
+ * Document: Only auto-generate the excerpt if it's not overridden (#4062)
+ * Utils: `deep_merge_hashes` should also merge `default_proc` (45f69bb)
+ * Defaults: compare paths in `applies_path?` as `String`s to avoid confusion (7b81f00)
### Development Fixes
@@ -151,6 +424,14 @@
* Update the way cucumber accesses Minitest assertions (#3678)
* Add `script/rubyprof` to generate cachegrind callgraphs (#3692)
* Upgrade cucumber to 2.x (#3795)
+ * Update Kramdown. (#3853)
+ * Updated the scripts shebang for portability (#3858)
+ * Update JRuby testing to 9K ([3ab386f](https://github.com/jekyll/jekyll/commit/3ab386f1b096be25a24fe038fc70fd0fb08d545d))
+ * Organize dependencies into dev and test groups. (#3852)
+ * Contributing.md should refer to `script/cucumber` (#3894)
+ * Update contributing documentation to reflect workflow updates (#3895)
+ * Add script to vendor mime types (#3933)
+ * Ignore .bundle dir in SimpleCov (#4033)
### Site Enhancements
@@ -217,6 +498,29 @@
* Update link for navbars with data attributes tutorial (#3728)
* Add `jekyll-asciinema` to list of third-party plugins (#3750)
* Update pagination example to be agnostic to first pagination dir (#3763)
+ * Detailed instructions for rsync deployment method (#3848)
+ * Add Jekyll Portfolio Generator to list of plugins (#3883)
+ * Add `site.html_files` to variables docs (#3880)
+ * Add Static Publisher tool to list of deployment methods (#3865)
+ * Fix a few typos. (#3897)
+ * Add `jekyll-youtube` to the list of third-party plugins (#3931)
+ * Add Views Router plugin (#3950)
+ * Update install docs (Core dependencies, Windows reqs, etc) (#3769)
+ * Use Jekyll Feed for jekyllrb.com (#3736)
+ * Add jekyll-umlauts to plugins.md ($3966)
+ * Troubleshooting: fix broken link, add other mac-specific info (#3968)
+ * Add a new site for learning purposes (#3917)
+ * Added documentation for Jekyll environment variables (#3989)
+ * Fix broken configuration documentation page (#3994)
+ * Add troubleshooting docs for installing on El Capitan (#3999)
+ * Add Lazy Tweet Embedding to the list of third-party plugins (#4015)
+ * Add installation instructions for 2 of 3 options for plugins (#4013)
+ * Add alternative jekyll gem installation instructions (#4018)
+ * Fix a few typos and formatting problems. (#4022)
+ * Fix pretty permalink example (#4029)
+ * Note that `_config.yml` is not reloaded during regeneration (#4034)
+ * Apply code block figure syntax to blocks in CONTRIBUTING (#4046)
+ * Add jekyll-smartify to the list of third-party plugins (#3572)
## 2.5.3 / 2014-12-22
@@ -299,16 +603,14 @@
* Strip newlines in site template `` description. (#2982)
* Add link to atom feed in `head` of site template files (#2996)
* Performance optimizations (#2994)
- * Use `Hash#each_key` instead of `Hash#keys.each` to speed up iteration
- over hash keys. (#3017)
+ * Use `Hash#each_key` instead of `Hash#keys.each` to speed up iteration over hash keys. (#3017)
* Further minor performance enhancements. (#3022)
* Add 'b' and 's' aliases for build and serve, respectively (#3065)
### Bug Fixes
* Fix Rouge's RedCarpet plugin interface integration (#2951)
- * Remove `--watch` from the site template blog post since it defaults
- to watching in in 2.4.0 (#2922)
+ * Remove `--watch` from the site template blog post since it defaults to watching in in 2.4.0 (#2922)
* Fix code for media query mixin in site template (#2946)
* Allow post URL's to have `.htm` extensions (#2925)
* `Utils.slugify`: Don't create new objects when gsubbing (#2997)
@@ -336,7 +638,7 @@
* Add Big Footnotes for Kramdown plugin to list of third-party plugins (#2916)
* Remove warning regarding GHP use of singular types for front matter defaults (#2919)
* Fix quote character typo in site documentation for templates (#2917)
- * Point Liquid links to Liquid’s Github wiki (#2887)
+ * Point Liquid links to Liquid’s GitHub wiki (#2887)
* Add HTTP Basic Auth (.htaccess) plugin to list of third-party plugins (#2931)
* (Minor) Grammar & `_config.yml` filename fixes (#2911)
* Added `mathml.rb` to the list of third-party plugins. (#2937)
@@ -386,11 +688,9 @@
* Document the `name` variable for collection permalinks (#2829)
* Adds info about installing jekyll in current dir (#2839)
- * Remove deprecated `jekyll-projectlist` plugin from list of third-party
- plugins (#2742)
+ * Remove deprecated `jekyll-projectlist` plugin from list of third-party plugins (#2742)
* Remove tag plugins that are built in to Jekyll (#2751)
- * Add `markdown-writer` package for Atom Editor to list of third-party
- plugins (#2763)
+ * Add `markdown-writer` package for Atom Editor to list of third-party plugins (#2763)
* Fix typo in site documentation for collections (#2764)
* Fix minor typo on plugins docs page (#2765)
* Replace markdown with HTML in `sass_dir` note on assets page (#2791)
@@ -478,8 +778,7 @@
### Site Enhancements
* Update Kramdown urls (#2588)
- * Add `Jekyll::AutolinkEmail` and `Jekyll::GitMetadata` to the list of
- third-party plugins (#2596)
+ * Add `Jekyll::AutolinkEmail` and `Jekyll::GitMetadata` to the list of third-party plugins (#2596)
* Fix a bunch of broken links in the site (#2601)
* Replace dead links with working links (#2611)
* Add jekyll-hook to deployment methods (#2617)
@@ -516,12 +815,10 @@
* Allow subdirectories in `_data` (#2395)
* Extract Pagination Generator into gem: `jekyll-paginate` (#2455)
* Utilize `date_to_rfc822` filter in site template (#2437)
- * Add categories, last build datetime, and generator to site template
- feed (#2438)
+ * Add categories, last build datetime, and generator to site template feed (#2438)
* Configurable, replaceable Logger-compliant logger (#2444)
* Extract `gist` tag into a separate gem (#2469)
- * Add `collection` attribute to `Document#to_liquid` to access the
- document's collection label. (#2436)
+ * Add `collection` attribute to `Document#to_liquid` to access the document's collection label. (#2436)
* Upgrade listen to `2.7.6 <= x < 3.0.0` (#2492)
* Allow configuration of different Twitter and GitHub usernames in site template (#2485)
* Bump Pygments to v0.6.0 (#2504)
@@ -546,8 +843,7 @@
* Allow front matter defaults to set post categories (#2373)
* Fix command in subcommand deprecation warning (#2457)
* Keep all parent directories of files/dirs in `keep_files` (#2458)
- * When using RedCarpet and Rouge without Rouge installed, fixed erroneous
- error which stated that redcarpet was missing, not rouge. (#2464)
+ * When using RedCarpet and Rouge without Rouge installed, fixed erroneous error which stated that redcarpet was missing, not rouge. (#2464)
* Ignore *all* directories and files that merit it on auto-generation (#2459)
* Before copying file, explicitly remove the old one (#2535)
* Merge file system categories with categories from YAML. (#2531)
@@ -576,8 +872,7 @@
* Prevent table from extending parent width in permalink style table (#2424)
* Add collections to info about pagination support (#2389)
* Add `jekyll_github_sample` plugin to list of third-party plugins (#2463)
- * Clarify documentation around front matter defaults and add details
- about defaults for collections. (#2439)
+ * Clarify documentation around front matter defaults and add details about defaults for collections. (#2439)
* Add Jekyll Project Version Tag to list of third-party plugins (#2468)
* Use `https` for GitHub links across whole site (#2470)
* Add StickerMule + Jekyll post (#2476)
@@ -593,13 +888,11 @@
### Bug Fixes
- * Properly prefix links in site template with URL or baseurl depending upon
- need. (#2319)
+ * Properly prefix links in site template with URL or baseurl depending upon need. (#2319)
* Update gist tag comments and error message to require username (#2326)
* Fix `permalink` setting in site template (#2331)
* Don't fail if any of the path objects are nil (#2325)
- * Instantiate all descendants for converters and generators, not just
- direct subclasses (#2334)
+ * Instantiate all descendants for converters and generators, not just direct subclasses (#2334)
* Replace all instances of `site.name` with `site.title` in site template (#2324)
* `Jekyll::Filters#time` now accepts UNIX timestamps in string or number form (#2339)
* Use `item_property` for `where` filter so it doesn't break on collections (#2359)
@@ -635,17 +928,16 @@
## 2.0.0 / 2014-05-06
### Major Enhancements
+
* Add "Collections" feature (#2199)
* Add gem-based plugin whitelist to safe mode (#1657)
- * Replace the commander command line parser with a more robust
- solution for our needs called `mercenary` (#1706)
+ * Replace the commander command line parser with a more robust solution for our needs called `mercenary` (#1706)
* Remove support for Ruby 1.8.x (#1780)
* Move to jekyll/jekyll from mojombo/jekyll (#1817)
* Allow custom markdown processors (#1872)
* Provide support for the Rouge syntax highlighter (#1859)
* Provide support for Sass (#1932)
- * Provide a 300% improvement when generating sites that use
- `Post#next` or `Post#previous` (#1983)
+ * Provide a 300% improvement when generating sites that use `Post#next` or `Post#previous` (#1983)
* Provide support for CoffeeScript (#1991)
* Replace Maruku with Kramdown as Default Markdown Processor (#1988)
* Expose `site.static_files` to Liquid (#2075)
@@ -656,10 +948,9 @@
* Exclude files based on prefix as well as `fnmatch?` (#2303)
### Minor Enhancements
- * Move the EntryFilter class into the Jekyll module to avoid polluting the
- global namespace (#1800)
- * Add `group_by` Liquid filter create lists of items grouped by a common
- property's value (#1788)
+
+ * Move the EntryFilter class into the Jekyll module to avoid polluting the global namespace (#1800)
+ * Add `group_by` Liquid filter create lists of items grouped by a common property's value (#1788)
* Add support for Maruku's `fenced_code_blocks` option (#1799)
* Update Redcarpet dependency to ~> 3.0 (#1815)
* Automatically sort all pages by name (#1848)
@@ -670,12 +961,10 @@
* Bump dependency `safe_yaml` to `~> 1.0` (#1886)
* Allow sorting of content by custom properties (#1849)
* Add `--quiet` flag to silence output during build and serve (#1898)
- * Add a `where` filter to filter arrays based on a key/value pair
- (#1875)
+ * Add a `where` filter to filter arrays based on a key/value pair (#1875)
* Route 404 errors to a custom 404 page in development (#1899)
* Excludes are now relative to the site source (#1916)
- * Bring MIME Types file for `jekyll serve` to complete parity with GH Pages
- servers (#1993)
+ * Bring MIME Types file for `jekyll serve` to complete parity with GH Pages servers (#1993)
* Adding Breakpoint to make new site template more responsive (#2038)
* Default to using the UTF-8 encoding when reading files. (#2031)
* Update Redcarpet dependency to ~> 3.1 (#2044)
@@ -693,13 +982,11 @@
* Add support for unpublished drafts (#2164)
* Add `force_polling` option to the `serve` command (#2165)
* Clean up the `` in the site template (#2186)
- * Permit YAML blocks to end with three dots to better conform with the
- YAML spec (#2110)
+ * Permit YAML blocks to end with three dots to better conform with the YAML spec (#2110)
* Use `File.exist?` instead of deprecated `File.exists?` (#2214)
* Require newline after start of YAML Front Matter header (#2211)
* Add the ability for pages to be marked as `published: false` (#1492)
- * Add `Jekyll::LiquidExtensions` with `.lookup_variable` method for easy
- looking up of variable values in a Liquid context. (#2253)
+ * Add `Jekyll::LiquidExtensions` with `.lookup_variable` method for easy looking up of variable values in a Liquid context. (#2253)
* Remove literal lang name from class (#2292)
* Return `utf-8` encoding in header for webrick error page response (#2289)
* Make template site easier to customize (#2268)
@@ -708,13 +995,12 @@
* Take into account missing values in the Liquid sort filter (#2299)
### Bug Fixes
+
* Don't allow nil entries when loading posts (#1796)
- * Remove the scrollbar that's always displayed in new sites generated
- from the site template (#1805)
+ * Remove the scrollbar that's always displayed in new sites generated from the site template (#1805)
* Add `#path` to required methods in `Jekyll::Convertible` (#1866)
* Default Maruku fenced code blocks to ON for 2.0.0-dev (#1831)
- * Change short opts for host and port for `jekyll docs` to be consistent with
- other subcommands (#1877)
+ * Change short opts for host and port for `jekyll docs` to be consistent with other subcommands (#1877)
* Fix typos (#1910)
* Lock Maruku at 0.7.0 to prevent bugs caused by Maruku 0.7.1 (#1958)
* Fixes full path leak to source directory when using include tag (#1951)
@@ -726,9 +1012,8 @@
* Patch a couple show-stopping security vulnerabilities (#1946)
* Sanitize paths uniformly, in a Windows-friendly way (#2065, #2109)
* Update gem build steps to work correctly on Windows (#2118)
- * Remove obsolete `normalize_options` method call from `bin/jekyll` (#2121).
- * Remove `+` characters from Pygments lexer names when adding as a CSS
- class (#994)
+ * Remove obsolete `normalize_options` method call from `bin/jekyll` (#2121)
+ * Remove `+` characters from Pygments lexer names when adding as a CSS class (#994)
* Remove some code that caused Ruby interpreter warnings (#2178)
* Only strip the drive name if it begins the string (#2175)
* Remove default post with invalid date from site template (#2200)
@@ -743,14 +1028,14 @@
* Add `output` to `Document` liquid output hash (#2309)
### Development Fixes
+
* Add a link to the site in the README.md file (#1795)
* Add in History and site changes from `v1-stable` branch (#1836)
* Testing additions on the Excerpt class (#1893)
* Fix the `highlight` tag feature (#1859)
* Test Jekyll under Ruby 2.1.0 (#1900)
* Add script/cibuild for fun and profit (#1912)
- * Use `Forwardable` for delegation between `Excerpt` and `Post`
- (#1927)
+ * Use `Forwardable` for delegation between `Excerpt` and `Post` (#1927)
* Rename `read_things` to `read_content` (#1928)
* Add `script/branding` script for ASCII art lovin' (#1936)
* Update the README to reflect the repo move (#1943)
@@ -778,11 +1063,11 @@
* Workaround for Travis bug (#2290)
### Site Enhancements
+
* Document Kramdown's GFM parser option (#1791)
* Move CSS to includes & update normalize.css to v2.1.3 (#1787)
* Minify CSS only in production (#1803)
- * Fix broken link to installation of Ruby on Mountain Lion blog post on
- Troubleshooting docs page (#1797)
+ * Fix broken link to installation of Ruby on Mountain Lion blog post on Troubleshooting docs page (#1797)
* Fix issues with 1.4.1 release blog post (#1804)
* Add note about deploying to OpenShift (#1812)
* Collect all Windows-related docs onto one page (#1818)
@@ -797,8 +1082,7 @@
* Add jekyll-compass to the plugin list (#1923)
* Add note in Posts docs about stripping `
` tags from excerpt (#1933)
* Add additional info about the new exclude behavior (#1938)
- * Linkify 'awesome contributors' to point to the contributors graph on
- GitHub (#1940)
+ * Linkify 'awesome contributors' to point to the contributors graph on GitHub (#1940)
* Update `docs/sites.md` link to GitHub Training materials (#1949)
* Update `master` with the release info from 1.4.3 (#1947)
* Define docs nav in datafile (#1953)
@@ -815,8 +1099,7 @@
* Update link to rack-jekyll on "Deployment Methods" page (#2047)
* Fix typo in /docs/configuration (#2073)
* Fix count in docs for `site.static_files` (#2077)
- * Update configuration docs to indicate utf-8 is the default for 2.0.0
- and ASCII for 1.9.3 (#2074)
+ * Update configuration docs to indicate utf-8 is the default for 2.0.0 and ASCII for 1.9.3 (#2074)
* Add info about unreleased feature to the site (#2061)
* Add whitespace to liquid example in GitHub Pages docs (#2084)
* Clarify the way Sass and CoffeeScript files are read in and output (#2067)
@@ -833,8 +1116,7 @@
* Some HTML tidying (#2130)
* Remove modernizr and use html5shiv.js directly for IE less than v9 (#2131)
* Remove unused images (#2187)
- * Use `array_to_sentence_string` filter when outputting news item
- categories (#2191)
+ * Use `array_to_sentence_string` filter when outputting news item categories (#2191)
* Add link to Help repo in primary navigation bar (#2177)
* Switch to using an ico file for the shortcut icon (#2193)
* Use numbers to specify font weights and only bring in font weights used (#2185)
@@ -884,64 +1166,72 @@
## 1.4.3 / 2014-01-13
### Bug Fixes
+
* Patch show-stopping security vulnerabilities (#1944)
## 1.4.2 / 2013-12-16
### Bug Fixes
+
* Turn on Maruku fenced code blocks by default (#1830)
## 1.4.1 / 2013-12-09
### Bug Fixes
+
* Don't allow nil entries when loading posts (#1796)
## 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)
+ * 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)
+ * 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)
+ * 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)
@@ -953,44 +1243,40 @@
## 1.3.0 / 2013-11-04
### Major Enhancements
- * Add support for adding data as YAML files under a site's `_data`
- directory (#1003)
+
+ * 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)
+ * 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)
+ * 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 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)
+ * 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)
+ * 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)
@@ -1007,6 +1293,7 @@
* 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)
@@ -1014,8 +1301,7 @@
* 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)
+ * 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)
@@ -1027,21 +1313,25 @@
## 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.
@@ -1051,42 +1341,38 @@
## 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)
+ * 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)
+ * 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)
+ * 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)
+ * 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)
+ * 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)
+ * 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)
+
+ * 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)
@@ -1096,6 +1382,7 @@
* 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)
@@ -1120,59 +1407,59 @@
## 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 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)
+ * 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)
+
+ * 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)
+ * 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)
+ * 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)
@@ -1180,22 +1467,20 @@
* 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)
+ * 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)
+ * 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)
+ * 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)
@@ -1209,17 +1494,16 @@
* 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 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)
+ * 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)
@@ -1228,16 +1512,16 @@
* 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)
+ * 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)
+ * 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)
@@ -1251,12 +1535,12 @@
* 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)
+ * 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)
@@ -1265,20 +1549,24 @@
## 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=""` 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)
@@ -1287,29 +1575,34 @@
## 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 `
` 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)
@@ -1317,6 +1610,7 @@
* 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)
@@ -1356,8 +1650,7 @@
* 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)
+ * 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)
@@ -1383,14 +1676,14 @@
* 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)
+ * 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)
@@ -1401,20 +1694,20 @@
* 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)
+ * 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)
+ * 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)
@@ -1424,6 +1717,7 @@
## 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)
@@ -1443,10 +1737,12 @@
* 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
@@ -1454,12 +1750,14 @@
## 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)
@@ -1473,12 +1771,14 @@
* 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)
@@ -1488,6 +1788,7 @@
## 0.8.0 / 2010-11-22
### Minor Enhancements
+
* Add wordpress.com importer (#207)
* Add `--limit-posts` cli option (#212)
* Add `uri_escape` filter (#234)
@@ -1502,12 +1803,14 @@
## 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)
@@ -1515,24 +1818,24 @@
* 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)
+ * 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
+ * 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)
@@ -1549,87 +1852,80 @@
## 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
+ * 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 front matter (#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.
+ * 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)
+ * 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 `` 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)
+ * Added --paginate option to the executable along with a paginator object for the payload (@calavera)
+ * Upgraded RedCloth to 4.2.1, which makes `` tags work once again.
+ * Configuration options set in config.yml are now available through the site payload (@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)
+ * 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)
+ * 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 front matter (@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)
+ * 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)
+ * 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)
@@ -1649,6 +1945,7 @@
## 0.4.1
### Minor Enhancements
+
* Changed date format on wordpress converter (zeropadding) (@dysinger)
* Bug Fixes
* Add Jekyll binary as executable to gemspec (@dysinger)
@@ -1656,9 +1953,11 @@
## 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)
@@ -1677,55 +1976,62 @@
## 0.3.0 / 2008-12-24
### Major Enhancements
- * Added `--server` option to start a simple WEBrick server on destination
- directory (@johnreilly and @mchung)
+
+ * 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)
+ * 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)
@@ -1735,21 +2041,24 @@
* 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
+ * 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/LICENSE b/LICENSE
index 527166b6..94dbfc39 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2008-2015 Tom Preston-Werner
+Copyright (c) 2008-2016 Tom Preston-Werner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.markdown b/README.markdown
index 42ad29d1..d3128bcf 100644
--- a/README.markdown
+++ b/README.markdown
@@ -1,36 +1,58 @@
-# [Jekyll](http://jekyllrb.com/)
+# [Jekyll](https://jekyllrb.com/)
-[](https://rubygems.org/gems/jekyll)
-[](https://travis-ci.org/jekyll/jekyll)
-[](https://codeclimate.com/github/jekyll/jekyll)
-[](https://gemnasium.com/jekyll/jekyll)
-[](https://hakiri.io/github/jekyll/jekyll/master)
+[][ruby-gems]
+[][travis]
+[][coverage]
+[][codeclimate]
+[][gemnasium]
+[][hakiri]
-By Tom Preston-Werner, Nick Quaranto, Parker Moore, and many [awesome contributors](https://github.com/jekyll/jekyll/graphs/contributors)!
+[ruby-gems]: https://rubygems.org/gems/jekyll
+[gemnasium]: https://gemnasium.com/jekyll/jekyll
+[codeclimate]: https://codeclimate.com/github/jekyll/jekyll
+[coverage]: https://codeclimate.com/github/jekyll/jekyll/coverage
+[hakiri]: https://hakiri.io/github/jekyll/jekyll/master
+[travis]: https://travis-ci.org/jekyll/jekyll
-Jekyll is a simple, blog-aware, static site generator perfect for personal, project, or organization sites. Think of it like a file-based CMS, without all the complexity. Jekyll takes your content, renders Markdown and Liquid templates, and spits out a complete, static website ready to be served by Apache, Nginx or another web server. Jekyll is the engine behind [GitHub Pages](http://pages.github.com), which you can use to host sites right from your GitHub repositories.
+Jekyll is a simple, blog-aware, static site generator perfect for personal, project, or organization sites. Think of it like a file-based CMS, without all the complexity. Jekyll takes your content, renders Markdown and Liquid templates, and spits out a complete, static website ready to be served by Apache, Nginx or another web server. Jekyll is the engine behind [GitHub Pages](https://pages.github.com), which you can use to host sites right from your GitHub repositories.
## Philosophy
Jekyll does what you tell it to do — no more, no less. It doesn't try to outsmart users by making bold assumptions, nor does it burden them with needless complexity and configuration. Put simply, Jekyll gets out of your way and allows you to concentrate on what truly matters: your content.
+## Having trouble with OS X El Capitan?
+
+See: https://jekyllrb.com/docs/troubleshooting/#jekyll-amp-mac-os-x-1011
+
## 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/)
+* [Install](https://jekyllrb.com/docs/installation/) the gem
+* Read up about its [Usage](https://jekyllrb.com/docs/usage/) and [Configuration](https://jekyllrb.com/docs/configuration/)
* Take a gander at some existing [Sites](https://wiki.github.com/jekyll/jekyll/sites)
-* Fork and [Contribute](http://jekyllrb.com/docs/contributing/) your own modifications
+* [Fork](https://github.com/jekyll/jekyll/fork) and [Contribute](https://jekyllrb.com/docs/contributing/) your own modifications
* Have questions? Check out our official forum community [Jekyll Talk](https://talk.jekyllrb.com/) or [`#jekyll` on irc.freenode.net](https://botbot.me/freenode/jekyll/)
+## Code of Conduct
+
+In order to have a more open and welcoming community, Jekyll adheres to a
+[code of conduct](CONDUCT.markdown) adapted from the Ruby on Rails code of
+conduct.
+
+Please adhere to this code of conduct in any interactions you have in the
+Jekyll community. It is strictly enforced on all official Jekyll
+repositories, websites, and resources. If you encounter someone violating
+these terms, please let a maintainer ([@parkr](https://github.com/parkr), [@envygeeks](https://github.com/envygeeks), or [@mattr-](https://github.com/mattr-)) know
+and we will address it as soon as possible.
+
## Diving In
* [Migrate](http://import.jekyllrb.com/docs/home/) 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
+* Learn how the [YAML Front Matter](https://jekyllrb.com/docs/frontmatter/) works
+* Put information on your site with [Variables](https://jekyllrb.com/docs/variables/)
+* Customize the [Permalinks](https://jekyllrb.com/docs/permalinks/) your posts are generated with
+* Use the built-in [Liquid Extensions](https://jekyllrb.com/docs/templates/) to make your life easier
+* Use custom [Plugins](https://jekyllrb.com/docs/plugins/) to generate content specific to your site
## License
-See [LICENSE](https://github.com/jekyll/jekyll/blob/master/LICENSE).
+See the [LICENSE](https://github.com/jekyll/jekyll/blob/master/LICENSE) file.
diff --git a/Rakefile b/Rakefile
index 98610a3c..4e9a1057 100644
--- a/Rakefile
+++ b/Rakefile
@@ -7,6 +7,8 @@ require 'yaml'
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
require 'jekyll/version'
+Dir.glob('rake/**.rake').each { |f| import f }
+
#############################################################################
#
# Helper functions
@@ -14,13 +16,17 @@ require 'jekyll/version'
#############################################################################
def name
- @name ||= File.basename(Dir['*.gemspec'].first, ".*")
+ "jekyll"
end
def version
Jekyll::VERSION
end
+def docs_name
+ "#{name}-docs"
+end
+
def gemspec_file
"#{name}.gemspec"
end
@@ -81,6 +87,34 @@ def converted_history(markdown)
normalize_bullets(markdown)))))
end
+def siteify_file(file, overrides_front_matter = {})
+ abort "You seem to have misplaced your #{file} file. I can haz?" unless File.exists?(file)
+ title = begin
+ File.read(file).match(/\A# (.*)$/)[1]
+ rescue
+ File.basename(file, ".*").downcase.capitalize
+ end
+ slug = File.basename(file, ".markdown").downcase
+ front_matter = {
+ "title" => title,
+ "layout" => "docs",
+ "permalink" => "/docs/#{slug}/",
+ "note" => "This file is autogenerated. Edit /#{file} instead."
+ }.merge(overrides_front_matter)
+ contents = "#{front_matter.to_yaml}---\n\n#{content_for(file)}"
+ File.write("site/_docs/#{slug}.md", contents)
+end
+
+def content_for(file)
+ contents = File.read(file)
+ case file
+ when "History.markdown"
+ converted_history(contents)
+ else
+ contents.gsub(/\A# .*\n\n?/, "")
+ end
+end
+
#############################################################################
#
# Standard tasks
@@ -124,181 +158,3 @@ desc "Open an irb session preloaded with this library"
task :console do
sh "irb -rubygems -r ./lib/#{name}.rb"
end
-
-#############################################################################
-#
-# Site tasks - http://jekyllrb.com
-#
-#############################################################################
-
-namespace :site do
- desc "Generate and view the site locally"
- task :preview do
- require "launchy"
- require "jekyll"
-
- # 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..."
- options = {
- "source" => File.expand_path("site"),
- "destination" => File.expand_path("site/_site"),
- "watch" => true,
- "serving" => true
- }
- Jekyll::Commands::Build.process(options)
- Jekyll::Commands::Serve.process(options)
- end
-
- desc "Generate the site"
- task :generate => [:history, :version_file] do
- require "jekyll"
- Jekyll::Commands::Build.process({
- "source" => File.expand_path("site"),
- "destination" => File.expand_path("site/_site")
- })
- end
-
- desc "Update normalize.css library to the latest version and minify"
- task :update_normalize_css do
- Dir.chdir("site/_sass") do
- sh 'curl "http://necolas.github.io/normalize.css/latest/normalize.css" -o "normalize.scss"'
- sh 'sass "normalize.scss":"_normalize.scss" --style compressed'
- rm ['normalize.scss', Dir.glob('*.map')].flatten
- end
- end
-
- desc "Commit the local site to the gh-pages branch and publish to GitHub Pages"
- task :publish => [:history, :version_file] 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 "Creating gh-pages dir..."
- sh "git clone git@github.com:jekyll/jekyll gh-pages"
- end
-
- # Ensure latest gh-pages branch history.
- Dir.chdir('gh-pages') do
- sh "git checkout gh-pages"
- sh "git pull origin gh-pages"
- end
-
- # Proceed to purge all files in case we removed a file in this release.
- puts "Cleaning gh-pages directory..."
- purge_exclude = %w[
- gh-pages/.
- gh-pages/..
- gh-pages/.git
- gh-pages/.gitignore
- ]
- FileList["gh-pages/{*,.*}"].exclude(*purge_exclude).each do |path|
- sh "rm -rf #{path}"
- end
-
- # Copy site to gh-pages dir.
- puts "Building site into gh-pages branch..."
- ENV['JEKYLL_ENV'] = 'production'
- require "jekyll"
- Jekyll::Commands::Build.process({
- "source" => File.expand_path("site"),
- "destination" => File.expand_path("gh-pages"),
- "sass" => { "style" => "compressed" },
- "full_rebuild" => true
- })
-
- File.open('gh-pages/.nojekyll', 'wb') { |f| f.puts(":dog: food.") }
-
- # Commit and push.
- puts "Committing and pushing to GitHub Pages..."
- sha = `git rev-parse HEAD`.strip
- Dir.chdir('gh-pages') do
- sh "git add ."
- sh "git commit --allow-empty -m 'Updating to #{sha}.'"
- sh "git push origin gh-pages"
- end
- puts 'Done.'
- end
-
- 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/"
- }
- 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
-
- desc "Write the site latest_version.txt file"
- task :version_file do
- File.open('site/latest_version.txt', 'wb') { |f| f.puts(version) } unless version =~ /(beta|rc|alpha)/i
- end
-
- 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
-
-#############################################################################
-#
-# Packaging tasks
-#
-#############################################################################
-
-desc "Release #{name} v#{version}"
-task :release => :build do
- unless `git branch` =~ /^\* master$/
- puts "You must be on the master branch to release!"
- exit!
- end
- sh "git commit --allow-empty -m 'Release :gem: #{version}'"
- sh "git tag v#{version}"
- sh "git push origin master"
- sh "git push origin v#{version}"
- sh "gem push pkg/#{name}-#{version}.gem"
-end
-
-desc "Build #{name} v#{version} into pkg/"
-task :build do
- mkdir_p "pkg"
- sh "gem build #{gemspec_file}"
- sh "mv #{gem_file} pkg"
-end
diff --git a/benchmark/end-with-vs-regexp b/benchmark/end-with-vs-regexp
index cb849f42..76f0312b 100644
--- a/benchmark/end-with-vs-regexp
+++ b/benchmark/end-with-vs-regexp
@@ -4,10 +4,12 @@ Benchmark.ips do |x|
path_without_ending_slash = '/some/very/very/long/path/to/a/file/i/like'
x.report('no slash regexp') { path_without_ending_slash =~ /\/$/ }
x.report('no slash end_with?') { path_without_ending_slash.end_with?("/") }
+ x.report('no slash [-1, 1]') { path_without_ending_slash[-1, 1] == "/" }
end
Benchmark.ips do |x|
path_with_ending_slash = '/some/very/very/long/path/to/a/file/i/like/'
x.report('slash regexp') { path_with_ending_slash =~ /\/$/ }
x.report('slash end_with?') { path_with_ending_slash.end_with?("/") }
+ x.report('slash [-1, 1]') { path_with_ending_slash[-1, 1] == "/" }
end
diff --git a/benchmark/file-dir-ensure-trailing-slash b/benchmark/file-dir-ensure-trailing-slash
new file mode 100644
index 00000000..aecfc039
--- /dev/null
+++ b/benchmark/file-dir-ensure-trailing-slash
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+require 'benchmark/ips'
+
+# For this pull request, which changes Page#dir
+# https://github.com/jekyll/jekyll/pull/4403
+
+FORWARD_SLASH = '/'.freeze
+
+def pre_pr(url)
+ url[-1, 1] == FORWARD_SLASH ? url : File.dirname(url)
+end
+
+def pr(url)
+ if url.end_with?(FORWARD_SLASH)
+ url
+ else
+ url_dir = File.dirname(url)
+ url_dir.end_with?(FORWARD_SLASH) ? url_dir : "#{url_dir}/"
+ end
+end
+
+def envygeeks(url)
+ return url if url.end_with?(FORWARD_SLASH) || url == FORWARD_SLASH
+
+ url = File.dirname(url)
+ url == FORWARD_SLASH ? url : "#{url}/"
+end
+
+# Just a slash
+Benchmark.ips do |x|
+ path = '/'
+ x.report("pre_pr:#{path}") { pre_pr(path) }
+ x.report("pr:#{path}") { pr(path) }
+ x.report("envygeeks:#{path}") { pr(path) }
+ x.compare!
+end
+
+# No trailing slash
+Benchmark.ips do |x|
+ path = '/some/very/very/long/path/to/a/file/i/like'
+ x.report("pre_pr:#{path}") { pre_pr(path) }
+ x.report("pr:#{path}") { pr(path) }
+ x.report("envygeeks:#{path}") { pr(path) }
+ x.compare!
+end
+
+# No trailing slash
+Benchmark.ips do |x|
+ path = '/some/very/very/long/path/to/a/file/i/like/'
+ x.report("pre_pr:#{path}") { pre_pr(path) }
+ x.report("pr:#{path}") { pr(path) }
+ x.report("envygeeks:#{path}") { pr(path) }
+ x.compare!
+end
diff --git a/benchmark/regexp-vs-include.rb b/benchmark/regexp-vs-include.rb
new file mode 100644
index 00000000..b2a4eff4
--- /dev/null
+++ b/benchmark/regexp-vs-include.rb
@@ -0,0 +1,51 @@
+#!/usr/bin/env ruby
+require 'benchmark/ips'
+
+# For this pull request, which changes Page#dir
+# https://github.com/jekyll/jekyll/pull/4403
+
+CONTENT_CONTAINING = <<-HTML.freeze
+
+
+
+
+
+ Jemoji
+
+
+
+
+
+
+
+
+HTML
+
+Benchmark.ips do |x|
+ x.report("no body include?") { CONTENT_NOT_CONTAINING.include?('Use Jekyll.configuration to build a full configuration for use w/Jekyll.
\n\n
Whatever: foo.bar
\n
Signs are nice
\n
Jekyll.sanitized_path is used to make sure your path is in your source.
\n
Run your generators! default
\n
Page without title.
\n
Run your generators! default
" in "_site/index.html"
+ Then I should get a zero exit status
+ And the _site directory should exist
And the "_site/methods/configuration.html" file should not exist
Scenario: Rendered collection
- Given I have an "index.html" page that contains "Collections: {{ site.collections }}"
+ Given I have an "index.html" page that contains "Collections: output => {{ site.collections[0].output }} label => {{ site.collections[0].label }}"
And I have an "collection_metadata.html" page that contains "Methods metadata: {{ site.collections[0].foo }} {{ site.collections[0] }}"
And I have fixture collections
And I have a "_config.yml" file with content:
@@ -24,9 +24,10 @@ Feature: Collections
foo: bar
"""
When I run jekyll build
- Then the _site directory should exist
- And I should see "Collections: {\"output\"=>true" in "_site/index.html"
- And I should see "\"label\"=>\"methods\"," in "_site/index.html"
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Collections: output => true" in "_site/index.html"
+ And I should see "label => methods" in "_site/index.html"
And I should see "Methods metadata: bar" in "_site/collection_metadata.html"
And I should see "
Whatever: foo.bar
" in "_site/methods/configuration.html"
@@ -41,11 +42,12 @@ Feature: Collections
permalink: /:collection/:path/
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "
Whatever: foo.bar
" in "_site/methods/configuration/index.html"
Scenario: Rendered document in a layout
- Given I have an "index.html" page that contains "Collections: {{ site.collections }}"
+ Given I have an "index.html" page that contains "Collections: output => {{ site.collections[0].output }} label => {{ site.collections[0].label }} foo => {{ site.collections[0].foo }}"
And I have a default layout that contains "
Tom Preston-Werner
{{content}}"
And I have fixture collections
And I have a "_config.yml" file with content:
@@ -56,9 +58,11 @@ Feature: Collections
foo: bar
"""
When I run jekyll build
- Then the _site directory should exist
- And I should see "Collections: {\"output\"=>true" in "_site/index.html"
- And I should see "\"label\"=>\"methods\"," in "_site/index.html"
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Collections: output => true" in "_site/index.html"
+ And I should see "label => methods" in "_site/index.html"
+ And I should see "foo => bar" in "_site/index.html"
And I should see "
Run your generators! default
" in "_site/methods/site/generate.html"
And I should see "
Tom Preston-Werner
" in "_site/methods/site/generate.html"
@@ -71,8 +75,9 @@ Feature: Collections
- methods
"""
When I run jekyll build
+ Then I should get a zero exit status
Then the _site directory should exist
- And I should see "Collections: _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
+ And I should see "Collections: _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
Scenario: Collections specified as an hash
Given I have an "index.html" page that contains "Collections: {% for method in site.methods %}{{ method.relative_path }} {% endfor %}"
@@ -83,8 +88,9 @@ Feature: Collections
- methods
"""
When I run jekyll build
+ Then I should get a zero exit status
Then the _site directory should exist
- And I should see "Collections: _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
+ And I should see "Collections: _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
Scenario: All the documents
Given I have an "index.html" page that contains "All documents: {% for doc in site.documents %}{{ doc.relative_path }} {% endfor %}"
@@ -95,11 +101,12 @@ Feature: Collections
- methods
"""
When I run jekyll build
+ Then I should get a zero exit status
Then the _site directory should exist
- And I should see "All documents: _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
+ And I should see "All documents: _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
Scenario: Documents have an output attribute, which is the converted HTML
- Given I have an "index.html" page that contains "First document's output: {{ site.documents.first.output }}"
+ Given I have an "index.html" page that contains "Second document's output: {{ site.documents[1].output }}"
And I have fixture collections
And I have a "_config.yml" file with content:
"""
@@ -107,8 +114,9 @@ Feature: Collections
- methods
"""
When I run jekyll build
+ Then I should get a zero exit status
Then the _site directory should exist
- And I should see "First document's output:
Use Jekyll.configuration to build a full configuration for use w/Jekyll.
\n\n
Whatever: foo.bar
" in "_site/index.html"
+ And I should see "Second document's output:
Use Jekyll.configuration to build a full configuration for use w/Jekyll.
\n\n
Whatever: foo.bar
" in "_site/index.html"
Scenario: Filter documents by where
Given I have an "index.html" page that contains "{% assign items = site.methods | where: 'whatever','foo.bar' %}Item count: {{ items.size }}"
@@ -119,11 +127,12 @@ Feature: Collections
- methods
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Item count: 2" in "_site/index.html"
Scenario: Sort by title
- Given I have an "index.html" page that contains "{% assign items = site.methods | sort: 'title' %}1. of {{ items.size }}: {{ items.first.output }}"
+ Given I have an "index.html" page that contains "{% assign items = site.methods | sort: 'title' %}2. of {{ items.size }}: {{ items[1].output }}"
And I have fixture collections
And I have a "_config.yml" file with content:
"""
@@ -131,11 +140,12 @@ Feature: Collections
- methods
"""
When I run jekyll build
- Then the _site directory should exist
- And I should see "1. of 7:
Page without title.
" in "_site/index.html"
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "2. of 8:
Page without title.
" in "_site/index.html"
Scenario: Sort by relative_path
- Given I have an "index.html" page that contains "Collections: {% assign methods = site.methods | sort: 'relative_path' %}{% for method in methods %}{{ method.title }}, {% endfor %}"
+ Given I have an "index.html" page that contains "Collections: {% assign methods = site.methods | sort: 'relative_path' %}{{ methods | map:"title" | join: ", " }}"
And I have fixture collections
And I have a "_config.yml" file with content:
"""
@@ -143,5 +153,22 @@ Feature: Collections
- methods
"""
When I run jekyll build
+ Then I should get a zero exit status
Then the _site directory should exist
- And I should see "Collections: Jekyll.configuration, Jekyll.escape, Jekyll.sanitized_path, Site#generate, , Site#generate," in "_site/index.html"
+ And I should see "Collections: Collection#entries, Jekyll.configuration, Jekyll.escape, Jekyll.sanitized_path, Site#generate, Initialize, Site#generate," in "_site/index.html"
+
+ Scenario: Rendered collection with date/dateless filename
+ Given I have an "index.html" page that contains "Collections: {% for method in site.thanksgiving %}{{ method.title }} {% endfor %}"
+ And I have fixture collections
+ And I have a "_config.yml" file with content:
+ """
+ collections:
+ thanksgiving:
+ output: true
+ """
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Thanksgiving Black Friday" in "_site/index.html"
+ And I should see "Happy Thanksgiving" in "_site/thanksgiving/2015-11-26-thanksgiving.html"
+ And I should see "Black Friday" in "_site/thanksgiving/black-friday.html"
diff --git a/features/create_sites.feature b/features/create_sites.feature
index 18996bfe..c1f75931 100644
--- a/features/create_sites.feature
+++ b/features/create_sites.feature
@@ -13,7 +13,8 @@ Feature: Create sites
Scenario: Basic site
Given I have an "index.html" file that contains "Basic Site"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Basic Site" in "_site/index.html"
Scenario: Basic site with a post
@@ -22,7 +23,8 @@ Feature: Create sites
| title | date | content |
| Hackers | 2009-03-27 | My First Exploit |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "My First Exploit" in "_site/2009/03/27/hackers.html"
Scenario: Basic site with layout and a page
@@ -30,7 +32,8 @@ Feature: Create sites
And I have an "index.html" page with layout "default" that contains "Basic Site with Layout"
And I have a default layout that contains "Page Layout: {{ content }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Page Layout: Basic Site with Layout" in "_site/index.html"
Scenario: Basic site with layout and a post
@@ -41,7 +44,8 @@ Feature: Create sites
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post Layout:
The only winning move is not to play.
" in "_site/2009/03/27/wargames.html"
Scenario: Basic site with layout inside a subfolder and a post
@@ -52,7 +56,8 @@ Feature: Create sites
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post Layout:
The only winning move is not to play.
" in "_site/2009/03/27/wargames.html"
Scenario: Basic site with layouts, pages, posts and files
@@ -75,7 +80,8 @@ Feature: Create sites
| entry3 | 2009-05-27 | post | content for entry3. |
| entry4 | 2009-06-27 | post | content for entry4. |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Page : Site contains 2 pages and 4 posts" in "_site/index.html"
And I should see "No replacement \{\{ site.posts.size \}\}" in "_site/about.html"
And I should see "" in "_site/another_file"
@@ -90,7 +96,8 @@ Feature: Create sites
And I have an "index.html" page that contains "Basic Site with include tag: {% include about.textile %}"
And I have an "_includes/about.textile" file that contains "Generated by Jekyll"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
Scenario: Basic site with subdir include tag
@@ -99,7 +106,8 @@ Feature: Create sites
And I have an info directory
And I have an "info/index.html" page that contains "Basic Site with subdir include tag: {% include about.textile %}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Basic Site with subdir include tag: Generated by Jekyll" in "_site/info/index.html"
Scenario: Basic site with nested include tag
@@ -108,31 +116,35 @@ Feature: Create sites
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 run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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 %}"
+ Given I have an "index.html" page that contains "URL: {% post_url 2008-01-01-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. |
+ | entry2 | 2008-01-01 | post | content for entry2. |
When I run jekyll build
- Then the _site directory should exist
- And I should see "URL: /2020/01/31/entry2/" in "_site/index.html"
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "URL: /2008/01/01/entry2/" in "_site/index.html"
Scenario: Basic site with whitelisted dotfile
Given I have an ".htaccess" file that contains "SomeDirective"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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"
@@ -146,13 +158,48 @@ Feature: Create sites
And I have a "secret.html" page with published "false" that contains "Unpublished page"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And the "_site/index.html" file should exist
And the "_site/public.html" file should exist
But the "_site/secret.html" file should not exist
When I run jekyll build --unpublished
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And the "_site/index.html" file should exist
And the "_site/public.html" file should exist
And the "_site/secret.html" file should exist
+
+ Scenario: Basic site with page with future date
+ Given I have a _posts directory
+ And I have the following post:
+ | title | date | layout | content |
+ | entry1 | 2020-12-31 | post | content for entry1. |
+ | entry2 | 2007-12-31 | post | content for entry2. |
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "content for entry2" in "_site/2007/12/31/entry2.html"
+ And the "_site/2020/12/31/entry1.html" file should not exist
+ When I run jekyll build --future
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And the "_site/2020/12/31/entry1.html" file should exist
+
+ Scenario: Basic site with layouts, posts and related posts
+ Given I have a _layouts directory
+ And I have a page layout that contains "Page {{ page.title }}: {{ content }}"
+ And I have a post layout that contains "Post {{ page.title }}: {{ content }}Related posts: {{ site.related_posts | size }}"
+ And I have an "index.html" page with layout "page" that contains "Site contains {{ site.pages.size }} pages and {{ site.posts.size }} posts; Related posts: {{ site.related_posts | size }}"
+ And I have a _posts directory
+ And I have the following posts:
+ | title | date | layout | content |
+ | entry1 | 2009-03-27 | post | content for entry1. |
+ | entry2 | 2009-04-27 | post | content for entry2. |
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Page : Site contains 1 pages and 2 posts; Related posts: 0" in "_site/index.html"
+ And I should see "Post entry1:
content for entry1.
\nRelated posts: 1" in "_site/2009/03/27/entry1.html"
+ And I should see "Post entry2:
content for entry2.
\nRelated posts: 1" in "_site/2009/04/27/entry2.html"
diff --git a/features/drafts.feature b/features/drafts.feature
index 5d7982ec..5a7f49f3 100644
--- a/features/drafts.feature
+++ b/features/drafts.feature
@@ -10,7 +10,8 @@ Feature: Draft Posts
| title | date | layout | content |
| Recipe | 2009-03-27 | default | Not baked yet. |
When I run jekyll build --drafts
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Not baked yet." in "_site/recipe.html"
Scenario: Don't preview a draft
@@ -21,7 +22,8 @@ Feature: Draft Posts
| title | date | layout | content |
| Recipe | 2009-03-27 | default | Not baked yet. |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And the "_site/recipe.html" file should not exist
Scenario: Don't preview a draft that is not published
@@ -32,7 +34,8 @@ Feature: Draft Posts
| title | date | layout | published | content |
| Recipe | 2009-03-27 | default | false | Not baked yet. |
When I run jekyll build --drafts
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And the "_site/recipe.html" file should not exist
Scenario: Use page.path variable
@@ -42,5 +45,6 @@ Feature: Draft Posts
| title | date | layout | content |
| Recipe | 2009-03-27 | simple | Post path: {{ page.path }} |
When I run jekyll build --drafts
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post path: _drafts/recipe.markdown" in "_site/recipe.html"
diff --git a/features/embed_filters.feature b/features/embed_filters.feature
index d6f99fc7..e3802fe5 100644
--- a/features/embed_filters.feature
+++ b/features/embed_filters.feature
@@ -11,7 +11,8 @@ Feature: Embed filters
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see today's date in "_site/2009/03/27/star-wars.html"
Scenario: Escape text for XML
@@ -22,7 +23,8 @@ Feature: Embed filters
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Star & Wars" in "_site/2009/03/27/star-wars.html"
Scenario: Calculate number of words
@@ -33,7 +35,8 @@ Feature: Embed filters
| Star Wars | 2009-03-27 | default | These aren't the droids you're looking for. |
And I have a default layout that contains "{{ content | number_of_words }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "7" in "_site/2009/03/27/star-wars.html"
Scenario: Convert an array into a sentence
@@ -44,7 +47,8 @@ Feature: Embed filters
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "scifi, movies, and force" in "_site/2009/03/27/star-wars.html"
Scenario: Markdownify a given string
@@ -55,7 +59,8 @@ Feature: Embed filters
| 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_' | markdownify }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "By
Obi-wan
" in "_site/2009/03/27/star-wars.html"
Scenario: Sort by an arbitrary variable
@@ -68,38 +73,37 @@ Feature: Embed filters
| Page-2 | default | 6 | Something |
And I have a default layout that contains "{{ site.pages | sort:'value' | map:'title' | join:', ' }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see exactly "Page-2, Page-1" in "_site/page-1.html"
And I should see exactly "Page-2, Page-1" in "_site/page-2.html"
Scenario: Sort pages by the title
Given I have a _layouts directory
+ And I have the following pages:
+ | title | layout | content |
+ | Dog | default | Run |
+ | Bird | default | Fly |
And I have the following page:
- | title | layout | content |
- | Dog | default | Run |
- And I have the following page:
- | title | layout | content |
- | Bird | default | Fly |
- And I have the following page:
- | layout | content |
- | default | Jump |
+ | layout | content |
+ | default | Jump |
And I have a default layout that contains "{% assign sorted_pages = site.pages | sort: 'title' %}The rule of {{ sorted_pages.size }}: {% for p in sorted_pages %}{{ p.content | strip_html | strip_newlines }}, {% endfor %}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see exactly "The rule of 3: Jump, Fly, Run," in "_site/bird.html"
Scenario: Sort pages by the title ordering pages without title last
Given I have a _layouts directory
+ And I have the following pages:
+ | title | layout | content |
+ | Dog | default | Run |
+ | Bird | default | Fly |
And I have the following page:
- | title | layout | content |
- | Dog | default | Run |
- And I have the following page:
- | title | layout | content |
- | Bird | default | Fly |
- And I have the following page:
- | layout | content |
- | default | Jump |
+ | layout | content |
+ | default | Jump |
And I have a default layout that contains "{% assign sorted_pages = site.pages | sort: 'title', 'last' %}The rule of {{ sorted_pages.size }}: {% for p in sorted_pages %}{{ p.content | strip_html | strip_newlines }}, {% endfor %}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see exactly "The rule of 3: Fly, Run, Jump," in "_site/bird.html"
diff --git a/features/frontmatter_defaults.feature b/features/frontmatter_defaults.feature
index a9a64ae2..31aee377 100644
--- a/features/frontmatter_defaults.feature
+++ b/features/frontmatter_defaults.feature
@@ -12,7 +12,8 @@ Feature: frontmatter defaults
And I have a configuration file with "defaults" set to "[{scope: {path: ""}, values: {layout: "pretty"}}]"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "THIS IS THE LAYOUT:
just some post
" in "_site/2013/09/11/default-layout.html"
And I should see "THIS IS THE LAYOUT: just some page" in "_site/index.html"
@@ -24,7 +25,8 @@ Feature: frontmatter defaults
And I have an "index.html" page that contains "just {{page.custom}} by {{page.author}}"
And I have a configuration file with "defaults" set to "[{scope: {path: ""}, values: {custom: "some special data", author: "Ben"}}]"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "
some special data
\n
Ben
" in "_site/2013/09/11/default-data.html"
And I should see "just some special data by Ben" in "_site/index.html"
@@ -48,7 +50,8 @@ Feature: frontmatter defaults
And I have a configuration file with "defaults" set to "[{scope: {path: "special"}, values: {layout: "subfolder", description: "the special section"}}, {scope: {path: ""}, values: {layout: "root", description: "the webpage"}}]"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "root:
info on the webpage
" in "_site/2013/10/14/about.html"
And I should see "subfolder:
info on the special section
" in "_site/special/2013/10/14/about.html"
And I should see "root: Overview for the webpage" in "_site/index.html"
@@ -71,7 +74,8 @@ Feature: frontmatter defaults
And I have a configuration file with "defaults" set to "[{scope: {path: "special"}, values: {layout: "main"}}, {scope: {path: "special/_posts"}, values: {layout: "main"}}, {scope: {path: "_posts"}, values: {layout: "main"}}]"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "main:
content of site/2013/10/14/about.html
" in "_site/2013/10/14/about.html"
And I should see "main:
content of site/special/2013/10/14/about1.html
" in "_site/special/2013/10/14/about1.html"
And I should see "main:
content of site/special/2013/10/14/about2.html
" in "_site/special/2013/10/14/about2.html"
@@ -132,7 +136,8 @@ Feature: frontmatter defaults
myval: "Test"
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Value: Test" in "_site/slides/slide1.html"
Scenario: Override frontmatter defaults inside a collection
@@ -159,7 +164,8 @@ Feature: frontmatter defaults
myval: "Test"
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Value: Override" in "_site/slides/slide2.html"
Scenario: Deep merge frontmatter defaults
diff --git a/features/hooks.feature b/features/hooks.feature
index b0846bab..48b2884e 100644
--- a/features/hooks.feature
+++ b/features/hooks.feature
@@ -24,7 +24,8 @@ Feature: Hooks
end
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "mytinypage" in "_site/foo.html"
Scenario: Modify the payload before rendering the site
@@ -37,7 +38,8 @@ Feature: Hooks
end
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "myparam!" in "_site/index.html"
Scenario: Modify the site contents after reading
@@ -51,7 +53,8 @@ Feature: Hooks
end
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And the "_site/page1.html" file should not exist
And I should see "page2" in "_site/page2.html"
@@ -67,33 +70,35 @@ Feature: Hooks
"""
And I have a "page1.html" page that contains "page1"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "page1" in "_site/firstpage.html"
Scenario: Alter a page right after it is initialized
Given I have a _plugins directory
And I have a "_plugins/ext.rb" file with content:
"""
- Jekyll::Hooks.register :page, :post_init do |page|
+ Jekyll::Hooks.register :pages, :post_init do |page|
page.name = 'renamed.html'
page.process(page.name)
end
"""
And I have a "page1.html" page that contains "page1"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "page1" in "_site/renamed.html"
Scenario: Alter the payload for one page but not another
Given I have a _plugins directory
And I have a "_plugins/ext.rb" file with content:
"""
- Jekyll::Hooks.register :page, :pre_render do |page, payload|
- payload['myparam'] = 'special' if page.name == 'page1.html'
+ Jekyll::Hooks.register :pages, :pre_render do |page, payload|
+ payload['page']['myparam'] = 'special' if page.name == 'page1.html'
end
"""
- And I have a "page1.html" page that contains "{{ myparam }}"
- And I have a "page2.html" page that contains "{{ myparam }}"
+ And I have a "page1.html" page that contains "{{ page.myparam }}"
+ And I have a "page2.html" page that contains "{{ page.myparam }}"
When I run jekyll build
Then I should see "special" in "_site/page1.html"
And I should not see "special" in "_site/page2.html"
@@ -103,7 +108,7 @@ Feature: Hooks
And I have a "index.html" page that contains "WRAP ME"
And I have a "_plugins/ext.rb" file with content:
"""
- Jekyll::Hooks.register :page, :post_render do |page|
+ Jekyll::Hooks.register :pages, :post_render do |page|
page.output = "{{{{{ #{page.output.chomp} }}}}}"
end
"""
@@ -115,7 +120,7 @@ Feature: Hooks
And I have a "index.html" page that contains "HELLO FROM A PAGE"
And I have a "_plugins/ext.rb" file with content:
"""
- Jekyll::Hooks.register :page, :post_write do |page|
+ Jekyll::Hooks.register :pages, :post_write do |page|
require 'fileutils'
filename = page.destination(page.site.dest)
FileUtils.mv(filename, "#{filename}.moved")
@@ -128,18 +133,18 @@ Feature: Hooks
Given I have a _plugins directory
And I have a "_plugins/ext.rb" file with content:
"""
- # rot13 translate
- Jekyll::Hooks.register :post, :post_init do |post|
- post.content.tr!('abcdefghijklmnopqrstuvwxyz',
- 'nopqrstuvwxyzabcdefghijklm')
+ Jekyll::Hooks.register :posts, :post_init do |post|
+ post.data['harold'] = "content for entry1.".tr!('abcdefghijklmnopqrstuvwxyz',
+ 'nopqrstuvwxyzabcdefghijklm')
end
"""
And I have a _posts directory
And I have the following posts:
- | title | date | layout | content |
- | entry1 | 2015-03-14 | nil | content for entry1. |
+ | title | date | layout | content |
+ | entry1 | 2015-03-14 | nil | {{ page.harold }} |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "pbagrag sbe ragel1." in "_site/2015/03/14/entry1.html"
Scenario: Alter the payload for certain posts
@@ -148,7 +153,7 @@ Feature: Hooks
"""
# Add myvar = 'old' to posts before 2015-03-15, and myvar = 'new' for
# others
- Jekyll::Hooks.register :post, :pre_render do |post, payload|
+ Jekyll::Hooks.register :posts, :pre_render do |post, payload|
if post.date < Time.new(2015, 3, 15)
payload['myvar'] = 'old'
else
@@ -170,7 +175,7 @@ Feature: Hooks
And I have a "_plugins/ext.rb" file with content:
"""
# Replace content after rendering
- Jekyll::Hooks.register :post, :post_render do |post|
+ Jekyll::Hooks.register :posts, :post_render do |post|
post.output.gsub! /42/, 'the answer to life, the universe and everything'
end
"""
@@ -188,7 +193,7 @@ Feature: Hooks
And I have a "_plugins/ext.rb" file with content:
"""
# Log all post filesystem writes
- Jekyll::Hooks.register :post, :post_write do |post|
+ Jekyll::Hooks.register :posts, :post_write do |post|
filename = post.destination(post.site.dest)
open('_site/post-build.log', 'a') do |f|
f.puts "Wrote #{filename} at #{Time.now}"
@@ -208,7 +213,7 @@ Feature: Hooks
Given I have a _plugins directory
And I have a "_plugins/ext.rb" file with content:
"""
- Jekyll::Hooks.register [:page, :post], :post_render do |owner|
+ Jekyll::Hooks.register [:pages, :posts], :post_render do |owner|
owner.output = "{{{{{ #{owner.output.chomp} }}}}}"
end
"""
@@ -225,19 +230,19 @@ Feature: Hooks
Given I have a _plugins directory
And I have a "_plugins/ext.rb" file with content:
"""
- Jekyll::Hooks.register :page, :post_render, priority: :normal do |owner|
+ Jekyll::Hooks.register :pages, :post_render, priority: :normal do |owner|
# first normal runs second
owner.output = "1 #{owner.output.chomp}"
end
- Jekyll::Hooks.register :page, :post_render, priority: :high do |owner|
+ Jekyll::Hooks.register :pages, :post_render, priority: :high do |owner|
# high runs last
owner.output = "2 #{owner.output.chomp}"
end
- Jekyll::Hooks.register :page, :post_render do |owner|
+ Jekyll::Hooks.register :pages, :post_render do |owner|
# second normal runs third (normal is default)
owner.output = "3 #{owner.output.chomp}"
end
- Jekyll::Hooks.register :page, :post_render, priority: :low do |owner|
+ Jekyll::Hooks.register :pages, :post_render, priority: :low do |owner|
# low runs first
owner.output = "4 #{owner.output.chomp}"
end
@@ -250,7 +255,7 @@ Feature: Hooks
Given I have a _plugins directory
And I have a "_plugins/ext.rb" file with content:
"""
- Jekyll::Hooks.register :document, :pre_render do |doc, payload|
+ Jekyll::Hooks.register :documents, :pre_render do |doc, payload|
doc.data['text'] = doc.data['text'] << ' are belong to us'
end
"""
@@ -269,14 +274,15 @@ Feature: Hooks
{{ site.memes.first.text }}
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "all your base are belong to us" in "_site/index.html"
Scenario: Update a document after rendering it, but before writing it to disk
Given I have a _plugins directory
And I have a "_plugins/ext.rb" file with content:
"""
- Jekyll::Hooks.register :document, :post_render do |doc|
+ Jekyll::Hooks.register :documents, :post_render do |doc|
doc.output.gsub! /
/, '
'
end
"""
@@ -295,14 +301,15 @@ Feature: Hooks
{{ page.text }}
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "
all your base are belong to us" in "_site/memes/doc1.html"
Scenario: Perform an action after every document is written
Given I have a _plugins directory
And I have a "_plugins/ext.rb" file with content:
"""
- Jekyll::Hooks.register :document, :post_write do |doc|
+ Jekyll::Hooks.register :documents, :post_write do |doc|
open('_site/document-build.log', 'a') do |f|
f.puts "Wrote document #{doc.collection.docs.index doc} at #{Time.now}"
end
@@ -323,5 +330,6 @@ Feature: Hooks
{{ page.text }}
"""
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Wrote document 0" in "_site/document-build.log"
diff --git a/features/include_tag.feature b/features/include_tag.feature
index c7e03ded..c8ebf717 100644
--- a/features/include_tag.feature
+++ b/features/include_tag.feature
@@ -15,11 +15,12 @@ Feature: Include tags
| Ignore params if unused | 2013-03-21 | html | {% include ignore.html date="today" %} |
| List multiple parameters | 2013-03-21 | html | {% include params.html date="today" start="tomorrow" %} |
| Dont keep parameters | 2013-03-21 | html | {% include ignore.html param="test" %}\n{% include header.html %} |
- | Allow params with spaces and quotes | 2013-04-07 | html | {% include params.html cool="param with spaces" super="\"quoted\"" single='has "quotes"' escaped='\'single\' quotes' %} |
+ | Allow params with spaces and quotes | 2013-04-07 | html | {% include params.html cool="param with spaces" super="\\"quoted\\"" single='has "quotes"' escaped='\\'single\\' quotes' %} |
| Parameter syntax | 2013-04-12 | html | {% include params.html param1_or_2="value" %} |
| Pass a variable | 2013-06-22 | html | {% assign var = 'some text' %}{% include params.html local=var title=page.title %} |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "My awesome blog header: myparam" 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 "
date = today
" in "_site/2013/03/21/list-multiple-parameters.html"
@@ -44,7 +45,8 @@ Feature: Include tags
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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
@@ -53,7 +55,8 @@ Feature: Include tags
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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "one two" in "_site/index.html"
Scenario: Include a file with variables and filters
@@ -64,7 +67,8 @@ Feature: Include tags
| include_file | one |
And I have an "index.html" page that contains "{% include {{ site.include_file | append: '.html' }} %}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "one included" in "_site/index.html"
Scenario: Include a file with partial variables
@@ -75,5 +79,28 @@ Feature: Include tags
| include_file | one |
And I have an "index.html" page that contains "{% include {{ site.include_file }}.html %}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "one included" in "_site/index.html"
+
+ Scenario: Include a file and rebuild when include content is changed
+ Given I have an _includes directory
+ And I have an "_includes/one.html" file that contains "include"
+ And I have an "index.html" page that contains "{% include one.html %}"
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "include" in "_site/index.html"
+ When I wait 1 second
+ Then I have an "_includes/one.html" file that contains "include content changed"
+ When I run jekyll build
+ Then I should see "include content changed" in "_site/index.html"
+
+ Scenario: Include a file with multiple variables
+ Given I have an _includes directory
+ And I have an "_includes/header-en.html" file that contains "include"
+ And I have an "index.html" page that contains "{% assign name = 'header' %}{% assign locale = 'en' %}{% include {{name}}-{{locale}}.html %}"
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "include" in "_site/index.html"
diff --git a/features/incremental_rebuild.feature b/features/incremental_rebuild.feature
index 08739d3e..128f5800 100644
--- a/features/incremental_rebuild.feature
+++ b/features/incremental_rebuild.feature
@@ -10,51 +10,59 @@ Feature: Incremental rebuild
| title | date | layout | content |
| 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 build
- Then the _site directory should exist
+ When I run jekyll build -I
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post Layout:
The only winning move is not to play.
" in "_site/2009/03/27/wargames.html"
- When I run jekyll build
- Then the _site directory should exist
+ When I run jekyll build -I
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post Layout:
The only winning move is not to play.
" in "_site/2009/03/27/wargames.html"
Scenario: Generate a metadata file
Given I have an "index.html" file that contains "Basic Site"
- When I run jekyll build
+ When I run jekyll build -I
Then the ".jekyll-metadata" file should exist
Scenario: Rebuild when content is changed
Given I have an "index.html" file that contains "Basic Site"
- When I run jekyll build
- Then the _site directory should exist
+ When I run jekyll build -I
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Basic Site" in "_site/index.html"
When I wait 1 second
Then I have an "index.html" file that contains "Bacon Site"
- When I run jekyll build
- Then the _site directory should exist
+ When I run jekyll build -I
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Bacon Site" in "_site/index.html"
Scenario: Rebuild when layout is changed
Given I have a _layouts directory
And I have an "index.html" page with layout "default" that contains "Basic Site with Layout"
And I have a default layout that contains "Page Layout: {{ content }}"
- When I run jekyll build
- Then the _site directory should exist
+ When I run jekyll build -I
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Page Layout: Basic Site with Layout" in "_site/index.html"
When I wait 1 second
Then I have a default layout that contains "Page Layout Changed: {{ content }}"
- When I run jekyll build --full-rebuild
- Then the _site directory should exist
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Page Layout Changed: Basic Site with Layout" in "_site/index.html"
Scenario: Rebuild when an include is changed
Given I have a _includes directory
And I have an "index.html" page that contains "Basic Site with include tag: {% include about.textile %}"
And I have an "_includes/about.textile" file that contains "Generated by Jekyll"
- When I run jekyll build
- Then the _site directory should exist
+ When I run jekyll build -I
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
When I wait 1 second
Then I have an "_includes/about.textile" file that contains "Regenerated by Jekyll"
- When I run jekyll build
- Then the _site directory should exist
+ When I run jekyll build -I
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Basic Site with include tag: Regenerated by Jekyll" in "_site/index.html"
diff --git a/features/layout_data.feature b/features/layout_data.feature
new file mode 100644
index 00000000..78998665
--- /dev/null
+++ b/features/layout_data.feature
@@ -0,0 +1,37 @@
+Feature: Layout data
+ As a hacker who likes to avoid repetition
+ I want to be able to embed data into my layouts
+ In order to make the layouts slightly dynamic
+
+ Scenario: Use custom layout data
+ Given I have a _layouts directory
+ And I have a "_layouts/custom.html" file with content:
+ """
+ ---
+ foo: my custom data
+ ---
+ {{ content }} foo: {{ layout.foo }}
+ """
+ And I have an "index.html" page with layout "custom" that contains "page content"
+ When I run jekyll build
+ Then the "_site/index.html" file should exist
+ And I should see "page content\n foo: my custom data" in "_site/index.html"
+
+ Scenario: Inherit custom layout data
+ Given I have a _layouts directory
+ And I have a "_layouts/custom.html" file with content:
+ """
+ ---
+ layout: base
+ foo: my custom data
+ ---
+ {{ content }}
+ """
+ And I have a "_layouts/base.html" file with content:
+ """
+ {{ content }} foo: {{ layout.foo }}
+ """
+ And I have an "index.html" page with layout "custom" that contains "page content"
+ When I run jekyll build
+ Then the "_site/index.html" file should exist
+ And I should see "page content\n foo: my custom data" in "_site/index.html"
diff --git a/features/markdown.feature b/features/markdown.feature
index c0eeb25d..3649a6d1 100644
--- a/features/markdown.feature
+++ b/features/markdown.feature
@@ -11,7 +11,8 @@ Feature: Markdown
| title | date | content | type |
| Hackers | 2009-03-27 | # My Title | markdown |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Index" in "_site/index.html"
And I should see "
My Title
" in "_site/2009/03/27/hackers.html"
And I should see "
My Title
" in "_site/index.html"
@@ -27,6 +28,7 @@ Feature: Markdown
| title | date | content | type |
| Hackers | 2009-03-27 | # My Title | markdown |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Index" in "_site/index.html"
And I should see "
My Title
" in "_site/index.html"
diff --git a/features/permalinks.feature b/features/permalinks.feature
index cb90d1f7..ca0482fc 100644
--- a/features/permalinks.feature
+++ b/features/permalinks.feature
@@ -10,7 +10,8 @@ Feature: Fancy permalinks
| None Permalink Schema | 2009-03-27 | Totally nothing. |
And I have a configuration file with "permalink" set to "none"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Totally nothing." in "_site/none-permalink-schema.html"
Scenario: Use pretty permalink schema
@@ -20,7 +21,8 @@ Feature: Fancy permalinks
| Pretty Permalink Schema | 2009-03-27 | Totally wordpress. |
And I have a configuration file with "permalink" set to "pretty"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Totally wordpress." in "_site/2009/03/27/pretty-permalink-schema/index.html"
Scenario: Use pretty permalink schema for pages
@@ -29,7 +31,8 @@ Feature: Fancy permalinks
And I have an "sitemap.xml" page that contains "Totally uhm, sitemap"
And I have a configuration file with "permalink" set to "pretty"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Totally index" in "_site/index.html"
And I should see "Totally awesome" in "_site/awesome/index.html"
And I should see "Totally uhm, sitemap" in "_site/sitemap.xml"
@@ -41,7 +44,8 @@ Feature: Fancy permalinks
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Totally custom." in "_site/blog/2009/03/27/custom-permalink-schema/index.html"
Scenario: Use custom permalink schema with category
@@ -51,7 +55,8 @@ Feature: Fancy permalinks
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Totally custom." in "_site/stuff/custom-permalink-schema.html"
Scenario: Use custom permalink schema with squished date
@@ -61,16 +66,32 @@ Feature: Fancy permalinks
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-schema.html"
+ Scenario: Use custom permalink schema with date and time
+ Given I have a _posts directory
+ And I have the following post:
+ | title | category | date | content |
+ | Custom Permalink Schema | stuff | 2009-03-27 22:31:07 | Totally custom. |
+ And I have a configuration file with:
+ | key | value |
+ | permalink | "/:year:month:day:hour:minute:second.html" |
+ | timezone | UTC |
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Totally custom." in "_site/20090327223107.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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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"
@@ -80,6 +101,44 @@ Feature: Fancy permalinks
| title | date | permalink | content |
| Some post | 2013-04-14 | /custom/posts/some.html | bla bla |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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"
+
+ Scenario: Use pretty permalink schema with cased file name
+ Given I have a _posts directory
+ And I have an "_posts/2009-03-27-Pretty-Permalink-Schema.md" page that contains "Totally wordpress"
+ And I have a configuration file with "permalink" set to "pretty"
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Totally wordpress." in "_site/2009/03/27/Pretty-Permalink-Schema/index.html"
+
+ Scenario: Use custom permalink schema with cased file name
+ Given I have a _posts directory
+ And I have an "_posts/2009-03-27-Custom-Schema.md" page with title "Custom Schema" that contains "Totally awesome"
+ And I have a configuration file with "permalink" set to "/:year/:month/:day/:slug/"
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Totally awesome" in "_site/2009/03/27/custom-schema/index.html"
+
+ Scenario: Use pretty permalink schema with title containing underscore
+ Given I have a _posts directory
+ And I have an "_posts/2009-03-27-Custom_Schema.md" page with title "Custom Schema" that contains "Totally awesome"
+ And I have a configuration file with "permalink" set to "pretty"
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Totally awesome" in "_site/2009/03/27/Custom_Schema/index.html"
+
+ Scenario: Use a non-HTML file extension in the permalink
+ Given I have a _posts directory
+ And I have an "_posts/2016-01-18-i-am-php.md" page with permalink "/2016/i-am-php.php" that contains "I am PHP"
+ And I have a "i-am-also-php.md" page with permalink "/i-am-also-php.php" that contains "I am also PHP"
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "I am PHP" in "_site/2016/i-am-php.php"
+ And I should see "I am also PHP" in "_site/i-am-also-php.php"
diff --git a/features/plugins.feature b/features/plugins.feature
index a36c6c82..be01a4a9 100644
--- a/features/plugins.feature
+++ b/features/plugins.feature
@@ -6,7 +6,8 @@ Feature: Configuring and using plugins
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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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"
@@ -17,7 +18,8 @@ Feature: Configuring and using plugins
| gems | [jekyll_test_plugin] |
| whitelist | [] |
When I run jekyll build --safe
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Whatever" in "_site/index.html"
And the "_site/test.txt" file should not exist
@@ -28,7 +30,8 @@ Feature: Configuring and using plugins
| gems | [jekyll_test_plugin, jekyll_test_plugin_malicious] |
| whitelist | [jekyll_test_plugin] |
When I run jekyll build --safe
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Whatever" in "_site/index.html"
And the "_site/test.txt" file should exist
And I should see "this is a test" in "_site/test.txt"
diff --git a/features/post_data.feature b/features/post_data.feature
index 736fc936..79b92c26 100644
--- a/features/post_data.feature
+++ b/features/post_data.feature
@@ -11,7 +11,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post title: Star Wars" in "_site/2009/03/27/star-wars.html"
Scenario: Use post.url variable
@@ -22,7 +23,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post url: /2009/03/27/star-wars.html" in "_site/2009/03/27/star-wars.html"
Scenario: Use post.date variable
@@ -33,9 +35,24 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post date: 27 Mar 2009" in "_site/2009/03/27/star-wars.html"
+ Scenario: Use post.date variable with invalid
+ Given I have a _posts directory
+ And I have a "_posts/2016-01-01-test.md" page with date "tuesday" that contains "I have a bad date."
+ When I run jekyll build
+ Then the _site directory should not exist
+ And I should see "Document '_posts/2016-01-01-test.md' does not have a valid date in the YAML front matter." in the build output
+
+ Scenario: Invalid date in filename
+ Given I have a _posts directory
+ And I have a "_posts/2016-22-01-test.md" page that contains "I have a bad date."
+ When I run jekyll build
+ Then the _site directory should not exist
+ And I should see "Document '_posts/2016-22-01-test.md' does not have a valid date in the filename." in the build output
+
Scenario: Use post.id variable
Given I have a _posts directory
And I have a _layouts directory
@@ -44,7 +61,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post id: /2009/03/27/star-wars" in "_site/2009/03/27/star-wars.html"
Scenario: Use post.content variable
@@ -55,7 +73,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post content:
Luke, I am your father.
" in "_site/2009/03/27/star-wars.html"
Scenario: Use post.categories variable when category is in a folder
@@ -67,7 +86,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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 a folder and has category in YAML
@@ -79,7 +99,8 @@ Feature: Post data
| Star Wars | 2009-03-27 | simple | film | Luke, I am your father. |
And I have a simple layout that contains "Post category: {{ page.categories }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post category: movies" in "_site/movies/film/2009/03/27/star-wars.html"
Scenario: Use post.categories variable when category is in a folder and has categories in YAML
@@ -91,7 +112,8 @@ Feature: Post data
| Star Wars | 2009-03-27 | simple | [film, scifi] | Luke, I am your father. |
And I have a simple layout that contains "Post category: {{ page.categories }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post category: movies" in "_site/movies/film/scifi/2009/03/27/star-wars.html"
Scenario: Use post.categories variable when category is in a folder and duplicated category is in YAML
@@ -103,7 +125,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
Scenario: Use post.tags variable
@@ -114,7 +137,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post tags: twist" in "_site/2009/05/18/star-wars.html"
Scenario: Use post.categories variable when categories are in folders
@@ -127,7 +151,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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
@@ -140,7 +165,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post categories: scifi and Movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
Scenario: Use post.categories variable when category is in YAML
@@ -151,7 +177,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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
@@ -162,7 +189,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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
@@ -173,7 +201,8 @@ Feature: Post data
| Star Wars | 2009-03-27 | simple | ['scifi', 'movies'] | Luke, I am your father. |
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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 YAML and are duplicated
@@ -184,7 +213,28 @@ Feature: Post data
| Star Wars | 2009-03-27 | simple | ['movies', 'movies'] | Luke, I am your father. |
And I have a simple layout that contains "Post category: {{ page.categories }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
+
+ Scenario: Superdirectories of _posts applied to post.categories
+ Given I have a movies/_posts directory
+ And I have a "movies/_posts/2009-03-27-star-wars.html" page with layout "simple" that contains "hi"
+ And I have a _layouts directory
+ And I have a simple layout that contains "Post category: {{ page.categories }}"
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
+
+ Scenario: Subdirectories of _posts not applied to post.categories
+ Given I have a movies/_posts/scifi directory
+ And I have a "movies/_posts/scifi/2009-03-27-star-wars.html" page with layout "simple" that contains "hi"
+ And I have a _layouts directory
+ And I have a simple layout that contains "Post category: {{ page.categories }}"
+ When I run jekyll build
+ Then I should get a zero exit status
+ And 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
@@ -196,7 +246,8 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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"
@@ -206,7 +257,8 @@ Feature: Post data
| title | type | date | content |
| my-post | html | 2013-04-12 | Source path: {{ page.path }} |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Source path: _posts/2013-04-12-my-post.html" in "_site//2013/04/12/my-post.html"
Examples:
@@ -215,14 +267,15 @@ Feature: Post data
| dir | dir/ |
| dir/nested | dir/nested/ |
- Scenario: Override page.path variable
+ Scenario: Cannot 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 }} |
+ | override | 2013-04-12 | override-path.html | Non-custom path: {{ page.path }} |
When I run jekyll build
- Then the _site directory should exist
- And I should see "Custom path: override-path.html" in "_site/2013/04/12/override.html"
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "Non-custom path: _posts/2013-04-12-override.markdown" in "_site/2013/04/12/override.html"
Scenario: Disable a post from being published
Given I have a _posts directory
@@ -231,7 +284,8 @@ Feature: Post data
| title | date | layout | published | content |
| Star Wars | 2009-03-27 | simple | false | Luke, I am your father. |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And the "_site/2009/03/27/star-wars.html" file should not exist
And I should see "Published!" in "_site/index.html"
@@ -243,9 +297,22 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Post author: Darth Vader" in "_site/2009/03/27/star-wars.html"
+ Scenario: Use a variable which is a reserved keyword in Ruby
+ Given I have a _posts directory
+ And I have a _layouts directory
+ And I have the following post:
+ | title | date | layout | class | content |
+ | My post | 2016-01-21 | simple | kewl-post | Luke, I am your father. |
+ And I have a simple layout that contains "{{page.title}} has class {{page.class}}"
+ When I run jekyll build
+ Then I should get a zero exit status
+ And the _site directory should exist
+ And I should see "My post has class kewl-post" in "_site/2016/01/21/my-post.html"
+
Scenario: Previous and next posts title
Given I have a _posts directory
And I have a _layouts directory
@@ -256,6 +323,7 @@ Feature: Post data
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "next post: Some like it hot" in "_site/2009/03/27/star-wars.html"
And I should see "Previous post: Some like it hot" in "_site/2009/05/27/terminator.html"
diff --git a/features/post_excerpts.feature b/features/post_excerpts.feature
index e9d048bd..7344000c 100644
--- a/features/post_excerpts.feature
+++ b/features/post_excerpts.feature
@@ -12,7 +12,8 @@ Feature: Post excerpts
| title | date | layout | content |
| entry1 | 2007-12-31 | post | content for entry1. |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see exactly "
content for entry1.
" in "_site/index.html"
Scenario: An excerpt from a post with a layout
@@ -24,7 +25,8 @@ Feature: Post excerpts
| title | date | layout | content |
| entry1 | 2007-12-31 | post | content for entry1. |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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
@@ -41,10 +43,11 @@ Feature: Post excerpts
| title | date | layout | content |
| entry1 | 2007-12-31 | post | content for entry1. |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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 "
content for entry1.
" in "_site/index.html"
- And I should see "
content for entry1.
\n\n" in "_site/2007/12/31/entry1.html"
+ And I should see "
content for entry1.
\n" in "_site/2007/12/31/entry1.html"
diff --git a/features/rendering.feature b/features/rendering.feature
index 55a9d3d2..5031ef06 100644
--- a/features/rendering.feature
+++ b/features/rendering.feature
@@ -5,11 +5,19 @@ Feature: Rendering
But I want to make it as simply as possible
So render with Liquid and place in Layouts
+ Scenario: When receiving bad Liquid
+ Given I have a "index.html" page with layout "simple" that contains "{% include invalid.html %}"
+ And I have a simple layout that contains "{{ content }}"
+ When I run jekyll build
+ Then I should get a non-zero exit-status
+ And I should see "Liquid Exception" in the build output
+
Scenario: Render Liquid and place in layout
Given I have a "index.html" page with layout "simple" that contains "Hi there, Jekyll {{ jekyll.environment }}!"
And I have a simple layout that contains "{{ content }}Ahoy, indeed!"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Hi there, Jekyll development!\nAhoy, indeed" in "_site/index.html"
Scenario: Don't place asset files in layout
@@ -18,7 +26,8 @@ Feature: Rendering
And I have a configuration file with "gems" set to "[jekyll-coffeescript]"
And I have a simple layout that contains "{{ content }}Ahoy, indeed!"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should not see "Ahoy, indeed!" in "_site/index.css"
And I should not see "Ahoy, indeed!" in "_site/index.js"
@@ -26,18 +35,21 @@ Feature: Rendering
Given I have an "index.scss" page that contains ".foo-bar { color:{{site.color}}; }"
And I have a configuration file with "color" set to "red"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see ".foo-bar {\n color: red; }" in "_site/index.css"
Scenario: Not render liquid in CoffeeScript without explicitly including jekyll-coffeescript
Given I have an "index.coffee" page with animal "cicada" that contains "hey='for {{page.animal}}'"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And the "_site/index.js" file should not exist
Scenario: Render liquid in CoffeeScript with jekyll-coffeescript enabled
Given I have an "index.coffee" page with animal "cicada" that contains "hey='for {{page.animal}}'"
And I have a configuration file with "gems" set to "[jekyll-coffeescript]"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "hey = 'for cicada';" in "_site/index.js"
diff --git a/features/site_configuration.feature b/features/site_configuration.feature
index c9edc2ff..5c495356 100644
--- a/features/site_configuration.feature
+++ b/features/site_configuration.feature
@@ -8,7 +8,8 @@ Feature: Site configuration
And I have an "_sourcedir/index.html" file that contains "Changing source directory"
And I have a configuration file with "source" set to "_sourcedir"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Changing source directory" in "_site/index.html"
Scenario: Change destination directory
@@ -66,27 +67,31 @@ Feature: Site configuration
Given I have an "index.markdown" page that contains "[Google](http://google.com)"
And I have a configuration file with "markdown" set to "rdiscount"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Google" in "_site/index.html"
Scenario: Use Kramdown for markup
Given I have an "index.markdown" page that contains "[Google](http://google.com)"
And I have a configuration file with "markdown" set to "kramdown"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Google" in "_site/index.html"
Scenario: Use Redcarpet for markup
Given I have an "index.markdown" page that contains "[Google](http://google.com)"
And I have a configuration file with "markdown" set to "redcarpet"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Google" in "_site/index.html"
Scenario: Highlight code with pygments
Given I have an "index.html" page that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Hello world!" in "_site/index.html"
And I should see "class=\"highlight\"" in "_site/index.html"
@@ -94,7 +99,8 @@ Feature: Site configuration
Given I have an "index.html" page that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}"
And I have a configuration file with "highlighter" set to "rouge"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Hello world!" in "_site/index.html"
And I should see "class=\"highlight\"" in "_site/index.html"
@@ -122,7 +128,8 @@ Feature: Site configuration
| entry1 | 2007-12-31 | post | content for entry1. |
| entry2 | 2020-01-31 | post | content for entry2. |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Page Layout: 1 on 2010-01-01" in "_site/index.html"
And I should see "Post Layout:
content for entry1.
" in "_site/2007/12/31/entry1.html"
And the "_site/2020/01/31/entry2.html" file should not exist
@@ -142,7 +149,8 @@ Feature: Site configuration
| entry1 | 2007-12-31 | post | content for entry1. |
| entry2 | 2020-01-31 | post | content for entry2. |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Page Layout: 2 on 2010-01-01" in "_site/index.html"
And I should see "Post Layout:
content for entry1.
" in "_site/2007/12/31/entry1.html"
And I should see "Post Layout:
content for entry2.
" in "_site/2020/01/31/entry2.html"
@@ -161,7 +169,8 @@ Feature: Site configuration
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Page Layout: 2" in "_site/index.html"
And I should see "Post Layout:
content for entry1.
\n built at 2013-04-09T23:22:00-04:00" in "_site/2013/04/09/entry1.html"
And I should see "Post Layout:
content for entry2.
\n built at 2013-04-10T03:14:00-04:00" in "_site/2013/04/10/entry2.html"
@@ -180,7 +189,8 @@ Feature: Site configuration
| 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Page Layout: 2" in "_site/index.html"
And the "_site/2013/04/09/entry1.html" file should exist
And the "_site/2013/04/09/entry2.html" file should exist
@@ -198,7 +208,8 @@ Feature: Site configuration
| Oranges | 2009-04-01 | An article about oranges |
| Bananas | 2009-04-05 | An article about bananas |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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
@@ -211,7 +222,8 @@ Feature: Site configuration
| .gitignore |
| .foo |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see ".DS_Store" in "_site/.gitignore"
And the "_site/.htaccess" file should not exist
@@ -224,14 +236,15 @@ Feature: Site configuration
| key | value |
| time | 2010-01-01 |
| future | true |
- | layouts | _theme |
+ | layouts_dir | _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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Page Layout: 2 on 2010-01-01" in "_site/index.html"
And I should see "Post Layout:
content for entry1.
" in "_site/2007/12/31/entry1.html"
And I should see "Post Layout:
content for entry2.
" in "_site/2020/01/31/entry2.html"
@@ -240,6 +253,7 @@ Feature: Site configuration
Given I have an "index.html" page with layout "page" that contains "FOO"
And I have a "_config.yml" file that contains "layouts: '../../../../../../../../../../../../../../usr/include'"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "FOO" in "_site/index.html"
And I should not see " " in "_site/index.html"
diff --git a/features/site_data.feature b/features/site_data.feature
index a7fadf34..e3c99a64 100644
--- a/features/site_data.feature
+++ b/features/site_data.feature
@@ -6,14 +6,16 @@ Feature: Site data
Scenario: Use page variable in a page
Given I have an "contact.html" page with title "Contact" that contains "{{ page.title }}: email@example.com"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Contact: email@example.com" in "_site/contact.html"
Scenario Outline: Use page.path variable in a page
Given I have a directory
And I have a "" page that contains "Source path: {{ page.path }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Source path: " in "_site/"
Examples:
@@ -25,13 +27,15 @@ Feature: Site data
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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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 }}"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see today's time in "_site/index.html"
Scenario: Use site.posts variable for latest post
@@ -43,7 +47,8 @@ Feature: Site data
| Second Post | 2009-03-26 | My Second Post |
| Third Post | 2009-03-27 | My Third Post |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Third Post: /2009/03/27/third-post.html" in "_site/index.html"
Scenario: Use site.posts variable in a loop
@@ -55,7 +60,8 @@ Feature: Site data
| Second Post | 2009-03-26 | My Second Post |
| Third Post | 2009-03-27 | My Third Post |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Third Post Second Post First Post" in "_site/index.html"
Scenario: Use site.categories.code variable
@@ -66,7 +72,8 @@ Feature: Site data
| Awesome Hack | 2009-03-26 | code | puts 'Hello World' |
| Delicious Beer | 2009-03-26 | food | 1) Yuengling |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Awesome Hack" in "_site/index.html"
Scenario: Use site.tags variable
@@ -76,7 +83,8 @@ Feature: Site data
| title | date | tag | content |
| Delicious Beer | 2009-03-26 | beer | 1) Yuengling |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "Yuengling" in "_site/index.html"
Scenario: Order Posts by name when on the same date
@@ -90,18 +98,21 @@ Feature: Site data
| C | 2009-03-26 | C |
| last | 2009-04-26 | last |
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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://example.com"
When I run jekyll build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And 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 build
- Then the _site directory should exist
+ Then I should get a zero exit status
+ And the _site directory should exist
And I should see "\d+\.\d+\.\d+" in "_site/index.html"
diff --git a/features/step_definitions.rb b/features/step_definitions.rb
new file mode 100644
index 00000000..f609076d
--- /dev/null
+++ b/features/step_definitions.rb
@@ -0,0 +1,245 @@
+Before do
+ FileUtils.mkdir_p(Paths.test_dir) unless Paths.test_dir.directory?
+ Dir.chdir(Paths.test_dir)
+end
+
+#
+
+After do
+ Paths.test_dir.rmtree if Paths.test_dir.exist?
+ Paths.output_file.delete if Paths.output_file.exist?
+ Paths.status_file.delete if Paths.status_file.exist?
+ Dir.chdir(Paths.test_dir.parent)
+end
+
+#
+
+Given %r{^I have a blank site in "(.*)"$} do |path|
+ if !File.exist?(path)
+ then FileUtils.mkdir_p(path)
+ end
+end
+
+#
+
+Given %r{^I do not have a "(.*)" directory$} do |path|
+ Paths.test_dir.join(path).directory?
+end
+
+#
+
+Given %r{^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$} do |file, key, value, text|
+ File.write(file, Jekyll::Utils.strip_heredoc(<<-DATA))
+ ---
+ #{key || 'layout'}: #{value || 'nil'}
+ ---
+
+ #{text}
+ DATA
+end
+
+#
+
+Given %r{^I have an? "(.*)" file that contains "(.*)"$} do |file, text|
+ File.write(file, text)
+end
+
+#
+
+Given %r{^I have an? (.*) (layout|theme) that contains "(.*)"$} do |name, type, text|
+ folder = type == "layout" ? "_layouts" : "_theme"
+
+ destination_file = Pathname.new(File.join(folder, "#{name}.html"))
+ FileUtils.mkdir_p(destination_file.parent) unless destination_file.parent.directory?
+ File.write(destination_file, text)
+end
+
+#
+
+Given %r{^I have an? "(.*)" file with content:$} do |file, text|
+ File.write(file, text)
+end
+
+#
+
+Given %r{^I have an? (.*) directory$} do |dir|
+ if !File.directory?(dir)
+ then FileUtils.mkdir_p(dir)
+ end
+end
+
+#
+
+Given %r{^I have the following (draft|page|post)s?(?: (in|under) "([^"]+)")?:$} do |status, direction, folder, table|
+ table.hashes.each do |input_hash|
+ title = slug(input_hash["title"])
+ ext = input_hash["type"] || "markdown"
+ filename = filename = "#{title}.#{ext}" if %w(draft page).include?(status)
+ before, after = location(folder, direction)
+ dest_folder = "_drafts" if status == "draft"
+ dest_folder = "_posts" if status == "post"
+ dest_folder = "" if status == "page"
+
+ if status == "post"
+ parsed_date = Time.xmlschema(input_hash['date']) rescue Time.parse(input_hash['date'])
+ filename = "#{parsed_date.strftime('%Y-%m-%d')}-#{title}.#{ext}"
+ end
+
+ path = File.join(before, dest_folder, after, filename)
+ File.write(path, file_content_from_hash(input_hash))
+ end
+end
+
+#
+
+Given %r{^I have a configuration file with "(.*)" set to "(.*)"$} do |key, value|
+ config = if source_dir.join("_config.yml").exist?
+ SafeYAML.load_file(source_dir.join("_config.yml"))
+ else
+ {}
+ end
+ config[key] = YAML.load(value)
+ File.write("_config.yml", YAML.dump(config))
+end
+
+#
+
+Given %r{^I have a configuration file with:$} do |table|
+ table.hashes.each do |row|
+ step %(I have a configuration file with "#{row["key"]}" set to "#{row["value"]}")
+ end
+end
+
+#
+
+Given %r{^I have a configuration file with "([^\"]*)" set to:$} do |key, table|
+ File.open("_config.yml", "w") do |f|
+ f.write("#{key}:\n")
+ table.hashes.each do |row|
+ f.write("- #{row["value"]}\n")
+ end
+ end
+end
+
+#
+
+Given %r{^I have fixture collections$} do
+ FileUtils.cp_r Paths.source_dir.join("test", "source", "_methods"), source_dir
+ FileUtils.cp_r Paths.source_dir.join("test", "source", "_thanksgiving"), source_dir
+end
+
+#
+
+Given %r{^I wait (\d+) second(s?)$} do |time, plural|
+ sleep(time.to_f)
+end
+
+#
+
+When %r{^I run jekyll(.*)$} do |args|
+ run_jekyll(args)
+ if args.include?("--verbose") || ENV["DEBUG"]
+ $stderr.puts "\n#{jekyll_run_output}\n"
+ end
+end
+
+#
+
+When %r{^I run bundle(.*)$} do |args|
+ run_bundle(args)
+ if args.include?("--verbose") || ENV['DEBUG']
+ $stderr.puts "\n#{jekyll_run_output}\n"
+ end
+end
+
+#
+
+When %r{^I change "(.*)" to contain "(.*)"$} do |file, text|
+ File.open(file, "a") do |f|
+ f.write(text)
+ end
+end
+
+#
+
+When %r{^I delete the file "(.*)"$} do |file|
+ File.delete(file)
+end
+
+#
+
+Then %r{^the (.*) directory should +(not )?exist$} do |dir, negative|
+ if negative.nil?
+ expect(Pathname.new(dir)).to exist
+ else
+ expect(Pathname.new(dir)).to_not exist
+ end
+end
+
+#
+Then %r{^I should (not )?see "(.*)" in "(.*)"$} do |negative, text, file|
+ step %(the "#{file}" file should exist)
+ regexp = Regexp.new(text, Regexp::MULTILINE)
+ if negative.nil? || negative.empty?
+ expect(file_contents(file)).to match regexp
+ else
+ expect(file_contents(file)).not_to match regexp
+ end
+end
+
+#
+
+Then %r{^I should see exactly "(.*)" in "(.*)"$} do |text, file|
+ step %(the "#{file}" file should exist)
+ expect(file_contents(file).strip).to eq text
+end
+
+#
+
+Then %r{^I should see escaped "(.*)" in "(.*)"$} do |text, file|
+ step %(I should see "#{Regexp.escape(text)}" in "#{file}")
+end
+
+#
+
+Then %r{^the "(.*)" file should +(not )?exist$} do |file, negative|
+ if negative.nil?
+ expect(Pathname.new(file)).to exist
+ else
+ expect(Pathname.new(file)).to_not exist
+ end
+end
+
+#
+
+Then %r{^I should see today's time in "(.*)"$} do |file|
+ step %(I should see "#{seconds_agnostic_time(Time.now)}" in "#{file}")
+end
+
+#
+
+Then %r{^I should see today's date in "(.*)"$} do |file|
+ step %(I should see "#{Date.today.to_s}" in "#{file}")
+end
+
+#
+
+Then %r{^I should (not )?see "(.*)" in the build output$} do |negative, text|
+ if negative.nil? || negative.empty?
+ expect(jekyll_run_output).to match Regexp.new(text)
+ else
+ expect(jekyll_run_output).not_to match Regexp.new(text)
+ end
+end
+
+#
+
+Then %r{^I should get a zero exit(?:\-| )status$} do
+ step %(I should see "EXIT STATUS: 0" in the build output)
+end
+
+#
+
+Then %r{^I should get a non-zero exit(?:\-| )status$} do
+ step %(I should not see "EXIT STATUS: 0" in the build output)
+end
diff --git a/features/step_definitions/jekyll_steps.rb b/features/step_definitions/jekyll_steps.rb
deleted file mode 100644
index 27c8692d..00000000
--- a/features/step_definitions/jekyll_steps.rb
+++ /dev/null
@@ -1,229 +0,0 @@
-def file_content_from_hash(input_hash)
- matter_hash = input_hash.reject { |k, v| k == "content" }
- matter = matter_hash.map { |k, v| "#{k}: #{v}\n" }.join.chomp
-
- content = if input_hash['input'] && input_hash['filter']
- "{{ #{input_hash['input']} | #{input_hash['filter']} }}"
- else
- input_hash['content']
- end
-
- <<-EOF
----
-#{matter}
----
-#{content}
-EOF
-end
-
-Before do
- FileUtils.mkdir_p(TEST_DIR) unless File.exist?(TEST_DIR)
- Dir.chdir(TEST_DIR)
-end
-
-After do
- FileUtils.rm_rf(TEST_DIR) if File.exist?(TEST_DIR)
- FileUtils.rm(JEKYLL_COMMAND_OUTPUT_FILE) if File.exist?(JEKYLL_COMMAND_OUTPUT_FILE)
- Dir.chdir(File.dirname(TEST_DIR))
-end
-
-World do
- MinitestWorld.new
-end
-
-Given /^I have a blank site in "(.*)"$/ do |path|
- FileUtils.mkdir_p(path) unless File.exist?(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
-Given /^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$/ do |file, key, value, text|
- File.open(file, 'w') do |f|
- f.write <<-EOF
----
-#{key || 'layout'}: #{value || 'nil'}
----
-#{text}
-EOF
- end
-end
-
-Given /^I have an? "(.*)" file that contains "(.*)"$/ do |file, text|
- File.open(file, 'w') do |f|
- f.write(text)
- end
-end
-
-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)
- end
-end
-
-Given /^I have an? (.*) directory$/ do |dir|
- FileUtils.mkdir_p(dir)
-end
-
-Given /^I have the following (draft|page|post)s?(?: (in|under) "([^"]+)")?:$/ do |status, direction, folder, table|
- table.hashes.each do |input_hash|
- title = slug(input_hash['title'])
- ext = input_hash['type'] || 'markdown'
- before, after = location(folder, direction)
-
- case status
- when "draft"
- dest_folder = '_drafts'
- filename = "#{title}.#{ext}"
- when "page"
- dest_folder = ''
- filename = "#{title}.#{ext}"
- when "post"
- parsed_date = Time.xmlschema(input_hash['date']) rescue Time.parse(input_hash['date'])
- dest_folder = '_posts'
- filename = "#{parsed_date.strftime('%Y-%m-%d')}-#{title}.#{ext}"
- end
-
- path = File.join(before, dest_folder, after, filename)
- File.open(path, 'w') do |f|
- f.write file_content_from_hash(input_hash)
- end
- end
-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")
- end
-end
-
-Given /^I have a configuration file with:$/ do |table|
- File.open('_config.yml', 'w') do |f|
- table.hashes.each do |row|
- f.write("#{row["key"]}: #{row["value"]}\n")
- end
- end
-end
-
-Given /^I have a configuration file with "([^\"]*)" set to:$/ do |key, table|
- File.open('_config.yml', 'w') do |f|
- f.write("#{key}:\n")
- table.hashes.each do |row|
- f.write("- #{row["value"]}\n")
- end
- end
-end
-
-Given /^I have fixture collections$/ do
- FileUtils.cp_r File.join(JEKYLL_SOURCE_DIR, "test", "source", "_methods"), source_dir
-end
-
-Given /^I wait (\d+) second(s?)$/ do |time, plural|
- sleep(time.to_f)
-end
-
-##################
-#
-# Changing stuff
-#
-##################
-
-When /^I run jekyll(.*)$/ do |args|
- status = run_jekyll(args)
- if args.include?("--verbose") || ENV['DEBUG']
- puts jekyll_run_output
- end
-end
-
-When /^I run bundle(.*)$/ do |args|
- status = run_bundle(args)
- if args.include?("--verbose") || ENV['DEBUG']
- puts jekyll_run_output
- end
-end
-
-When /^I change "(.*)" to contain "(.*)"$/ do |file, text|
- File.open(file, 'a') do |f|
- f.write(text)
- end
-end
-
-When /^I delete the file "(.*)"$/ do |file|
- File.delete(file)
-end
-
-##################
-#
-# Checking stuff
-#
-##################
-
-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, Regexp::MULTILINE), 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|
- refute_match Regexp.new(text, Regexp::MULTILINE), 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|
- file_does_exist = File.file?(file)
- unless file_does_exist
- all_steps_to_path(file).each do |dir|
- STDERR.puts ""
- STDERR.puts "Dir #{dir}:"
- STDERR.puts Dir["#{dir}/**/*"]
- end
- end
- assert file_does_exist, "The file \"#{file}\" does not exist.\n"
-end
-
-Then /^the "(.*)" file should not exist$/ do |file|
- assert !File.exist?(file), "The file \"#{file}\" exists"
-end
-
-Then /^I should see today's time in "(.*)"$/ do |file|
- 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_contents(file)
-end
-
-Then /^I should see "(.*)" in the build output$/ do |text|
- assert_match Regexp.new(text), jekyll_run_output
-end
diff --git a/features/support/env.rb b/features/support/env.rb
deleted file mode 100644
index 9e9f47fd..00000000
--- a/features/support/env.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-require 'fileutils'
-require 'posix-spawn'
-require 'minitest/spec'
-require 'time'
-
-class MinitestWorld
- extend Minitest::Assertions
- attr_accessor :assertions
-
- def initialize
- self.assertions = 0
- end
-end
-
-JEKYLL_SOURCE_DIR = File.dirname(File.dirname(File.dirname(__FILE__)))
-TEST_DIR = File.expand_path(File.join('..', '..', 'tmp', 'jekyll'), File.dirname(__FILE__))
-JEKYLL_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'jekyll'))
-JEKYLL_COMMAND_OUTPUT_FILE = File.join(File.dirname(TEST_DIR), 'jekyll_output.txt')
-
-def source_dir(*files)
- File.join(TEST_DIR, *files)
-end
-
-def all_steps_to_path(path)
- source = Pathname.new(source_dir('_site')).expand_path
- dest = Pathname.new(path).expand_path
- paths = []
- dest.ascend do |f|
- break if f.eql? source
- paths.unshift f.to_s
- end
- paths
-end
-
-def jekyll_output_file
- JEKYLL_COMMAND_OUTPUT_FILE
-end
-
-def jekyll_run_output
- File.read(jekyll_output_file) if File.file?(jekyll_output_file)
-end
-
-def run_bundle(args)
- child = run_in_shell('bundle', *args.strip.split(' '))
-end
-
-def run_jekyll(args)
- child = run_in_shell(JEKYLL_PATH, *args.strip.split(' '), "--trace")
- child.status.exitstatus == 0
-end
-
-def run_in_shell(*args)
- POSIX::Spawn::Child.new *args, :out => [JEKYLL_COMMAND_OUTPUT_FILE, "w"]
-end
-
-def slug(title)
- if title
- title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
- else
- Time.now.strftime("%s%9N") # nanoseconds since the Epoch
- end
-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)
- date, time, zone = datetime.to_s.split(" ")
- time = seconds_agnostic_time(time)
- [
- 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
diff --git a/features/support/overview.rb b/features/support/formatter.rb
similarity index 55%
rename from features/support/overview.rb
rename to features/support/formatter.rb
index 8d414be7..f399a3ce 100644
--- a/features/support/overview.rb
+++ b/features/support/formatter.rb
@@ -2,140 +2,177 @@ require 'fileutils'
require 'colorator'
require 'cucumber/formatter/console'
require 'cucumber/formatter/io'
-require 'gherkin/formatter/escaping'
-module Features
- module Support
- # The formatter used for --format pretty (the default formatter).
- #
- # This formatter prints features to plain text - exactly how they were parsed,
- # just prettier. That means with proper indentation and alignment of table columns.
- #
- # If the output is STDOUT (and not a file), there are bright colours to watch too.
- #
- class Overview
+module Jekyll
+ module Cucumber
+ class Formatter
+ attr_accessor :indent, :runtime
+ include ::Cucumber::Formatter::Console
+ include ::Cucumber::Formatter::Io
include FileUtils
- include Cucumber::Formatter::Console
- include Cucumber::Formatter::Io
- include Gherkin::Formatter::Escaping
- attr_writer :indent
- attr_reader :runtime
+
+ CHARS = {
+ :failed => "\u2718".red,
+ :pending => "\u203D".yellow,
+ :undefined => "\u2718".red,
+ :passed => "\u2714".green,
+ :skipped => "\u203D".blue
+ }
+
+ #
def initialize(runtime, path_or_io, options)
- @runtime, @io, @options = runtime, ensure_io(path_or_io, "pretty"), options
- @exceptions = []
- @indent = 0
+ @runtime = runtime
+ @snippets_input = []
+ @io = ensure_io(path_or_io)
@prefixes = options[:prefixes] || {}
@delayed_messages = []
+ @options = options
+ @exceptions = []
+ @indent = 0
end
+ #
+
def before_features(features)
print_profile_information
end
+ #
+
def after_features(features)
@io.puts
print_summary(features)
end
+ #
+
def before_feature(feature)
@exceptions = []
@indent = 0
end
- def comment_line(comment_line)
- end
+ #
- def after_tags(tags)
- end
+ def tag_name(tag_name); end
+ def comment_line(comment_line); end
+ def after_feature_element(feature_element); end
+ def after_tags(tags); end
- def tag_name(tag_name)
- end
+ #
def before_feature_element(feature_element)
@indent = 2
@scenario_indent = 2
end
- def after_feature_element(feature_element)
- end
+ #
def before_background(background)
- @indent = 2
@scenario_indent = 2
@in_background = true
+ @indent = 2
end
+ #
+
def after_background(background)
@in_background = nil
end
- def background_name(keyword, name, file_colon_line, source_indent)
- print_feature_element_name(keyword, name, file_colon_line, source_indent)
+ #
+
+ def background_name(keyword, name, source_line, indend)
+ print_feature_element_name(
+ keyword, name, source_line, indend
+ )
end
- def scenario_name(keyword, name, file_colon_line, source_indent)
- print_feature_element_name(keyword, name, file_colon_line, source_indent)
+ #
+
+ def scenario_name(keyword, name, source_line, indent)
+ print_feature_element_name(
+ keyword, name, source_line, indent
+ )
end
+ #
+
def before_step(step)
@current_step = step
end
- def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
+ #
+
+ def before_step_result(keyword, step_match, multiline_arg, status, exception, \
+ source_indent, background, file_colon_line)
+
@hide_this_step = false
if exception
if @exceptions.include?(exception)
@hide_this_step = true
return
end
+
@exceptions << exception
end
+
if status != :failed && @in_background ^ background
@hide_this_step = true
return
end
+
@status = status
end
- CHARS = {
- :failed => "x".red,
- :pending => "?".yellow,
- :undefined => "x".red,
- :passed => ".".green,
- :skipped => "-".blue
- }
+ #
def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
@io.print CHARS[status]
+ @io.print " "
end
+ #
+
def exception(exception, status)
return if @hide_this_step
+
@io.puts
print_exception(exception, status, @indent)
@io.flush
end
- private
+ #
- def print_feature_element_name(keyword, name, file_colon_line, source_indent)
+ def after_test_step(test_step, result)
+ collect_snippet_data(
+ test_step, result
+ )
+ end
+
+ #
+
+ private
+ def print_feature_element_name(keyword, name, source_line, indent)
@io.puts
- names = name.empty? ? [name] : name.split("\n")
- line = " #{keyword}: #{names[0]}"
- if @options[:source]
- line_comment = "#{file_colon_line}"
- @io.print(line_comment)
- end
+
+ names = name.empty? ? [name] : name.each_line.to_a
+ line = " #{keyword}: #{names[0]}"
+
+ @io.print(source_line) if @options[:source]
@io.print(line)
@io.print " "
@io.flush
end
+ #
+
def cell_prefix(status)
@prefixes[status]
end
+ #
+
def print_summary(features)
@io.puts
print_stats(features, @options)
diff --git a/features/support/helpers.rb b/features/support/helpers.rb
new file mode 100644
index 00000000..b8334cfd
--- /dev/null
+++ b/features/support/helpers.rb
@@ -0,0 +1,161 @@
+require "fileutils"
+require "jekyll/utils"
+require "open3"
+require "time"
+require "safe_yaml/load"
+
+class Paths
+ SOURCE_DIR = Pathname.new(File.expand_path("../..", __dir__))
+ def self.test_dir; source_dir.join("tmp", "jekyll"); end
+ def self.output_file; test_dir.join("jekyll_output.txt"); end
+ def self.status_file; test_dir.join("jekyll_status.txt"); end
+ def self.jekyll_bin; source_dir.join("bin", "jekyll"); end
+ def self.source_dir; SOURCE_DIR; end
+end
+
+#
+
+def file_content_from_hash(input_hash)
+ matter_hash = input_hash.reject { |k, v| k == "content" }
+ matter = matter_hash.map do |k, v| "#{k}: #{v}\n"
+ end
+
+ matter = matter.join.chomp
+ content = \
+ if !input_hash['input'] || !input_hash['filter']
+ then input_hash['content']
+ else "{{ #{input_hash['input']} | " \
+ "#{input_hash['filter']} }}"
+ end
+
+ Jekyll::Utils.strip_heredoc(<<-EOF)
+ ---
+ #{matter.gsub(
+ /\n/, "\n "
+ )}
+ ---
+ #{content}
+ EOF
+end
+
+#
+
+def source_dir(*files)
+ return Paths.test_dir(*files)
+end
+
+#
+
+def all_steps_to_path(path)
+ source = source_dir
+ dest = Pathname.new(path).expand_path
+ paths = []
+
+ dest.ascend do |f|
+ break if f == source
+ paths.unshift f.to_s
+ end
+
+ paths
+end
+
+#
+
+def jekyll_run_output
+ if Paths.output_file.file?
+ then return Paths.output_file.read
+ end
+end
+
+#
+
+def jekyll_run_status
+ if Paths.status_file.file?
+ then return Paths.status_file.read
+ end
+end
+
+#
+
+def run_bundle(args)
+ run_in_shell("bundle", *args.strip.split(' '))
+end
+
+#
+
+def run_jekyll(args)
+ args = args.strip.split(" ") # Shellwords?
+ process = run_in_shell(Paths.jekyll_bin.to_s, *args, "--trace")
+ process.exitstatus == 0
+end
+
+#
+
+def run_in_shell(*args)
+ i, o, e, p = Open3.popen3(*args)
+ out = o.read.strip
+ err = e.read.strip
+
+ [i, o, e].each do |m|
+ m.close
+ end
+
+ File.write(Paths.status_file, p.value.exitstatus)
+ File.open(Paths.output_file, "wb") do |f|
+ f.puts "$ " << args.join(" ")
+ f.puts out
+ f.puts err
+ f.puts "EXIT STATUS: #{p.value.exitstatus}"
+ end
+
+ p.value
+end
+
+#
+
+def slug(title = nil)
+ if !title
+ then Time.now.strftime("%s%9N") # nanoseconds since the Epoch
+ else title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
+ end
+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)
+ return Pathname.new(path).read
+end
+
+#
+
+def seconds_agnostic_datetime(datetime = Time.now)
+ date, time, zone = datetime.to_s.split(" ")
+ time = seconds_agnostic_time(time)
+
+ [
+ Regexp.escape(date),
+ "#{time}:\\d{2}",
+ Regexp.escape(zone)
+ ] \
+ .join("\\ ")
+end
+
+#
+
+def seconds_agnostic_time(time)
+ time = time.strftime("%H:%M:%S") if time.is_a?(Time)
+ hour, minutes, _ = time.split(":")
+ "#{hour}:#{minutes}"
+end
diff --git a/jekyll.gemspec b/jekyll.gemspec
index 470781c7..167e424c 100644
--- a/jekyll.gemspec
+++ b/jekyll.gemspec
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
s.homepage = 'https://github.com/jekyll/jekyll'
all_files = `git ls-files -z`.split("\x0")
- s.files = all_files.grep(%r{^(bin|lib)/})
+ s.files = all_files.grep(%r{^(bin|lib)/|^.rubocop.yml$})
s.executables = all_files.grep(%r{^bin/}) { |f| File.basename(f) }
s.require_paths = ['lib']
diff --git a/lib/jekyll.rb b/lib/jekyll.rb
index 9d6b5b63..6896bb0b 100644
--- a/lib/jekyll.rb
+++ b/lib/jekyll.rb
@@ -1,4 +1,4 @@
-$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
+$LOAD_PATH.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
# Require all of the Ruby files in the given directory.
#
@@ -16,6 +16,7 @@ end
require 'rubygems'
# stdlib
+require 'forwardable'
require 'fileutils'
require 'time'
require 'English'
@@ -30,10 +31,8 @@ require 'kramdown'
require 'colorator'
SafeYAML::OPTIONS[:suppress_warnings] = true
-Liquid::Template.error_mode = :strict
module Jekyll
-
# internal requires
autoload :Cleaner, 'jekyll/cleaner'
autoload :Collection, 'jekyll/collection'
@@ -53,14 +52,12 @@ module Jekyll
autoload :CollectionReader, 'jekyll/readers/collection_reader'
autoload :DataReader, 'jekyll/readers/data_reader'
autoload :LayoutReader, 'jekyll/readers/layout_reader'
- autoload :DraftReader, 'jekyll/readers/draft_reader'
autoload :PostReader, 'jekyll/readers/post_reader'
autoload :PageReader, 'jekyll/readers/page_reader'
autoload :StaticFileReader, 'jekyll/readers/static_file_reader'
autoload :LogAdapter, 'jekyll/log_adapter'
autoload :Page, 'jekyll/page'
autoload :PluginManager, 'jekyll/plugin_manager'
- autoload :Post, 'jekyll/post'
autoload :Publisher, 'jekyll/publisher'
autoload :Reader, 'jekyll/reader'
autoload :Regenerator, 'jekyll/regenerator'
@@ -98,7 +95,7 @@ module Jekyll
# list of option names and their defaults.
#
# Returns the final configuration Hash.
- def configuration(override = Hash.new)
+ def configuration(override = {})
config = Configuration[Configuration::DEFAULTS]
override = Configuration[override].stringify_keys
unless override.delete('skip_config_files')
@@ -136,7 +133,7 @@ module Jekyll
#
# Returns the new logger.
def logger=(writer)
- @logger = LogAdapter.new(writer)
+ @logger = LogAdapter.new(writer, (ENV["JEKYLL_LOG_LEVEL"] || :info).to_sym)
end
# Public: An array of sites
@@ -156,25 +153,27 @@ module Jekyll
def sanitized_path(base_directory, questionable_path)
return base_directory if base_directory.eql?(questionable_path)
+ questionable_path.insert(0, '/') if questionable_path.start_with?('~')
clean_path = File.expand_path(questionable_path, "/")
- clean_path = clean_path.sub(/\A\w\:\//, '/')
+ clean_path.sub!(/\A\w\:\//, '/')
- unless clean_path.start_with?(base_directory.sub(/\A\w\:\//, '/'))
- File.join(base_directory, clean_path)
- else
+ if clean_path.start_with?(base_directory.sub(/\A\w\:\//, '/'))
clean_path
+ else
+ File.join(base_directory, clean_path)
end
end
# Conditional optimizations
Jekyll::External.require_if_present('liquid-c')
-
end
end
+require "jekyll/drops/drop"
require_all 'jekyll/commands'
require_all 'jekyll/converters'
require_all 'jekyll/converters/markdown'
+require_all 'jekyll/drops'
require_all 'jekyll/generators'
require_all 'jekyll/tags'
diff --git a/lib/jekyll/cleaner.rb b/lib/jekyll/cleaner.rb
index 509cebb1..cab94d55 100644
--- a/lib/jekyll/cleaner.rb
+++ b/lib/jekyll/cleaner.rb
@@ -3,6 +3,7 @@ require 'set'
module Jekyll
# Handles the cleanup of a site's destination before it is built.
class Cleaner
+ HIDDEN_FILE_REGEX = /\/\.{1,2}$/
attr_reader :site
def initialize(site)
@@ -12,7 +13,7 @@ module Jekyll
# Cleans up the site's destination directory
def cleanup!
FileUtils.rm_rf(obsolete_files)
- FileUtils.rm_rf(metadata_file) if @site.full_rebuild?
+ FileUtils.rm_rf(metadata_file) unless @site.incremental?
end
private
@@ -39,8 +40,8 @@ module Jekyll
regex = keep_file_regex
dirs = keep_dirs
- Dir.glob(site.in_dest_dir("**", "*"), File::FNM_DOTMATCH) do |file|
- next if file =~ /\/\.{1,2}$/ || file =~ regex || dirs.include?(file)
+ Utils.safe_glob(site.in_dest_dir, ["**", "*"], File::FNM_DOTMATCH).each do |file|
+ next if file =~ HIDDEN_FILE_REGEX || file =~ regex || dirs.include?(file)
files << file
end
diff --git a/lib/jekyll/collection.rb b/lib/jekyll/collection.rb
index e8740cf6..11a4f06f 100644
--- a/lib/jekyll/collection.rb
+++ b/lib/jekyll/collection.rb
@@ -1,6 +1,7 @@
module Jekyll
class Collection
attr_reader :site, :label, :metadata
+ attr_writer :docs
# Create a new Collection.
#
@@ -22,6 +23,23 @@ module Jekyll
@docs ||= []
end
+ # Override of normal respond_to? to match method_missing's logic for
+ # looking in @data.
+ def respond_to?(method, include_private = false)
+ docs.respond_to?(method.to_sym, include_private) || super
+ end
+
+ # Override of method_missing to check in @data for the key.
+ def method_missing(method, *args, &blck)
+ if docs.respond_to?(method.to_sym)
+ Jekyll.logger.warn "Deprecation:", "#{label}.#{method} should be changed to #{label}.docs.#{method}."
+ Jekyll.logger.warn "", "Called by #{caller.first}."
+ docs.public_send(method.to_sym, *args, &blck)
+ else
+ super
+ end
+ end
+
# Fetch the static files in this collection.
# Defaults to an empty array if no static files have been read in.
#
@@ -38,9 +56,13 @@ module Jekyll
full_path = collection_dir(file_path)
next if File.directory?(full_path)
if Utils.has_yaml_header? full_path
- doc = Jekyll::Document.new(full_path, { site: site, collection: self })
+ doc = Jekyll::Document.new(full_path, { :site => site, :collection => self })
doc.read
- docs << doc if site.publisher.publish?(doc)
+ if site.publisher.publish?(doc) || !write?
+ docs << doc
+ else
+ Jekyll.logger.debug "Skipped From Publishing:", doc.relative_path
+ end
else
relative_dir = Jekyll.sanitized_path(relative_directory, File.dirname(file_path)).chomp("/.")
files << StaticFile.new(site, site.source, relative_dir, File.basename(full_path), self)
@@ -54,10 +76,11 @@ module Jekyll
# Returns an Array of file paths to the documents in this collection
# relative to the collection's directory
def entries
- return Array.new unless exists?
+ return [] unless exists?
@entries ||=
- Dir.glob(collection_dir("**", "*.*")).map do |entry|
- entry["#{collection_dir}/"] = ''; entry
+ Utils.safe_glob(collection_dir, ["**", "*"]).map do |entry|
+ entry["#{collection_dir}/"] = ''
+ entry
end
end
@@ -66,7 +89,7 @@ module Jekyll
#
# Returns a list of filtered entry paths.
def filtered_entries
- return Array.new unless exists?
+ return [] unless exists?
@filtered_entries ||=
Dir.chdir(directory) do
entry_filter.filter(entries).reject do |f|
@@ -148,14 +171,7 @@ module Jekyll
#
# Returns a representation of this collection for use in Liquid.
def to_liquid
- metadata.merge({
- "label" => label,
- "docs" => docs,
- "files" => files,
- "directory" => directory,
- "output" => write?,
- "relative_directory" => relative_directory
- })
+ Drops::CollectionDrop.new self
end
# Whether the collection's documents ought to be written as individual
@@ -163,15 +179,15 @@ module Jekyll
#
# Returns true if the 'write' metadata is true, false otherwise.
def write?
- !!metadata['output']
+ !!metadata.fetch('output', false)
end
# The URL template to render collection's documents at.
#
# Returns the URL template to render collection's documents at.
def url_template
- metadata.fetch('permalink') do
- Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
+ @url_template ||= metadata.fetch('permalink') do
+ Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
end
end
@@ -180,7 +196,7 @@ module Jekyll
# Returns the metadata for this collection
def extract_metadata
if site.config['collections'].is_a?(Hash)
- site.config['collections'][label] || Hash.new
+ site.config['collections'][label] || {}
else
{}
end
diff --git a/lib/jekyll/command.rb b/lib/jekyll/command.rb
index a72640fb..afe72a5b 100644
--- a/lib/jekyll/command.rb
+++ b/lib/jekyll/command.rb
@@ -1,8 +1,6 @@
module Jekyll
class Command
-
class << self
-
# A list of subclasses of Jekyll::Command
def subclasses
@subclasses ||= []
@@ -60,10 +58,8 @@ module Jekyll
c.option 'unpublished', '--unpublished', 'Render posts that were marked as unpublished'
c.option 'quiet', '-q', '--quiet', 'Silence output.'
c.option 'verbose', '-V', '--verbose', 'Print verbose output.'
- c.option 'full_rebuild', '-f', '--full-rebuild', 'Disable incremental rebuild.'
+ c.option 'incremental', '-I', '--incremental', 'Enable incremental rebuild.'
end
-
end
-
end
end
diff --git a/lib/jekyll/commands/build.rb b/lib/jekyll/commands/build.rb
index b6db514d..baa4e88a 100644
--- a/lib/jekyll/commands/build.rb
+++ b/lib/jekyll/commands/build.rb
@@ -1,9 +1,7 @@
module Jekyll
module Commands
class Build < Command
-
class << self
-
# Create the Mercenary command for the Jekyll CLI for this Command
def init_with_program(prog)
prog.command(:build) do |c|
@@ -13,7 +11,7 @@ module Jekyll
add_build_options(c)
- c.action do |args, options|
+ c.action do |_, options|
options["serving"] = false
Jekyll::Commands::Build.process(options)
end
@@ -35,7 +33,9 @@ module Jekyll
build(site, options)
end
- if options.fetch('watch', false)
+ if options.fetch('detach', false)
+ Jekyll.logger.info "Auto-regeneration:", "disabled when running server detached."
+ elsif options.fetch('watch', false)
watch(site, options)
else
Jekyll.logger.info "Auto-regeneration:", "disabled. Use --watch to enable."
@@ -52,10 +52,10 @@ module Jekyll
t = Time.now
source = options['source']
destination = options['destination']
- full_build = options['full_rebuild']
+ incremental = options['incremental']
Jekyll.logger.info "Source:", source
Jekyll.logger.info "Destination:", destination
- Jekyll.logger.info "Incremental build:", (full_build ? "disabled" : "enabled")
+ Jekyll.logger.info "Incremental build:", (incremental ? "enabled" : "disabled. Enable with --incremental")
Jekyll.logger.info "Generating..."
process_site(site)
Jekyll.logger.info "", "done in #{(Time.now - t).round(3)} seconds."
@@ -67,13 +67,11 @@ module Jekyll
# options - A Hash of options passed to the command
#
# Returns nothing.
- def watch(site, options)
+ def watch(_site, options)
External.require_with_graceful_fail 'jekyll-watch'
Jekyll::Watcher.watch(options)
end
-
end # end of class << self
-
end
end
end
diff --git a/lib/jekyll/commands/clean.rb b/lib/jekyll/commands/clean.rb
index 7d787d30..ca19d9b5 100644
--- a/lib/jekyll/commands/clean.rb
+++ b/lib/jekyll/commands/clean.rb
@@ -2,14 +2,15 @@ module Jekyll
module Commands
class Clean < Command
class << self
-
def init_with_program(prog)
prog.command(:clean) do |c|
c.syntax 'clean [subcommand]'
c.description 'Clean the site (removes site output and metadata file) without building.'
- c.action do |args, _|
- Jekyll::Commands::Clean.process({})
+ add_build_options(c)
+
+ c.action do |_, options|
+ Jekyll::Commands::Clean.process(options)
end
end
end
@@ -18,24 +19,21 @@ module Jekyll
options = configuration_from_options(options)
destination = options['destination']
metadata_file = File.join(options['source'], '.jekyll-metadata')
+ sass_cache = File.join(options['source'], '.sass-cache')
- if File.directory? destination
- Jekyll.logger.info "Cleaning #{destination}..."
- FileUtils.rm_rf(destination)
- Jekyll.logger.info "", "done."
- else
- Jekyll.logger.info "Nothing to do for #{destination}."
- end
-
- if File.file? metadata_file
- Jekyll.logger.info "Removing #{metadata_file}..."
- FileUtils.rm_rf(metadata_file)
- Jekyll.logger.info "", "done."
- else
- Jekyll.logger.info "Nothing to do for #{metadata_file}."
- end
+ remove(destination, checker_func: :directory?)
+ remove(metadata_file, checker_func: :file?)
+ remove(sass_cache, checker_func: :directory?)
end
+ def remove(filename, checker_func: :file?)
+ if File.public_send(checker_func, filename)
+ Jekyll.logger.info "Cleaner:", "Removing #{filename}..."
+ FileUtils.rm_rf(filename)
+ else
+ Jekyll.logger.info "Cleaner:", "Nothing to do for #{filename}."
+ end
+ end
end
end
end
diff --git a/lib/jekyll/commands/doctor.rb b/lib/jekyll/commands/doctor.rb
index d6b31205..5c48d5be 100644
--- a/lib/jekyll/commands/doctor.rb
+++ b/lib/jekyll/commands/doctor.rb
@@ -2,16 +2,15 @@ module Jekyll
module Commands
class Doctor < Command
class << self
-
def init_with_program(prog)
prog.command(:doctor) do |c|
c.syntax 'doctor'
c.description 'Search site and print specific deprecation warnings'
c.alias(:hyde)
- c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
+ c.option 'config', '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
- c.action do |args, options|
+ c.action do |_, options|
Jekyll::Commands::Doctor.process(options)
end
end
@@ -32,14 +31,15 @@ module Jekyll
[
fsnotify_buggy?(site),
!deprecated_relative_permalinks(site),
- !conflicting_urls(site)
+ !conflicting_urls(site),
+ !urls_only_differ_by_case(site)
].all?
end
def deprecated_relative_permalinks(site)
if site.config['relative_permalinks']
- Jekyll::Deprecator.deprecation_message "Your site still uses relative" +
- " permalinks, which was removed in" +
+ Jekyll::Deprecator.deprecation_message "Your site still uses relative" \
+ " permalinks, which was removed in" \
" Jekyll v3.0.0."
return true
end
@@ -49,19 +49,18 @@ module Jekyll
conflicting_urls = false
urls = {}
urls = collect_urls(urls, site.pages, site.dest)
- urls = collect_urls(urls, site.posts, site.dest)
+ urls = collect_urls(urls, site.posts.docs, 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
+ next unless paths.size > 1
+ conflicting_urls = true
+ Jekyll.logger.warn "Conflict:", "The URL '#{url}' is the destination" \
+ " for the following pages: #{paths.join(", ")}"
end
conflicting_urls
end
- def fsnotify_buggy?(site)
- return true if !Utils::Platforms.osx?
+ def fsnotify_buggy?(_site)
+ return true unless Utils::Platforms.osx?
if Dir.pwd != `pwd`.strip
Jekyll.logger.error " " + <<-STR.strip.gsub(/\n\s+/, "\n ")
We have detected that there might be trouble using fsevent on your
@@ -76,6 +75,19 @@ module Jekyll
true
end
+ def urls_only_differ_by_case(site)
+ urls_only_differ_by_case = false
+ urls = case_insensitive_urls(site.pages + site.docs_to_write, site.dest)
+ urls.each do |case_insensitive_url, real_urls|
+ next unless real_urls.uniq.size > 1
+ urls_only_differ_by_case = true
+ Jekyll.logger.warn "Warning:", "The following URLs only differ" \
+ " by case. On a case-insensitive file system one of the URLs" \
+ " will be overwritten by the other: #{real_urls.join(", ")}"
+ end
+ urls_only_differ_by_case
+ end
+
private
def collect_urls(urls, things, destination)
things.each do |thing|
@@ -89,8 +101,14 @@ module Jekyll
urls
end
+ def case_insensitive_urls(things, destination)
+ things.inject({}) do |memo, thing|
+ dest = thing.destination(destination)
+ (memo[dest.downcase] ||= []) << dest
+ memo
+ end
+ end
end
-
end
end
end
diff --git a/lib/jekyll/commands/help.rb b/lib/jekyll/commands/help.rb
index 421d87e5..01bf3280 100644
--- a/lib/jekyll/commands/help.rb
+++ b/lib/jekyll/commands/help.rb
@@ -2,7 +2,6 @@ module Jekyll
module Commands
class Help < Command
class << self
-
def init_with_program(prog)
prog.command(:help) do |c|
c.syntax 'help [subcommand]'
@@ -26,7 +25,6 @@ module Jekyll
Jekyll.logger.error "Error:", "Hmm... we don't know what the '#{cmd}' command is."
Jekyll.logger.info "Valid commands:", prog.commands.keys.join(", ")
end
-
end
end
end
diff --git a/lib/jekyll/commands/serve.rb b/lib/jekyll/commands/serve.rb
index 111d6709..69ea8ba7 100644
--- a/lib/jekyll/commands/serve.rb
+++ b/lib/jekyll/commands/serve.rb
@@ -1,151 +1,208 @@
-# -*- encoding: utf-8 -*-
module Jekyll
module Commands
class Serve < Command
-
class << self
+ COMMAND_OPTIONS = {
+ "ssl_cert" => ["--ssl-cert [CERT]", "X.509 (SSL) certificate."],
+ "host" => ["host", "-H", "--host [HOST]", "Host to bind to"],
+ "open_url" => ["-o", "--open-url", "Launch your browser with your site."],
+ "detach" => ["-B", "--detach", "Run the server in the background (detach)"],
+ "ssl_key" => ["--ssl-key [KEY]", "X.509 (SSL) Private Key."],
+ "port" => ["-P", "--port [PORT]", "Port to listen on"],
+ "baseurl" => ["-b", "--baseurl [URL]", "Base URL"],
+ "show_dir_listing" => ["--show-dir-listing",
+ "Show a directory listing instead of loading your index file."],
+ "skip_initial_build" => ["skip_initial_build", "--skip-initial-build",
+ "Skips the initial site build which occurs before the server is started."]
+ }
+
+ #
def init_with_program(prog)
- prog.command(:serve) do |c|
- c.syntax 'serve [options]'
- c.description 'Serve your site locally'
- c.alias :server
- c.alias :s
+ prog.command(:serve) do |cmd|
+ cmd.description "Serve your site locally"
+ cmd.syntax "serve [options]"
+ cmd.alias :server
+ cmd.alias :s
- add_build_options(c)
+ add_build_options(cmd)
+ COMMAND_OPTIONS.each do |key, val|
+ cmd.option key, *val
+ end
- c.option 'detach', '-B', '--detach', 'Run the server in the background (detach)'
- c.option 'port', '-P', '--port [PORT]', 'Port to listen on'
- c.option 'host', '-H', '--host [HOST]', 'Host to bind to'
- c.option 'baseurl', '-b', '--baseurl [URL]', 'Base URL'
- c.option 'skip_initial_build', '--skip-initial-build', 'Skips the initial site build which occurs before the server is started.'
-
- c.action do |args, options|
- options["serving"] = true
- options["watch"] = true unless options.key?("watch")
- Jekyll::Commands::Build.process(options)
- Jekyll::Commands::Serve.process(options)
+ cmd.action do |_, opts|
+ opts["serving"] = true
+ opts["watch" ] = true unless opts.key?("watch")
+ Build.process(opts)
+ Serve.process(opts)
end
end
end
- # Boot up a WEBrick server which points to the compiled site's root.
- def process(options)
- options = configuration_from_options(options)
- destination = options['destination']
+ #
+
+ def process(opts)
+ opts = configuration_from_options(opts)
+ destination = opts["destination"]
setup(destination)
- s = WEBrick::HTTPServer.new(webrick_options(options))
- s.unmount("")
+ server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
+ server.mount(opts["baseurl"], Servlet, destination, file_handler_opts)
+ Jekyll.logger.info "Server address:", server_address(server, opts)
+ launch_browser server, opts if opts["open_url"]
+ boot_or_detach server, opts
+ end
- s.mount(
- options['baseurl'],
- custom_file_handler,
- destination,
- file_handler_options
- )
+ # Do a base pre-setup of WEBRick so that everything is in place
+ # when we get ready to party, checking for an setting up an error page
+ # and making sure our destination exists.
- Jekyll.logger.info "Server address:", server_address(s, options)
+ private
+ def setup(destination)
+ require_relative "serve/servlet"
+
+ FileUtils.mkdir_p(destination)
+ if File.exist?(File.join(destination, "404.html"))
+ WEBrick::HTTPResponse.class_eval do
+ def create_error_page
+ @header["Content-Type"] = "text/html; charset=UTF-8"
+ @body = IO.read(File.join(@config[:DocumentRoot], "404.html"))
+ end
+ end
+ end
+ end
+
+ #
+
+ private
+ def webrick_opts(opts)
+ opts = {
+ :JekyllOptions => opts,
+ :DoNotReverseLookup => true,
+ :MimeTypes => mime_types,
+ :DocumentRoot => opts["destination"],
+ :StartCallback => start_callback(opts["detach"]),
+ :BindAddress => opts["host"],
+ :Port => opts["port"],
+ :DirectoryIndex => %W(
+ index.htm
+ index.html
+ index.rhtml
+ index.cgi
+ index.xml
+ )
+ }
+
+ opts[:DirectoryIndex] = [] if opts[:JekyllOptions]['show_dir_listing']
+
+ enable_ssl(opts)
+ enable_logging(opts)
+ opts
+ end
+
+ # Recreate NondisclosureName under utf-8 circumstance
+
+ private
+ def file_handler_opts
+ WEBrick::Config::FileHandler.merge({
+ :FancyIndexing => true,
+ :NondisclosureName => [
+ '.ht*', '~*'
+ ]
+ })
+ end
+
+ #
+
+ private
+ def server_address(server, opts)
+ address = server.config[:BindAddress]
+ baseurl = "#{opts["baseurl"]}/" if opts["baseurl"]
+ port = server.config[:Port]
+
+ "http://#{address}:#{port}#{baseurl}"
+ end
+
+ #
+
+ private
+ def launch_browser(server, opts)
+ command =
+ if Utils::Platforms.windows?
+ "start"
+ elsif Utils::Platforms.osx?
+ "open"
+ else
+ "xdg-open"
+ end
+ system command, server_address(server, opts)
+ end
+
+ # Keep in our area with a thread or detach the server as requested
+ # by the user. This method determines what we do based on what you
+ # ask us to do.
+
+ private
+ def boot_or_detach(server, opts)
+ if opts["detach"]
+ pid = Process.fork do
+ server.start
+ end
- if options['detach'] # detach the server
- pid = Process.fork { s.start }
Process.detach(pid)
- Jekyll.logger.info "Server detached with pid '#{pid}'.", "Run `pkill -f jekyll' or `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 }
+ Jekyll.logger.info "Server detached with pid '#{pid}'.", \
+ "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
+ else
+ t = Thread.new { server.start }
+ trap("INT") { server.shutdown }
t.join
end
end
- def setup(destination)
- require 'webrick'
+ # Make the stack verbose if the user requests it.
- FileUtils.mkdir_p(destination)
-
- # monkey patch WEBrick using custom 404 page (/404.html)
- if File.exist?(File.join(destination, '404.html'))
- WEBrick::HTTPResponse.class_eval do
- def create_error_page
- @header['content-type'] = "text/html; charset=UTF-8"
- @body = IO.read(File.join(@config[:DocumentRoot], '404.html'))
- end
- end
- end
+ private
+ def enable_logging(opts)
+ opts[:AccessLog] = []
+ level = WEBrick::Log.const_get(opts[:JekyllOptions]["verbose"] ? :DEBUG : :WARN)
+ opts[:Logger] = WEBrick::Log.new($stdout, level)
end
- def webrick_options(config)
- opts = {
- :BindAddress => config['host'],
- :DirectoryIndex => %w(index.html index.htm index.cgi index.rhtml index.xml),
- :DocumentRoot => config['destination'],
- :DoNotReverseLookup => true,
- :MimeTypes => mime_types,
- :Port => config['port'],
- :StartCallback => start_callback(config['detach'])
- }
+ # Add SSL to the stack if the user triggers --enable-ssl and they
+ # provide both types of certificates commonly needed. Raise if they
+ # forget to add one of the certificates.
- if config['verbose']
- opts.merge!({
- :Logger => WEBrick::Log.new($stdout, WEBrick::Log::DEBUG)
- })
- else
- opts.merge!({
- :AccessLog => [],
- :Logger => WEBrick::Log.new([], WEBrick::Log::WARN)
- })
+ private
+ def enable_ssl(opts)
+ return if !opts[:JekyllOptions]["ssl_cert"] && !opts[:JekyllOptions]["ssl_key"]
+ if !opts[:JekyllOptions]["ssl_cert"] || !opts[:JekyllOptions]["ssl_key"]
+ raise RuntimeError, "--ssl-cert or --ssl-key missing."
end
- opts
- end
-
- # Custom WEBrick FileHandler servlet for serving "/file.html" at "/file"
- # when no exact match is found. This mirrors the behavior of GitHub
- # Pages and many static web server configs.
- def custom_file_handler
- Class.new WEBrick::HTTPServlet::FileHandler do
- def search_file(req, res, basename)
- if file = super
- file
- else
- super(req, res, "#{basename}.html")
- end
- end
- end
+ require "openssl"
+ require "webrick/https"
+ source_key = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_key" ])
+ source_certificate = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_cert"])
+ opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read(source_certificate))
+ opts[:SSLPrivateKey ] = OpenSSL::PKey::RSA.new(File.read(source_key))
+ opts[:EnableSSL] = true
end
+ private
def start_callback(detached)
unless detached
- Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
+ proc do
+ Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
+ end
end
end
+ private
def mime_types
- mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
- WEBrick::HTTPUtils::load_mime_types(mime_types_file)
+ file = File.expand_path('../mime.types', File.dirname(__FILE__))
+ WEBrick::HTTPUtils.load_mime_types(file)
end
-
- def server_address(server, options)
- baseurl = "#{options['baseurl']}/" if options['baseurl']
- [
- "http://",
- server.config[:BindAddress],
- ":",
- server.config[:Port],
- baseurl || ""
- ].map(&:to_s).join("")
- end
-
- # recreate NondisclosureName under utf-8 circumstance
- def file_handler_options
- WEBrick::Config::FileHandler.merge({
- :FancyIndexing => true,
- :NondisclosureName => ['.ht*','~*']
- })
- end
-
end
-
end
end
end
diff --git a/lib/jekyll/commands/serve/servlet.rb b/lib/jekyll/commands/serve/servlet.rb
new file mode 100644
index 00000000..bb4afe5a
--- /dev/null
+++ b/lib/jekyll/commands/serve/servlet.rb
@@ -0,0 +1,61 @@
+require "webrick"
+
+module Jekyll
+ module Commands
+ class Serve
+ class Servlet < WEBrick::HTTPServlet::FileHandler
+ DEFAULTS = {
+ "Cache-Control" => "private, max-age=0, proxy-revalidate, " \
+ "no-store, no-cache, must-revalidate"
+ }
+
+ def initialize(server, root, callbacks)
+ # So we can access them easily.
+ @jekyll_opts = server.config[:JekyllOptions]
+ set_defaults
+ super
+ end
+
+ # Add the ability to tap file.html the same way that Nginx does on our
+ # Docker images (or on GitHub Pages.) The difference is that we might end
+ # up with a different preference on which comes first.
+
+ def search_file(req, res, basename)
+ # /file.* > /file/index.html > /file.html
+ super || super(req, res, "#{basename}.html")
+ end
+
+ #
+
+ def do_GET(req, res)
+ rtn = super
+ validate_and_ensure_charset(req, res)
+ res.header.merge!(@headers)
+ rtn
+ end
+
+ #
+
+ private
+ def validate_and_ensure_charset(_req, res)
+ key = res.header.keys.grep(/content-type/i).first
+ typ = res.header[key]
+
+ unless typ =~ /;\s*charset=/
+ res.header[key] = "#{typ}; charset=#{@jekyll_opts["encoding"]}"
+ end
+ end
+
+ #
+
+ private
+ def set_defaults
+ hash_ = @jekyll_opts.fetch("webrick", {}).fetch("headers", {})
+ DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash|
+ hash[key] = val unless hash.key?(key)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/configuration.rb b/lib/jekyll/configuration.rb
index 35b10503..cf499aa2 100644
--- a/lib/jekyll/configuration.rb
+++ b/lib/jekyll/configuration.rb
@@ -2,31 +2,30 @@
module Jekyll
class Configuration < Hash
-
# Default options. Overridden by values in _config.yml.
# Strings rather than symbols are used for compatibility with YAML.
- DEFAULTS = {
+ DEFAULTS = Configuration[{
# Where things are
'source' => Dir.pwd,
'destination' => File.join(Dir.pwd, '_site'),
- 'plugins' => '_plugins',
- 'layouts' => '_layouts',
- 'data_source' => '_data',
- 'collections' => nil,
+ 'plugins_dir' => '_plugins',
+ 'layouts_dir' => '_layouts',
+ 'data_dir' => '_data',
+ 'includes_dir' => '_includes',
+ 'collections' => {},
# Handling Reading
'safe' => false,
'include' => ['.htaccess'],
'exclude' => [],
- 'keep_files' => ['.git','.svn'],
+ 'keep_files' => ['.git', '.svn'],
'encoding' => 'utf-8',
'markdown_ext' => 'markdown,mkdown,mkdn,mkd,md',
- 'full_rebuild' => false,
# Filtering Content
'show_drafts' => nil,
'limit_posts' => 0,
- 'future' => true, # remove and make true just default
+ 'future' => false,
'unpublished' => false,
# Plugins
@@ -38,12 +37,14 @@ module Jekyll
'highlighter' => 'rouge',
'lsi' => false,
'excerpt_separator' => "\n\n",
+ 'incremental' => false,
# Serving
'detach' => false, # default to not detaching the server
'port' => '4000',
'host' => '127.0.0.1',
'baseurl' => '',
+ 'show_dir_listing' => false,
# Output Configuration
'permalink' => 'date',
@@ -64,28 +65,20 @@ module Jekyll
'kramdown' => {
'auto_ids' => true,
- 'footnote_nr' => 1,
- 'entity_output' => 'as_char',
'toc_levels' => '1..6',
+ 'entity_output' => 'as_char',
'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
- 'enable_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'
- }
+ 'input' => "GFM",
+ 'hard_wrap' => false,
+ 'footnote_nr' => 1
}
- }
+ }]
# 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) }
+ reduce({}) { |hsh, (k, v)| hsh.merge(k.to_s => v) }
end
def get_config_value_with_override(config_key, override)
@@ -117,7 +110,7 @@ module Jekyll
Jekyll::External.require_with_graceful_fail('toml') unless defined?(TOML)
TOML.load_file(filename)
when /\.ya?ml/i
- SafeYAML.load_file(filename)
+ SafeYAML.load_file(filename) || {}
else
raise ArgumentError, "No parser for '#{filename}' is available. Use a .toml or .y(a)ml file instead."
end
@@ -135,7 +128,7 @@ module Jekyll
# Get configuration from /_config.yml or /
config_files = override.delete('config')
if config_files.to_s.empty?
- default = %w[yml yaml].find(Proc.new { 'yml' }) do |ext|
+ default = %w(yml yaml).find(-> { 'yml' }) do |ext|
File.exist?(Jekyll.sanitized_path(source(override), "_config.#{ext}"))
end
config_files = Jekyll.sanitized_path(source(override), "_config.#{default}")
@@ -152,7 +145,7 @@ module Jekyll
# 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)
+ check_config_is_hash!(next_config, file)
Jekyll.logger.info "Configuration file:", file
next_config
rescue SystemCallError
@@ -180,12 +173,12 @@ module Jekyll
configuration = Utils.deep_merge_hashes(configuration, new_config)
end
rescue ArgumentError => err
- Jekyll.logger.warn "WARNING:", "Error reading configuration. " +
+ Jekyll.logger.warn "WARNING:", "Error reading configuration. " \
"Using defaults (and options)."
$stderr.puts "#{err}"
end
- configuration.fix_common_issues.backwards_compatibilize
+ configuration.fix_common_issues.backwards_compatibilize.add_default_collections
end
# Public: Split a CSV string into an array containing its values
@@ -205,44 +198,41 @@ module Jekyll
config = clone
# Provide backwards-compatibility
if config.key?('auto') || config.key?('watch')
- Jekyll::Deprecator.deprecation_message "Auto-regeneration can no longer" +
- " be set from your configuration file(s). Use the"+
+ Jekyll::Deprecator.deprecation_message "Auto-regeneration can no longer" \
+ " be set from your configuration file(s). Use the"\
" --[no-]watch/-w command-line option instead."
config.delete('auto')
config.delete('watch')
end
if config.key? 'server'
- Jekyll::Deprecator.deprecation_message "The 'server' configuration option" +
- " is no longer accepted. Use the 'jekyll serve'" +
+ Jekyll::Deprecator.deprecation_message "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.key? 'server_port'
- Jekyll::Deprecator.deprecation_message "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.key?('port')
- config.delete('server_port')
- end
+ renamed_key 'server_port', 'port', config
+ renamed_key 'plugins', 'plugins_dir', config
+ renamed_key 'layouts', 'layouts_dir', config
+ renamed_key 'data_source', 'data_dir', config
if config.key? 'pygments'
- Jekyll::Deprecator.deprecation_message "The 'pygments' configuration option" +
- " has been renamed to 'highlighter'. Please update your" +
- " config file accordingly. The allowed values are 'rouge', " +
+ Jekyll::Deprecator.deprecation_message "The 'pygments' configuration option" \
+ " has been renamed to 'highlighter'. Please update your" \
+ " config file accordingly. The allowed values are 'rouge', " \
"'pygments' or null."
config['highlighter'] = 'pygments' if config['pygments']
config.delete('pygments')
end
- %w[include exclude].each do |option|
- if config.fetch(option, []).is_a?(String)
- Jekyll::Deprecator.deprecation_message "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" +
+ %w(include exclude).each do |option|
+ config[option] ||= []
+ if config[option].is_a?(String)
+ Jekyll::Deprecator.deprecation_message "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
@@ -250,16 +240,16 @@ module Jekyll
end
if (config['kramdown'] || {}).key?('use_coderay')
- Jekyll::Deprecator.deprecation_message "Please change 'use_coderay'" +
+ Jekyll::Deprecator.deprecation_message "Please change 'use_coderay'" \
" to 'enable_coderay' in your configuration file."
config['kramdown']['use_coderay'] = config['kramdown'].delete('enable_coderay')
end
if config.fetch('markdown', 'kramdown').to_s.downcase.eql?("maruku")
- Jekyll.logger.abort_with "Error:", "You're using the 'maruku' " +
- "Markdown processor, which has been removed as of 3.0.0. " +
- "We recommend you switch to Kramdown. To do this, replace " +
- "`markdown: maruku` with `markdown: kramdown` in your " +
+ Jekyll.logger.abort_with "Error:", "You're using the 'maruku' " \
+ "Markdown processor, which has been removed as of 3.0.0. " \
+ "We recommend you switch to Kramdown. To do this, replace " \
+ "`markdown: maruku` with `markdown: kramdown` in your " \
"`_config.yml` file."
end
@@ -270,12 +260,65 @@ module Jekyll
config = clone
if config.key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
- Jekyll.logger.warn "Config Warning:", "The `paginate` key must be a" +
+ 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
+
+ def add_default_collections
+ config = clone
+
+ return config if config['collections'].nil?
+
+ if config['collections'].is_a?(Array)
+ config['collections'] = Hash[config['collections'].map { |c| [c, {}] }]
+ end
+ config['collections']['posts'] ||= {}
+ config['collections']['posts']['output'] = true
+ config['collections']['posts']['permalink'] = style_to_permalink(config['permalink'])
+
+ config
+ end
+
+ def renamed_key(old, new, config, _ = nil)
+ if config.key?(old)
+ Jekyll::Deprecator.deprecation_message "The '#{old}' configuration" \
+ "option has been renamed to '#{new}'. Please update your config " \
+ "file accordingly."
+ config[new] = config.delete(old)
+ end
+ end
+
+ private
+
+ def style_to_permalink(permalink_style)
+ case permalink_style.to_sym
+ when :pretty
+ "/:categories/:year/:month/:day/:title/"
+ when :none
+ "/:categories/:title:output_ext"
+ when :date
+ "/:categories/:year/:month/:day/:title:output_ext"
+ when :ordinal
+ "/:categories/:year/:y_day/:title:output_ext"
+ else
+ permalink_style.to_s
+ end
+ end
+
+ # Private: Checks if a given config is a hash
+ #
+ # extracted_config - the value to check
+ # file - the file from which the config was extracted
+ #
+ # Raises an ArgumentError if given config is not a hash
+ def check_config_is_hash!(extracted_config, file)
+ unless extracted_config.is_a?(Hash)
+ raise ArgumentError.new("Configuration file: (INVALID) #{file}".yellow)
+ end
+ end
end
end
diff --git a/lib/jekyll/converters/identity.rb b/lib/jekyll/converters/identity.rb
index 69171b00..9574769d 100644
--- a/lib/jekyll/converters/identity.rb
+++ b/lib/jekyll/converters/identity.rb
@@ -5,7 +5,7 @@ module Jekyll
priority :lowest
- def matches(ext)
+ def matches(_ext)
true
end
diff --git a/lib/jekyll/converters/markdown.rb b/lib/jekyll/converters/markdown.rb
index 30c7ef36..aed906d7 100644
--- a/lib/jekyll/converters/markdown.rb
+++ b/lib/jekyll/converters/markdown.rb
@@ -1,57 +1,62 @@
module Jekyll
module Converters
class Markdown < Converter
- safe true
-
highlighter_prefix "\n"
highlighter_suffix "\n"
+ safe true
def setup
return if @setup
- @parser =
- case @config['markdown'].downcase
- when 'redcarpet' then RedcarpetParser.new(@config)
- when 'kramdown' then KramdownParser.new(@config)
- when 'rdiscount' then RDiscountParser.new(@config)
- else
- # So they can't try some tricky bullshit or go down the ancestor chain, I hope.
- if allowed_custom_class?(@config['markdown'])
- self.class.const_get(@config['markdown']).new(@config)
- else
- Jekyll.logger.error "Invalid Markdown Processor:", "#{@config['markdown']}"
- Jekyll.logger.error "", "Valid options are [ #{valid_processors.join(" | ")} ]"
- raise Errors::FatalException, "Invalid Markdown Processor: #{@config['markdown']}"
- end
- end
+ unless (@parser = get_processor)
+ Jekyll.logger.error "Invalid Markdown processor given:", @config["markdown"]
+ Jekyll.logger.info "", "Custom processors are not loaded in safe mode" if @config["safe"]
+ Jekyll.logger.error "", "Available processors are: #{valid_processors.join(", ")}"
+ raise Errors::FatalException, "Bailing out; invalid Markdown processor."
+ end
+
@setup = true
end
- def valid_processors
- %w[
- rdiscount
- kramdown
- redcarpet
- ] + third_party_processors
+ def get_processor
+ case @config["markdown"].downcase
+ when "redcarpet" then return RedcarpetParser.new(@config)
+ when "kramdown" then return KramdownParser.new(@config)
+ when "rdiscount" then return RDiscountParser.new(@config)
+ else
+ get_custom_processor
+ end
end
+ # Public: Provides you with a list of processors, the ones we
+ # support internally and the ones that you have provided to us (if you
+ # are not in safe mode.)
+
+ def valid_processors
+ %W(rdiscount kramdown redcarpet) + third_party_processors
+ end
+
+ # Public: A list of processors that you provide via plugins.
+ # This is really only available if you are not in safe mode, if you are
+ # in safe mode (re: GitHub) then there will be none.
+
def third_party_processors
- self.class.constants - %w[
- KramdownParser
- RDiscountParser
- RedcarpetParser
- PRIORITIES
- ].map(&:to_sym)
+ self.class.constants - \
+ %w(KramdownParser RDiscountParser RedcarpetParser PRIORITIES).map(
+ &:to_sym
+ )
end
def extname_list
- @extname_list ||= @config['markdown_ext'].split(',').map { |e| ".#{e.downcase}" }
+ @extname_list ||= @config['markdown_ext'].split(',').map do |e|
+ ".#{e.downcase}"
+ end
end
def matches(ext)
- extname_list.include? ext.downcase
+ extname_list.include?(ext.downcase)
end
- def output_ext(ext)
+ def output_ext(_ext)
".html"
end
@@ -61,16 +66,26 @@ module Jekyll
end
private
+ def get_custom_processor
+ converter_name = @config["markdown"]
+ if custom_class_allowed?(converter_name)
+ self.class.const_get(converter_name).new(@config)
+ end
+ end
- # Private: Determine whether a class name is an allowed custom markdown
- # class name
+ # Private: Determine whether a class name is an allowed custom
+ # markdown class name.
#
# parser_name - the name of the parser class
#
- # Returns true if the parser name contains only alphanumeric characters
- # and is defined within Jekyll::Converters::Markdown
- def allowed_custom_class?(parser_name)
- parser_name !~ /[^A-Za-z0-9]/ && self.class.constants.include?(parser_name.to_sym)
+ # Returns true if the parser name contains only alphanumeric
+ # characters and is defined within Jekyll::Converters::Markdown
+
+ private
+ def custom_class_allowed?(parser_name)
+ parser_name !~ /[^A-Za-z0-9_]/ && self.class.constants.include?(
+ parser_name.to_sym
+ )
end
end
end
diff --git a/lib/jekyll/converters/markdown/kramdown_parser.rb b/lib/jekyll/converters/markdown/kramdown_parser.rb
index a9dbec96..93605cdd 100644
--- a/lib/jekyll/converters/markdown/kramdown_parser.rb
+++ b/lib/jekyll/converters/markdown/kramdown_parser.rb
@@ -1,28 +1,116 @@
+# Frozen-string-literal: true
+# Encoding: utf-8
+
module Jekyll
module Converters
class Markdown
class KramdownParser
+ CODERAY_DEFAULTS = {
+ "css" => "style",
+ "bold_every" => 10,
+ "line_numbers" => "inline",
+ "line_number_start" => 1,
+ "tab_width" => 4,
+ "wrap" => "div"
+ }.freeze
+
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 Errors::FatalException.new("Missing dependency: kramdown")
+ Jekyll::External.require_with_graceful_fail "kramdown"
+ @main_fallback_highlighter = config["highlighter"] || "rouge"
+ @config = config["kramdown"] || {}
+ setup
+ end
+
+ # Setup and normalize the configuration:
+ # * Create Kramdown if it doesn't exist.
+ # * Set syntax_highlighter, detecting enable_coderay and merging highlighter if none.
+ # * Merge kramdown[coderay] into syntax_highlighter_opts stripping coderay_.
+ # * Make sure `syntax_highlighter_opts` exists.
+
+ def setup
+ @config["syntax_highlighter"] ||= highlighter
+ @config["syntax_highlighter_opts"] ||= {}
+ @config["coderay"] ||= {} # XXX: Legacy.
+ modernize_coderay_config
+ make_accessible
end
def convert(content)
- # Check for use of coderay
- if @config['kramdown']['enable_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'].key?(key)
- end
- end
-
- Kramdown::Document.new(content, Utils.symbolize_hash_keys(@config['kramdown'])).to_html
+ Kramdown::Document.new(content, @config).to_html
end
+ private
+ def make_accessible(hash = @config)
+ proc_ = proc { |hash_, key| hash_[key.to_s] if key.is_a?(Symbol) }
+ hash.default_proc = proc_
+
+ hash.each do |_, val|
+ make_accessible val if val.is_a?(
+ Hash
+ )
+ end
+ end
+
+ # config[kramdown][syntax_higlighter] > config[kramdown][enable_coderay] > config[highlighter]
+ # Where `enable_coderay` is now deprecated because Kramdown
+ # supports Rouge now too.
+
+ private
+ def highlighter
+ return @highlighter if @highlighter
+
+ if @config["syntax_highlighter"]
+ return @highlighter = @config[
+ "syntax_highlighter"
+ ]
+ end
+
+ @highlighter = begin
+ if @config.key?("enable_coderay") && @config["enable_coderay"]
+ Jekyll::Deprecator.deprecation_message "You are using 'enable_coderay', " \
+ "use syntax_highlighter: coderay in your configuration file."
+
+ "coderay"
+ else
+ @main_fallback_highlighter
+ end
+ end
+ end
+
+ private
+ def strip_coderay_prefix(hash)
+ hash.each_with_object({}) do |(key, val), hsh|
+ cleaned_key = key.gsub(/\Acoderay_/, "")
+
+ if key != cleaned_key
+ Jekyll::Deprecator.deprecation_message(
+ "You are using '#{key}'. Normalizing to #{cleaned_key}."
+ )
+ end
+
+ hsh[cleaned_key] = val
+ end
+ end
+
+ # If our highlighter is CodeRay we go in to merge the CodeRay defaults
+ # with your "coderay" key if it's there, deprecating it in the
+ # process of you using it.
+
+ private
+ def modernize_coderay_config
+ if highlighter == "coderay"
+ Jekyll::Deprecator.deprecation_message "You are using 'kramdown.coderay' in your configuration, " \
+ "please use 'syntax_highlighter_opts' instead."
+
+ @config["syntax_highlighter_opts"] = begin
+ strip_coderay_prefix(
+ @config["syntax_highlighter_opts"] \
+ .merge(CODERAY_DEFAULTS) \
+ .merge(@config["coderay"])
+ )
+ end
+ end
+ end
end
end
end
diff --git a/lib/jekyll/converters/markdown/rdiscount_parser.rb b/lib/jekyll/converters/markdown/rdiscount_parser.rb
index fb5172e7..daf8874e 100644
--- a/lib/jekyll/converters/markdown/rdiscount_parser.rb
+++ b/lib/jekyll/converters/markdown/rdiscount_parser.rb
@@ -5,7 +5,7 @@ module Jekyll
def initialize(config)
Jekyll::External.require_with_graceful_fail "rdiscount"
@config = config
- @rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym }
+ @rdiscount_extensions = @config['rdiscount']['extensions'].map(&:to_sym)
end
def convert(content)
diff --git a/lib/jekyll/converters/markdown/redcarpet_parser.rb b/lib/jekyll/converters/markdown/redcarpet_parser.rb
index 8ddf2292..79133a2a 100644
--- a/lib/jekyll/converters/markdown/redcarpet_parser.rb
+++ b/lib/jekyll/converters/markdown/redcarpet_parser.rb
@@ -2,12 +2,12 @@ module Jekyll
module Converters
class Markdown
class RedcarpetParser
-
module CommonMethods
def add_code_tags(code, lang)
code = code.to_s
code = code.sub(/
/, "
")
- code = code.sub(/<\/pre>/,"
")
+ code = code.sub(/<\/pre>/, "
")
+ code
end
end
@@ -48,12 +48,11 @@ module Jekyll
end
protected
- def rouge_formatter(lexer)
+ def rouge_formatter(_lexer)
Rouge::Formatters::HTML.new(:wrap => false)
end
end
-
def initialize(config)
External.require_with_graceful_fail("redcarpet")
@config = config
@@ -71,12 +70,12 @@ module Jekyll
end
when "rouge"
Class.new(Redcarpet::Render::HTML) do
- Jekyll::External.require_with_graceful_fail(%w[
+ Jekyll::External.require_with_graceful_fail(%w(
rouge
rouge/plugins/redcarpet
- ])
+ ))
- if Rouge.version < '1.3.0'
+ unless Gem::Version.new(Rouge.version) > Gem::Version.new("1.3.0")
abort "Please install Rouge 1.3.0 or greater and try running Jekyll again."
end
diff --git a/lib/jekyll/converters/smartypants.rb b/lib/jekyll/converters/smartypants.rb
new file mode 100644
index 00000000..d1bc8103
--- /dev/null
+++ b/lib/jekyll/converters/smartypants.rb
@@ -0,0 +1,34 @@
+class Kramdown::Parser::SmartyPants < Kramdown::Parser::Kramdown
+ def initialize(source, options)
+ super
+ @block_parsers = [:block_html]
+ @span_parsers = [:smart_quotes, :html_entity, :typographic_syms, :span_html]
+ end
+end
+
+module Jekyll
+ module Converters
+ class SmartyPants < Converter
+ safe true
+ priority :low
+
+ def initialize(config)
+ Jekyll::External.require_with_graceful_fail "kramdown"
+ @config = config["kramdown"].dup || {}
+ @config[:input] = :SmartyPants
+ end
+
+ def matches(_)
+ false
+ end
+
+ def output_ext(_)
+ nil
+ end
+
+ def convert(content)
+ Kramdown::Document.new(content, @config).to_html.chomp
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb
index 0cf8e1c1..f58796f0 100644
--- a/lib/jekyll/convertible.rb
+++ b/lib/jekyll/convertible.rb
@@ -28,12 +28,6 @@ module Jekyll
!(data.key?('published') && data['published'] == false)
end
- # Returns merged option hash for File.read of self.site (if exists)
- # and a given param
- def merged_file_read_opts(opts)
- (site ? site.file_read_opts : {}).merge(opts)
- end
-
# Read the YAML frontmatter.
#
# base - The String path to the dir containing the file.
@@ -42,28 +36,41 @@ module Jekyll
#
# Returns nothing.
def read_yaml(base, name, opts = {})
+ filename = File.join(base, name)
+
begin
self.content = File.read(site.in_source_dir(base, name),
- merged_file_read_opts(opts))
+ Utils.merged_file_read_opts(site, opts))
if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
self.content = $POSTMATCH
- self.data = SafeYAML.load($1)
+ self.data = SafeYAML.load(Regexp.last_match(1))
end
rescue SyntaxError => e
- Jekyll.logger.warn "YAML Exception reading #{File.join(base, name)}: #{e.message}"
+ Jekyll.logger.warn "YAML Exception reading #{filename}: #{e.message}"
rescue Exception => e
- Jekyll.logger.warn "Error reading file #{File.join(base, name)}: #{e.message}"
+ Jekyll.logger.warn "Error reading file #{filename}: #{e.message}"
end
self.data ||= {}
- unless self.data.is_a?(Hash)
- Jekyll.logger.abort_with "Fatal:", "Invalid YAML front matter in #{File.join(base, name)}"
- end
+ validate_data! filename
+ validate_permalink! filename
self.data
end
+ def validate_data!(filename)
+ unless self.data.is_a?(Hash)
+ raise Errors::InvalidYAMLFrontMatterError, "Invalid YAML front matter in #{filename}"
+ end
+ end
+
+ def validate_permalink!(filename)
+ if self.data['permalink'] && self.data['permalink'].size == 0
+ raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
+ end
+ end
+
# Transform the contents based on the content type.
#
# Returns the transformed contents.
@@ -84,13 +91,7 @@ module Jekyll
# Returns the String extension for the output file.
# e.g. ".html" for an HTML output file.
def output_ext
- if converters.all? { |c| c.is_a?(Jekyll::Converters::Identity) }
- ext
- else
- converters.map { |c|
- c.output_ext(ext) unless c.is_a?(Jekyll::Converters::Identity)
- }.compact.last
- end
+ Jekyll::Renderer.new(site, self).output_ext
end
# Determine which converter to use based on this convertible's
@@ -109,7 +110,7 @@ module Jekyll
#
# Returns the converted content
def render_liquid(content, payload, info, path)
- site.liquid_renderer.file(path).parse(content).render(payload, info)
+ site.liquid_renderer.file(path).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
@@ -122,9 +123,9 @@ module Jekyll
#
# Returns the Hash representation of this Convertible.
def to_liquid(attrs = nil)
- further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map { |attribute|
+ further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map do |attribute|
[attribute, send(attribute)]
- }]
+ end]
defaults = site.frontmatter_defaults.all(relative_path, type)
Utils.deep_merge_hashes defaults, Utils.deep_merge_hashes(data, further_data)
@@ -135,11 +136,14 @@ module Jekyll
#
# Returns the type of self.
def type
- if is_a?(Draft)
- :drafts
- elsif is_a?(Post)
- :posts
- elsif is_a?(Page)
+ if is_a?(Page)
+ :pages
+ end
+ end
+
+ # returns the owner symbol for hook triggering
+ def hook_owner
+ if is_a?(Page)
:pages
end
end
@@ -157,7 +161,7 @@ module Jekyll
#
# Returns true if extname == .sass or .scss, false otherwise.
def sass_file?
- %w[.sass .scss].include?(ext)
+ %w(.sass .scss).include?(ext)
end
# Determine whether the document is a CoffeeScript file.
@@ -206,12 +210,14 @@ module Jekyll
used = Set.new([layout])
while layout
- payload = Utils.deep_merge_hashes(payload, {"content" => output, "page" => layout.data})
+ Jekyll.logger.debug "Rendering Layout:", path
+ payload["content"] = output
+ payload["layout"] = Utils.deep_merge_hashes(payload["layout"] || {}, layout.data)
self.output = render_liquid(layout.content,
payload,
info,
- File.join(site.config['layouts'], layout.name))
+ File.join(site.config['layouts_dir'], layout.name))
# Add layout to dependency tree
site.regenerator.add_dependency(
@@ -231,26 +237,34 @@ module Jekyll
# Add any necessary layouts to this convertible document.
#
- # payload - The site payload Hash.
+ # payload - The site payload Drop or Hash.
# layouts - A Hash of {"name" => "layout"}.
#
# Returns nothing.
def do_layout(payload, layouts)
- Jekyll::Hooks.trigger self, :pre_render, payload
- info = { :filters => [Jekyll::Filters], :registers => { :site => site, :page => payload['page'] } }
+ Jekyll.logger.debug "Rendering:", self.relative_path
+
+ Jekyll.logger.debug "Pre-Render Hooks:", self.relative_path
+ Jekyll::Hooks.trigger hook_owner, :pre_render, self, payload
+ info = { :filters => [Jekyll::Filters], :registers => { :site => site, :page => payload["page"] } }
# render and transform content (this becomes the final content of the object)
payload["highlighter_prefix"] = converters.first.highlighter_prefix
payload["highlighter_suffix"] = converters.first.highlighter_suffix
- self.content = render_liquid(content, payload, info, path) if render_with_liquid?
+ if render_with_liquid?
+ Jekyll.logger.debug "Rendering Liquid:", self.relative_path
+ self.content = render_liquid(content, payload, info, path)
+ end
+ Jekyll.logger.debug "Rendering Markup:", self.relative_path
self.content = transform
# output keeps track of what will finally be written
self.output = content
render_all_layouts(layouts, payload, info) if place_in_layout?
- Jekyll::Hooks.trigger self, :post_render
+ Jekyll.logger.debug "Post-Render Hooks:", self.relative_path
+ Jekyll::Hooks.trigger hook_owner, :post_render, self
end
# Write the generated page file to the destination directory.
@@ -264,7 +278,7 @@ module Jekyll
File.open(path, 'wb') do |f|
f.write(output)
end
- Jekyll::Hooks.trigger self, :post_write
+ Jekyll::Hooks.trigger hook_owner, :post_write, self
end
# Accessor for data properties by Liquid.
diff --git a/lib/jekyll/deprecator.rb b/lib/jekyll/deprecator.rb
index dfd3183c..21449400 100644
--- a/lib/jekyll/deprecator.rb
+++ b/lib/jekyll/deprecator.rb
@@ -3,9 +3,10 @@ module Jekyll
extend self
def process(args)
- no_subcommand(args)
arg_is_present? args, "--server", "The --server command has been replaced by the \
'serve' subcommand."
+ arg_is_present? args, "--serve", "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'."
@@ -16,12 +17,13 @@ module Jekyll
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."
+ no_subcommand(args)
end
def no_subcommand(args)
- if args.size > 0 && args.first =~ /^--/ && !%w[--help --version].include?(args.first)
- deprecation_message "Jekyll now uses subcommands instead of just \
- switches. Run `jekyll --help` to find out more."
+ if args.size > 0 && args.first =~ /^--/ && !%w(--help --version).include?(args.first)
+ deprecation_message "Jekyll now uses subcommands instead of just switches. Run `jekyll help` to find out more."
+ abort
end
end
diff --git a/lib/jekyll/document.rb b/lib/jekyll/document.rb
index 045bdacb..6768fcf6 100644
--- a/lib/jekyll/document.rb
+++ b/lib/jekyll/document.rb
@@ -4,33 +4,39 @@ module Jekyll
class Document
include Comparable
- attr_reader :path, :site, :extname, :output_ext, :content, :output, :collection
+ attr_reader :path, :site, :extname, :collection
+ attr_accessor :content, :output
YAML_FRONT_MATTER_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
+ DATELESS_FILENAME_MATCHER = /^(.+\/)*(.*)(\.[^.]+)$/
+ DATE_FILENAME_MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
# Create a new Document.
#
- # site - the Jekyll::Site instance to which this Document belongs
# path - the path to the file
+ # relations - a hash with keys :site and :collection, the values of which
+ # are the Jekyll::Site and Jekyll::Collection to which this
+ # Document belong.
#
# Returns nothing.
- def initialize(path, relations)
+ def initialize(path, relations = {})
@site = relations[:site]
@path = path
@extname = File.extname(path)
- @output_ext = Jekyll::Renderer.new(site, self).output_ext
@collection = relations[:collection]
@has_yaml_header = nil
- end
- def output=(output)
- @to_liquid = nil
- @output = output
- end
+ if draft?
+ categories_from_path("_drafts")
+ else
+ categories_from_path(collection.relative_directory)
+ end
- def content=(content)
- @to_liquid = nil
- @content = content
+ data.default_proc = proc do |_, key|
+ site.frontmatter_defaults.find(relative_path, collection.label, key)
+ end
+
+ trigger_hooks(:post_init)
end
# Fetch the Document's data.
@@ -38,7 +44,44 @@ module Jekyll
# Returns a Hash containing the data. An empty hash is returned if
# no data was read.
def data
- @data ||= Hash.new
+ @data ||= {}
+ end
+
+ # Merge some data in with this document's data.
+ #
+ # Returns the merged data.
+ def merge_data!(other, source: "YAML front matter")
+ if other.key?('categories') && !other['categories'].nil?
+ if other['categories'].is_a?(String)
+ other['categories'] = other['categories'].split(" ").map(&:strip)
+ end
+ other['categories'] = (data['categories'] || []) | other['categories']
+ end
+ Utils.deep_merge_hashes!(data, other)
+ if data.key?('date') && !data['date'].is_a?(Time)
+ data['date'] = Utils.parse_date(
+ data['date'].to_s,
+ "Document '#{relative_path}' does not have a valid date in the #{source}."
+ )
+ end
+ data
+ end
+
+ def date
+ data['date'] ||= (draft? ? source_file_mtime : site.time)
+ end
+
+ def source_file_mtime
+ @source_file_mtime ||= File.mtime(path)
+ end
+
+ # Returns whether the document is a draft. This is only the case if
+ # the document is in the 'posts' collection but in a different
+ # directory than '_posts'.
+ #
+ # Returns whether the document is a draft.
+ def draft?
+ data['draft'] ||= relative_path.index(collection.relative_directory).nil? && collection.label == "posts"
end
# The path to the document, relative to the site source.
@@ -49,6 +92,13 @@ module Jekyll
@relative_path ||= Pathname.new(path).relative_path_from(Pathname.new(site.source)).to_s
end
+ # The output extension of the document.
+ #
+ # Returns the output extension
+ def output_ext
+ Jekyll::Renderer.new(site, self).output_ext
+ end
+
# The base filename of the document, without the file extname.
#
# Returns the basename without the file extname.
@@ -76,14 +126,14 @@ module Jekyll
# Returns the cleaned relative path of the document.
def cleaned_relative_path
@cleaned_relative_path ||=
- relative_path[0 .. -extname.length - 1].sub(collection.relative_directory, "")
+ relative_path[0..-extname.length - 1].sub(collection.relative_directory, "")
end
# Determine whether the document is a YAML file.
#
# Returns true if the extname is either .yml or .yaml, false otherwise.
def yaml_file?
- %w[.yaml .yml].include?(extname)
+ %w(.yaml .yml).include?(extname)
end
# Determine whether the document is an asset file.
@@ -99,7 +149,7 @@ module Jekyll
#
# Returns true if extname == .sass or .scss, false otherwise.
def sass_file?
- %w[.sass .scss].include?(extname)
+ %w(.sass .scss).include?(extname)
end
# Determine whether the document is a CoffeeScript file.
@@ -137,13 +187,7 @@ module Jekyll
#
# Returns the Hash of key-value pairs for replacement in the URL.
def url_placeholders
- {
- collection: collection.label,
- path: cleaned_relative_path,
- output_ext: output_ext,
- name: Utils.slugify(basename_without_ext),
- title: Utils.slugify(data['slug']) || Utils.slugify(basename_without_ext)
- }
+ @url_placeholders ||= Drops::UrlDrop.new(self)
end
# The permalink for this Document.
@@ -159,12 +203,16 @@ module Jekyll
# Returns the computed URL for the document.
def url
@url = URL.new({
- template: url_template,
- placeholders: url_placeholders,
- permalink: permalink
+ :template => url_template,
+ :placeholders => url_placeholders,
+ :permalink => permalink
}).to_s
end
+ def [](key)
+ data[key]
+ end
+
# The full path to the output file.
#
# base_directory - the base path of the output directory
@@ -173,8 +221,11 @@ module Jekyll
def destination(base_directory)
dest = site.in_dest_dir(base_directory)
path = site.in_dest_dir(dest, URL.unescape_path(url))
- path = File.join(path, "index.html") if url.end_with?("/")
- path << output_ext unless path.end_with?(output_ext)
+ if url.end_with? "/"
+ path = File.join(path, "index.html")
+ else
+ path << output_ext unless path.end_with? output_ext
+ end
path
end
@@ -190,17 +241,7 @@ module Jekyll
f.write(output)
end
- Jekyll::Hooks.trigger self, :post_write
- end
-
- # Returns merged option hash for File.read of self.site (if exists)
- # and a given param
- #
- # opts - override options
- #
- # Return the file read options hash.
- def merged_file_read_opts(opts)
- site ? site.file_read_opts.merge(opts) : opts
+ trigger_hooks(:post_write)
end
# Whether the file is published or not, as indicated in YAML front-matter
@@ -216,48 +257,86 @@ module Jekyll
#
# Returns nothing.
def read(opts = {})
- @to_liquid = nil
+ Jekyll.logger.debug "Reading:", relative_path
if yaml_file?
@data = SafeYAML.load_file(path)
else
begin
defaults = @site.frontmatter_defaults.all(url, collection.label.to_sym)
- unless defaults.empty?
- @data = defaults
- end
- self.content = File.read(path, merged_file_read_opts(opts))
+ merge_data!(defaults, source: "front matter defaults") unless defaults.empty?
+
+ self.content = File.read(path, Utils.merged_file_read_opts(site, opts))
if content =~ YAML_FRONT_MATTER_REGEXP
self.content = $POSTMATCH
- data_file = SafeYAML.load($1)
- unless data_file.nil?
- @data = Utils.deep_merge_hashes(defaults, data_file)
- end
+ data_file = SafeYAML.load(Regexp.last_match(1))
+ merge_data!(data_file, source: "YAML front matter") if data_file
end
+
+ post_read
rescue SyntaxError => e
- puts "YAML Exception reading #{path}: #{e.message}"
+ Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{e.message}"
rescue Exception => e
- puts "Error reading file #{path}: #{e.message}"
+ if e.is_a? Jekyll::Errors::FatalException
+ raise e
+ end
+ Jekyll.logger.error "Error:", "could not read file #{path}: #{e.message}"
end
end
end
+ def post_read
+ if relative_path =~ DATE_FILENAME_MATCHER
+ date, slug, ext = $2, $3, $4
+ if !data['date'] || data['date'].to_i == site.time.to_i
+ merge_data!({"date" => date}, source: "filename")
+ end
+ elsif relative_path =~ DATELESS_FILENAME_MATCHER
+ slug, ext = $2, $3
+ end
+
+ # Try to ensure the user gets a title.
+ data["title"] ||= Utils.titleize_slug(slug)
+ # Only overwrite slug & ext if they aren't specified.
+ data['slug'] ||= slug
+ data['ext'] ||= ext
+
+ populate_categories
+ populate_tags
+ generate_excerpt
+ end
+
+ # Add superdirectories of the special_dir to categories.
+ # In the case of es/_posts, 'es' is added as a category.
+ # In the case of _posts/es, 'es' is NOT added as a category.
+ #
+ # Returns nothing.
+ def categories_from_path(special_dir)
+ superdirs = relative_path.sub(/#{special_dir}(.*)/, '').split(File::SEPARATOR).reject do |c|
+ c.empty? || c.eql?(special_dir) || c.eql?(basename)
+ end
+ merge_data!({ 'categories' => superdirs }, source: "file path")
+ end
+
+ def populate_categories
+ merge_data!({
+ 'categories' => (
+ Array(data['categories']) + Utils.pluralized_array_from_hash(data, 'category', 'categories')
+ ).map(&:to_s).flatten.uniq
+ })
+ end
+
+ def populate_tags
+ merge_data!({
+ "tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
+ })
+ end
+
# Create a Liquid-understandable version of this Document.
#
# Returns a Hash representing this Document's data.
def to_liquid
- @to_liquid ||= if data.is_a?(Hash)
- Utils.deep_merge_hashes data, {
- "output" => output,
- "content" => content,
- "relative_path" => relative_path,
- "path" => relative_path,
- "url" => url,
- "collection" => collection.label
- }
- else
- data
- end
+ @to_liquid ||= Drops::DocumentDrop.new(self)
end
# The inspect string for this document.
@@ -272,7 +351,7 @@ module Jekyll
#
# Returns the content of the document
def to_s
- content || ''
+ output || content || 'NO CONTENT'
end
# Compare this document against another document.
@@ -280,8 +359,11 @@ module Jekyll
#
# Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
# equal or greater than the other doc's path. See String#<=> for more details.
- def <=>(anotherDocument)
- path <=> anotherDocument.path
+ def <=>(other)
+ return nil unless other.respond_to?(:data)
+ cmp = data['date'] <=> other.data['date']
+ cmp = path <=> other.path if cmp.nil? || cmp == 0
+ cmp
end
# Determine whether this document should be written.
@@ -292,5 +374,78 @@ module Jekyll
def write?
collection && collection.write?
end
+
+ # The Document excerpt_separator, from the YAML Front-Matter or site
+ # default excerpt_separator value
+ #
+ # Returns the document excerpt_separator
+ def excerpt_separator
+ (data['excerpt_separator'] || site.config['excerpt_separator']).to_s
+ end
+
+ # Whether to generate an excerpt
+ #
+ # Returns true if the excerpt separator is configured.
+ def generate_excerpt?
+ !excerpt_separator.empty?
+ end
+
+ def next_doc
+ pos = collection.docs.index { |post| post.equal?(self) }
+ if pos && pos < collection.docs.length - 1
+ collection.docs[pos + 1]
+ else
+ nil
+ end
+ end
+
+ def previous_doc
+ pos = collection.docs.index { |post| post.equal?(self) }
+ if pos && pos > 0
+ collection.docs[pos - 1]
+ else
+ nil
+ end
+ end
+
+ def trigger_hooks(hook_name, *args)
+ Jekyll::Hooks.trigger collection.label.to_sym, hook_name, self, *args if collection
+ Jekyll::Hooks.trigger :documents, hook_name, self, *args
+ end
+
+ def id
+ @id ||= File.join(File.dirname(url), (data['slug'] || basename_without_ext).to_s)
+ end
+
+ # Calculate related posts.
+ #
+ # Returns an Array of related Posts.
+ def related_posts
+ Jekyll::RelatedPosts.new(self).build
+ end
+
+ # Override of normal respond_to? to match method_missing's logic for
+ # looking in @data.
+ def respond_to?(method, include_private = false)
+ data.key?(method.to_s) || super
+ end
+
+ # Override of method_missing to check in @data for the key.
+ def method_missing(method, *args, &blck)
+ if data.key?(method.to_s)
+ Jekyll.logger.warn "Deprecation:", "Document##{method} is now a key in the #data hash."
+ Jekyll.logger.warn "", "Called by #{caller.first}."
+ data[method.to_s]
+ else
+ super
+ end
+ end
+
+ private # :nodoc:
+ def generate_excerpt
+ if generate_excerpt?
+ data["excerpt"] ||= Jekyll::Excerpt.new(self)
+ end
+ end
end
end
diff --git a/lib/jekyll/draft.rb b/lib/jekyll/draft.rb
deleted file mode 100644
index 16daefdf..00000000
--- a/lib/jekyll/draft.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-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(dir)
- site.in_source_dir(dir, '_drafts')
- end
-
- # The path to the draft source file, relative to the site source
- def relative_path
- File.join(@dir, '_drafts', @name)
- 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/drops/collection_drop.rb b/lib/jekyll/drops/collection_drop.rb
new file mode 100644
index 00000000..5f5025b1
--- /dev/null
+++ b/lib/jekyll/drops/collection_drop.rb
@@ -0,0 +1,22 @@
+# encoding: UTF-8
+
+module Jekyll
+ module Drops
+ class CollectionDrop < Drop
+ extend Forwardable
+
+ mutable false
+
+ def_delegator :@obj, :write?, :output
+ def_delegators :@obj, :label, :docs, :files, :directory,
+ :relative_directory
+
+ def to_s
+ docs.to_s
+ end
+
+ private
+ def_delegator :@obj, :metadata, :fallback_data
+ end
+ end
+end
diff --git a/lib/jekyll/drops/document_drop.rb b/lib/jekyll/drops/document_drop.rb
new file mode 100644
index 00000000..69933752
--- /dev/null
+++ b/lib/jekyll/drops/document_drop.rb
@@ -0,0 +1,27 @@
+# encoding: UTF-8
+
+module Jekyll
+ module Drops
+ class DocumentDrop < Drop
+ extend Forwardable
+
+ mutable false
+
+ def_delegator :@obj, :next_doc, :next
+ def_delegator :@obj, :previous_doc, :previous
+ def_delegator :@obj, :relative_path, :path
+ def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url
+
+ def collection
+ @obj.collection.label
+ end
+
+ def excerpt
+ fallback_data['excerpt'].to_s
+ end
+
+ private
+ def_delegator :@obj, :data, :fallback_data
+ end
+ end
+end
diff --git a/lib/jekyll/drops/drop.rb b/lib/jekyll/drops/drop.rb
new file mode 100644
index 00000000..d1bffcc5
--- /dev/null
+++ b/lib/jekyll/drops/drop.rb
@@ -0,0 +1,176 @@
+# encoding: UTF-8
+
+module Jekyll
+ module Drops
+ class Drop < Liquid::Drop
+ NON_CONTENT_METHODS = [:[], :[]=, :inspect, :to_h, :fallback_data].freeze
+
+ # Get or set whether the drop class is mutable.
+ # Mutability determines whether or not pre-defined fields may be
+ # overwritten.
+ #
+ # is_mutable - Boolean set mutability of the class (default: nil)
+ #
+ # Returns the mutability of the class
+ def self.mutable(is_mutable = nil)
+ if is_mutable
+ @is_mutable = is_mutable
+ else
+ @is_mutable = false
+ end
+ end
+
+ def self.mutable?
+ @is_mutable
+ end
+
+ # Create a new Drop
+ #
+ # obj - the Jekyll Site, Collection, or Document required by the
+ # drop.
+ #
+ # Returns nothing
+ def initialize(obj)
+ @obj = obj
+ @mutations = {} # only if mutable: true
+ end
+
+ # Access a method in the Drop or a field in the underlying hash data.
+ # If mutable, checks the mutations first. Then checks the methods,
+ # and finally check the underlying hash (e.g. document front matter)
+ # if all the previous places didn't match.
+ #
+ # key - the string key whose value to fetch
+ #
+ # Returns the value for the given key, or nil if none exists
+ def [](key)
+ if self.class.mutable? && @mutations.key?(key)
+ @mutations[key]
+ elsif self.class.invokable? key
+ public_send key
+ else
+ fallback_data[key]
+ end
+ end
+
+ # Set a field in the Drop. If mutable, sets in the mutations and
+ # returns. If not mutable, checks first if it's trying to override a
+ # Drop method and raises a DropMutationException if so. If not
+ # mutable and the key is not a method on the Drop, then it sets the
+ # key to the value in the underlying hash (e.g. document front
+ # matter)
+ #
+ # key - the String key whose value to set
+ # val - the Object to set the key's value to
+ #
+ # Returns the value the key was set to unless the Drop is not mutable
+ # and the key matches a method in which case it raises a
+ # DropMutationException.
+ def []=(key, val)
+ if respond_to?("#{key}=")
+ public_send("#{key}=", val)
+ elsif respond_to? key
+ if self.class.mutable?
+ @mutations[key] = val
+ else
+ raise Errors::DropMutationException, "Key #{key} cannot be set in the drop."
+ end
+ else
+ fallback_data[key] = val
+ end
+ end
+
+ # Generates a list of strings which correspond to content getter
+ # methods.
+ #
+ # Returns an Array of strings which represent method-specific keys.
+ def content_methods
+ @content_methods ||= (
+ self.class.instance_methods(false) - NON_CONTENT_METHODS
+ ).map(&:to_s).reject do |method|
+ method.end_with?("=")
+ end
+ end
+
+ # Check if key exists in Drop
+ #
+ # key - the string key whose value to fetch
+ #
+ # Returns true if the given key is present
+ def key?(key)
+ if self.class.mutable && @mutations.key?(key)
+ true
+ else
+ respond_to?(key) || fallback_data.key?(key)
+ end
+ end
+
+ # Generates a list of keys with user content as their values.
+ # This gathers up the Drop methods and keys of the mutations and
+ # underlying data hashes and performs a set union to ensure a list
+ # of unique keys for the Drop.
+ #
+ # Returns an Array of unique keys for content for the Drop.
+ def keys
+ (content_methods |
+ @mutations.keys |
+ fallback_data.keys).flatten
+ end
+
+ # Generate a Hash representation of the Drop by resolving each key's
+ # value. It includes Drop methods, mutations, and the underlying object's
+ # data. See the documentation for Drop#keys for more.
+ #
+ # Returns a Hash with all the keys and values resolved.
+ def to_h
+ keys.each_with_object({}) do |(key, _), result|
+ result[key] = self[key]
+ end
+ end
+ alias_method :to_hash, :to_h
+
+ # Inspect the drop's keys and values through a JSON representation
+ # of its keys and values.
+ #
+ # Returns a pretty generation of the hash representation of the Drop.
+ def inspect
+ require 'json'
+ JSON.pretty_generate to_h
+ end
+
+ # Collects all the keys and passes each to the block in turn.
+ #
+ # block - a block which accepts one argument, the key
+ #
+ # Returns nothing.
+ def each_key(&block)
+ keys.each(&block)
+ end
+
+ def merge(other, &block)
+ self.dup.tap do |me|
+ if block.nil?
+ me.merge!(other)
+ else
+ me.merge!(other, block)
+ end
+ end
+ end
+
+ def merge!(other)
+ other.each_key do |key|
+ if block_given?
+ self[key] = yield key, self[key], other[key]
+ else
+ if Utils.mergable?(self[key]) && Utils.mergable?(other[key])
+ self[key] = Utils.deep_merge_hashes(self[key], other[key])
+ next
+ end
+
+ self[key] = other[key] unless other[key].nil?
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/drops/jekyll_drop.rb b/lib/jekyll/drops/jekyll_drop.rb
new file mode 100644
index 00000000..c4009da0
--- /dev/null
+++ b/lib/jekyll/drops/jekyll_drop.rb
@@ -0,0 +1,21 @@
+# encoding: UTF-8
+
+module Jekyll
+ module Drops
+ class JekyllDrop < Liquid::Drop
+ class << self
+ def global
+ @global ||= JekyllDrop.new
+ end
+ end
+
+ def version
+ Jekyll::VERSION
+ end
+
+ def environment
+ Jekyll.env
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/drops/site_drop.rb b/lib/jekyll/drops/site_drop.rb
new file mode 100644
index 00000000..4d07ebe8
--- /dev/null
+++ b/lib/jekyll/drops/site_drop.rb
@@ -0,0 +1,38 @@
+# encoding: UTF-8
+
+module Jekyll
+ module Drops
+ class SiteDrop < Drop
+ extend Forwardable
+
+ mutable false
+
+ def_delegator :@obj, :site_data, :data
+ def_delegators :@obj, :time, :pages, :static_files, :documents,
+ :tags, :categories
+
+ def [](key)
+ if @obj.collections.key?(key) && key != "posts"
+ @obj.collections[key].docs
+ else
+ super(key)
+ end
+ end
+
+ def posts
+ @site_posts ||= @obj.posts.docs.sort { |a, b| b <=> a }
+ end
+
+ def html_pages
+ @site_html_pages ||= @obj.pages.select { |page| page.html? || page.url.end_with?("/") }
+ end
+
+ def collections
+ @site_collections ||= @obj.collections.values.map(&:to_liquid)
+ end
+
+ private
+ def_delegator :@obj, :config, :fallback_data
+ end
+ end
+end
diff --git a/lib/jekyll/drops/unified_payload_drop.rb b/lib/jekyll/drops/unified_payload_drop.rb
new file mode 100644
index 00000000..b642bda2
--- /dev/null
+++ b/lib/jekyll/drops/unified_payload_drop.rb
@@ -0,0 +1,25 @@
+# encoding: UTF-8
+
+module Jekyll
+ module Drops
+ class UnifiedPayloadDrop < Drop
+ mutable true
+
+ attr_accessor :page, :layout, :content, :paginator
+ attr_accessor :highlighter_prefix, :highlighter_suffix
+
+ def jekyll
+ JekyllDrop.global
+ end
+
+ def site
+ @site_drop ||= SiteDrop.new(@obj)
+ end
+
+ private
+ def fallback_data
+ @fallback_data ||= {}
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/drops/url_drop.rb b/lib/jekyll/drops/url_drop.rb
new file mode 100644
index 00000000..2815edf7
--- /dev/null
+++ b/lib/jekyll/drops/url_drop.rb
@@ -0,0 +1,83 @@
+# encoding: UTF-8
+
+module Jekyll
+ module Drops
+ class UrlDrop < Drop
+ extend Forwardable
+
+ mutable false
+
+ def_delegator :@obj, :cleaned_relative_path, :path
+ def_delegator :@obj, :output_ext, :output_ext
+
+ def collection
+ @obj.collection.label
+ end
+
+ def name
+ Utils.slugify(@obj.basename_without_ext)
+ end
+
+ def title
+ Utils.slugify(@obj.data['slug'], :mode => "pretty", :cased => true) ||
+ Utils.slugify(@obj.basename_without_ext, :mode => "pretty", :cased => true)
+ end
+
+ def slug
+ Utils.slugify(@obj.data['slug']) || Utils.slugify(@obj.basename_without_ext)
+ end
+
+ def categories
+ category_set = Set.new
+ Array(@obj.data['categories']).each do |category|
+ category_set << category.to_s.downcase
+ end
+ category_set.to_a.join('/')
+ end
+
+ def year
+ @obj.date.strftime("%Y")
+ end
+
+ def month
+ @obj.date.strftime("%m")
+ end
+
+ def day
+ @obj.date.strftime("%d")
+ end
+
+ def hour
+ @obj.date.strftime("%H")
+ end
+
+ def minute
+ @obj.date.strftime("%M")
+ end
+
+ def second
+ @obj.date.strftime("%S")
+ end
+
+ def i_day
+ @obj.date.strftime("%-d")
+ end
+
+ def i_month
+ @obj.date.strftime("%-m")
+ end
+
+ def short_month
+ @obj.date.strftime("%b")
+ end
+
+ def short_year
+ @obj.date.strftime("%y")
+ end
+
+ def y_day
+ @obj.date.strftime("%j")
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/entry_filter.rb b/lib/jekyll/entry_filter.rb
index e4270187..48509f9d 100644
--- a/lib/jekyll/entry_filter.rb
+++ b/lib/jekyll/entry_filter.rb
@@ -1,6 +1,6 @@
module Jekyll
class EntryFilter
- SPECIAL_LEADING_CHARACTERS = ['.', '_', '#'].freeze
+ SPECIAL_LEADING_CHARACTERS = ['.', '_', '#', '~'].freeze
attr_reader :site
@@ -47,7 +47,7 @@ module Jekyll
def excluded?(entry)
excluded = glob_include?(site.exclude, relative_to_source(entry))
- Jekyll.logger.debug "EntryFilter:", "excluded?(#{relative_to_source(entry)}) ==> #{excluded}"
+ Jekyll.logger.debug "EntryFilter:", "excluded #{relative_to_source(entry)}" if excluded
excluded
end
diff --git a/lib/jekyll/errors.rb b/lib/jekyll/errors.rb
index dc5238a0..322eb6af 100644
--- a/lib/jekyll/errors.rb
+++ b/lib/jekyll/errors.rb
@@ -1,9 +1,14 @@
module Jekyll
module Errors
- class FatalException < RuntimeError
- end
+ FatalException = Class.new(::RuntimeError)
- class MissingDependencyException < FatalException
- end
+ DropMutationException = Class.new(FatalException)
+ InvalidPermalinkError = Class.new(FatalException)
+ InvalidYAMLFrontMatterError = Class.new(FatalException)
+ MissingDependencyException = Class.new(FatalException)
+
+ InvalidDateError = Class.new(FatalException)
+ InvalidPostNameError = Class.new(FatalException)
+ PostURLError = Class.new(FatalException)
end
end
diff --git a/lib/jekyll/excerpt.rb b/lib/jekyll/excerpt.rb
index 347be217..f5884d68 100644
--- a/lib/jekyll/excerpt.rb
+++ b/lib/jekyll/excerpt.rb
@@ -1,47 +1,42 @@
-require 'forwardable'
-
module Jekyll
class Excerpt
- include Convertible
extend Forwardable
- attr_accessor :post
- attr_accessor :content, :output, :ext
+ attr_accessor :doc
+ attr_accessor :content, :ext
+ attr_writer :output
- def_delegator :@post, :site, :site
- def_delegator :@post, :name, :name
- def_delegator :@post, :ext, :ext
+ def_delegators :@doc, :site, :name, :ext, :relative_path, :extname,
+ :render_with_liquid?, :collection, :related_posts
- # Initialize this Post instance.
+ # Initialize this Excerpt instance.
#
- # site - The Site.
- # base - The String path to the dir containing the post file.
- # name - The String filename of the post file.
+ # doc - The Document.
#
- # Returns the new Post.
- def initialize(post)
- self.post = post
- self.content = extract_excerpt(post.content)
+ # Returns the new Excerpt.
+ def initialize(doc)
+ self.doc = doc
+ self.content = extract_excerpt(doc.content)
end
- def to_liquid
- post.to_liquid(post.class::EXCERPT_ATTRIBUTES_FOR_LIQUID)
- end
-
- # Fetch YAML front-matter data from related post, without layout key
+ # Fetch YAML front-matter data from related doc, without layout key
#
- # Returns Hash of post data
+ # Returns Hash of doc data
def data
- @data ||= post.data.dup
+ @data ||= doc.data.dup
@data.delete("layout")
+ @data.delete("excerpt")
@data
end
+ def trigger_hooks(*)
+ end
+
# 'Path' of the excerpt.
#
- # Returns the path for the post this excerpt belongs to with #excerpt appended
+ # Returns the path for the doc this excerpt belongs to with #excerpt appended
def path
- File.join(post.path, "#excerpt")
+ File.join(doc.path, "#excerpt")
end
# Check if excerpt includes a string
@@ -51,28 +46,43 @@ module Jekyll
(output && output.include?(something)) || content.include?(something)
end
- # The UID for this post (useful in feeds).
- # e.g. /2008/11/05/my-awesome-post
+ # The UID for this doc (useful in feeds).
+ # e.g. /2008/11/05/my-awesome-doc
#
# Returns the String UID.
def id
- File.join(post.dir, post.slug, "#excerpt")
+ "#{doc.id}#excerpt"
end
def to_s
output || content
end
- # Returns the shorthand String identifier of this Post.
+ def to_liquid
+ doc.data['excerpt'] = nil
+ @to_liquid ||= doc.to_liquid
+ doc.data['excerpt'] = self
+ @to_liquid
+ end
+
+ # Returns the shorthand String identifier of this doc.
def inspect
""
end
+ def output
+ @output ||= Renderer.new(doc.site, self, site.site_payload).run
+ end
+
+ def place_in_layout?
+ false
+ end
+
protected
# Internal: Extract excerpt from the content
#
- # By default excerpt is your first paragraph of a post: everything before
+ # By default excerpt is your first paragraph of a doc: everything before
# the first two new lines:
#
# ---
@@ -86,16 +96,16 @@ module Jekyll
# [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
+ # problems for HTML docs (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:
+ # alternative for HTML docs:
#
# # file: _config.yml
# excerpt_separator: ""
#
# Notice that all markdown-style link references will be appended to the
- # excerpt. So the example post above will have this excerpt source:
+ # excerpt. So the example doc above will have this excerpt source:
#
# First paragraph with [link][1].
#
@@ -104,10 +114,14 @@ module Jekyll
# Excerpts are rendered same time as content is rendered.
#
# Returns excerpt String
- def extract_excerpt(post_content)
- head, _, tail = post_content.to_s.partition(post.excerpt_separator)
+ def extract_excerpt(doc_content)
+ head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)
- "" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
+ if tail.empty?
+ head
+ else
+ "" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
+ end
end
end
end
diff --git a/lib/jekyll/external.rb b/lib/jekyll/external.rb
index e41bce27..69b8d1eb 100644
--- a/lib/jekyll/external.rb
+++ b/lib/jekyll/external.rb
@@ -1,16 +1,15 @@
module Jekyll
module External
class << self
-
#
# Gems that, if installed, should be loaded.
# Usually contain subcommands.
#
def blessed_gems
- %w{
+ %w(
jekyll-docs
jekyll-import
- }
+ )
end
#
@@ -18,12 +17,13 @@ module Jekyll
#
# names - a string gem name or array of gem names
#
- def require_if_present(names)
+ def require_if_present(names, &block)
Array(names).each do |name|
begin
require name
rescue LoadError
Jekyll.logger.debug "Couldn't load #{name}. Skipping."
+ block.call(name) if block
false
end
end
@@ -39,6 +39,7 @@ module Jekyll
def require_with_graceful_fail(names)
Array(names).each do |name|
begin
+ Jekyll.logger.debug "Requiring:", "#{name}"
require name
rescue LoadError => e
Jekyll.logger.error "Dependency Error:", <<-MSG
@@ -53,7 +54,6 @@ If you run into trouble, you can find helpful resources at http://jekyllrb.com/h
end
end
end
-
end
end
end
diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb
index 12d4eb5a..02523d9c 100644
--- a/lib/jekyll/filters.rb
+++ b/lib/jekyll/filters.rb
@@ -15,6 +15,17 @@ module Jekyll
converter.convert(input)
end
+ # Convert quotes into smart quotes.
+ #
+ # input - The String to convert.
+ #
+ # Returns the smart-quotified String.
+ def smartify(input)
+ site = @context.registers[:site]
+ converter = site.find_converter_instance(Jekyll::Converters::SmartyPants)
+ converter.convert(input)
+ end
+
# Convert a Sass string into CSS output.
#
# input - The Sass String to convert.
@@ -45,7 +56,7 @@ module Jekyll
# Returns the given filename or title as a lowercase URL String.
# See Utils.slugify for more detail.
def slugify(input, mode=nil)
- Utils.slugify(input, mode)
+ Utils.slugify(input, :mode => mode)
end
# Format a date in short format e.g. "27 Jan 2011".
@@ -106,7 +117,7 @@ module Jekyll
#
# Returns the escaped String.
def xml_escape(input)
- CGI.escapeHTML(input.to_s)
+ input.to_s.encode(:xml => :attr).gsub(/\A"|"\Z/, "")
end
# CGI escape a string for use in a URL. Replaces any special characters
@@ -194,7 +205,7 @@ module Jekyll
input.group_by do |item|
item_property(item, property).to_s
end.inject([]) do |memo, i|
- memo << {"name" => i.first, "items" => i.last}
+ memo << { "name" => i.first, "items" => i.last, "size" => i.last.size }
end
else
input
@@ -211,7 +222,7 @@ module Jekyll
def where(input, property, value)
return input unless input.is_a?(Enumerable)
input = input.values if input.is_a?(Hash)
- input.select { |object| item_property(object, property) == value }
+ input.select { |object| Array(item_property(object, property)).map(&:to_s).include?(value.to_s) }
end
# Sort an array of objects
@@ -223,7 +234,7 @@ module Jekyll
# Returns the filtered array of objects
def sort(input, property = nil, nils = "first")
if input.nil?
- raise ArgumentError.new("Cannot sort a null object.")
+ raise ArgumentError.new("Cannot sort a null object.")
end
if property.nil?
input.sort
@@ -234,11 +245,11 @@ module Jekyll
when nils == "last"
order = + 1
else
- raise ArgumentError.new("Invalid nils order: " +
+ raise ArgumentError.new("Invalid nils order: " \
"'#{nils}' is not a valid nils order. It must be 'first' or 'last'.")
end
- input.sort { |apple, orange|
+ input.sort do |apple, orange|
apple_property = item_property(apple, property)
orange_property = item_property(orange, property)
@@ -249,7 +260,7 @@ module Jekyll
else
apple_property <=> orange_property
end
- }
+ end
end
end
@@ -281,20 +292,30 @@ module Jekyll
new_ary
end
+ def sample(input, num = 1)
+ return input unless input.respond_to?(:sample)
+ n = num.to_i rescue 1
+ if n == 1
+ input.sample
+ else
+ input.sample(n)
+ end
+ end
+
# Convert an object into its String representation for debugging
#
# input - The Object to be converted
#
# Returns a String representation of the object.
def inspect(input)
- CGI.escapeHTML(input.inspect)
+ xml_escape(input.inspect)
end
private
def time(input)
case input
when Time
- input
+ input.clone
when Date
input.to_time
when String
@@ -327,7 +348,7 @@ module Jekyll
pairs = item.map { |k, v| as_liquid([k, v]) }
Hash[pairs]
when Array
- item.map{ |i| as_liquid(i) }
+ item.map { |i| as_liquid(i) }
else
if item.respond_to?(:to_liquid)
liquidated = item.to_liquid
diff --git a/lib/jekyll/frontmatter_defaults.rb b/lib/jekyll/frontmatter_defaults.rb
index 160e6bec..877f517e 100644
--- a/lib/jekyll/frontmatter_defaults.rb
+++ b/lib/jekyll/frontmatter_defaults.rb
@@ -13,23 +13,31 @@ module Jekyll
def update_deprecated_types(set)
return set unless set.key?('scope') && set['scope'].key?('type')
- set['scope']['type'] = case set['scope']['type']
- when 'page'
- Deprecator.defaults_deprecate_type('page', 'pages')
- 'pages'
- when 'post'
- Deprecator.defaults_deprecate_type('post', 'posts')
- 'posts'
- when 'draft'
- Deprecator.defaults_deprecate_type('draft', 'drafts')
- 'drafts'
- else
- set['scope']['type']
- end
+ set['scope']['type'] =
+ case set['scope']['type']
+ when 'page'
+ Deprecator.defaults_deprecate_type('page', 'pages')
+ 'pages'
+ when 'post'
+ Deprecator.defaults_deprecate_type('post', 'posts')
+ 'posts'
+ when 'draft'
+ Deprecator.defaults_deprecate_type('draft', 'drafts')
+ 'drafts'
+ else
+ set['scope']['type']
+ end
set
end
+ def ensure_time!(set)
+ return set unless set.key?('values') && set['values'].key?('date')
+ return set if set['values']['date'].is_a?(Time)
+ set['values']['date'] = Utils.parse_date(set['values']['date'], "An invalid date format was found in a front-matter default set: #{set}")
+ set
+ end
+
# Finds a default value for a given setting, filtered by path and type
#
# path - the path (relative to the source) of the page, post or :draft the default is used in
@@ -83,11 +91,11 @@ module Jekyll
end
def applies_path?(scope, path)
- return true if !scope.has_key?('path') || scope['path'].empty?
+ return true if !scope.key?('path') || scope['path'].empty?
scope_path = Pathname.new(scope['path'])
Pathname.new(sanitize_path(path)).ascend do |path|
- if path == scope_path
+ if path.to_s == scope_path.to_s
return true
end
end
@@ -143,7 +151,7 @@ module Jekyll
# Returns an array of hashes
def matching_sets(path, type)
valid_sets.select do |set|
- !set.has_key?('scope') || applies?(set['scope'], path, type)
+ !set.key?('scope') || applies?(set['scope'], path, type)
end
end
@@ -159,7 +167,7 @@ module Jekyll
sets.map do |set|
if valid?(set)
- update_deprecated_types(set)
+ ensure_time!(update_deprecated_types(set))
else
Jekyll.logger.warn "Defaults:", "An invalid front-matter default set was found:"
Jekyll.logger.warn "#{set}"
diff --git a/lib/jekyll/generator.rb b/lib/jekyll/generator.rb
index 57973a74..bf7c0f19 100644
--- a/lib/jekyll/generator.rb
+++ b/lib/jekyll/generator.rb
@@ -1,4 +1,3 @@
module Jekyll
- class Generator < Plugin
- end
+ Generator = Class.new(Plugin)
end
diff --git a/lib/jekyll/hooks.rb b/lib/jekyll/hooks.rb
index d01cae4c..869bcc1f 100644
--- a/lib/jekyll/hooks.rb
+++ b/lib/jekyll/hooks.rb
@@ -1,47 +1,41 @@
module Jekyll
module Hooks
- # Helps look up hooks from the registry by owner's class
- OWNER_MAP = {
- Jekyll::Site => :site,
- Jekyll::Page => :page,
- Jekyll::Post => :post,
- Jekyll::Document => :document,
- }.freeze
-
DEFAULT_PRIORITY = 20
# compatibility layer for octopress-hooks users
PRIORITY_MAP = {
- low: 10,
- normal: 20,
- high: 30,
+ :low => 10,
+ :normal => 20,
+ :high => 30
}.freeze
# initial empty hooks
@registry = {
:site => {
- after_reset: [],
- post_read: [],
- pre_render: [],
- post_write: [],
+ :after_reset => [],
+ :post_read => [],
+ :pre_render => [],
+ :post_render => [],
+ :post_write => []
},
- :page => {
- post_init: [],
- pre_render: [],
- post_render: [],
- post_write: [],
+ :pages => {
+ :post_init => [],
+ :pre_render => [],
+ :post_render => [],
+ :post_write => []
},
- :post => {
- post_init: [],
- pre_render: [],
- post_render: [],
- post_write: [],
- },
- :document => {
- pre_render: [],
- post_render: [],
- post_write: [],
+ :posts => {
+ :post_init => [],
+ :pre_render => [],
+ :post_render => [],
+ :post_write => []
},
+ :documents => {
+ :post_init => [],
+ :pre_render => [],
+ :post_render => [],
+ :post_write => []
+ }
}
# map of all hooks and their priorities
@@ -65,13 +59,15 @@ module Jekyll
# register a single hook to be called later, internal API
def self.register_one(owner, event, priority, &block)
- unless @registry[owner]
- raise NotAvailable, "Hooks are only available for the following " <<
- "classes: #{@registry.keys.inspect}"
- end
+ @registry[owner] ||={
+ :post_init => [],
+ :pre_render => [],
+ :post_render => [],
+ :post_write => []
+ }
unless @registry[owner][event]
- raise NotAvailable, "Invalid hook. #{owner} supports only the " <<
+ raise NotAvailable, "Invalid hook. #{owner} supports only the " \
"following hooks #{@registry[owner].keys.inspect}"
end
@@ -88,19 +84,17 @@ module Jekyll
end
# interface for Jekyll core components to trigger hooks
- def self.trigger(instance, event, *args)
- owner_symbol = OWNER_MAP[instance.class]
-
+ def self.trigger(owner, event, *args)
# proceed only if there are hooks to call
- return unless @registry[owner_symbol]
- return unless @registry[owner_symbol][event]
+ return unless @registry[owner]
+ return unless @registry[owner][event]
# hooks to call for this owner and event
- hooks = @registry[owner_symbol][event]
+ hooks = @registry[owner][event]
# sort and call hooks according to priority and load order
hooks.sort_by { |h| @hook_priority[h] }.each do |hook|
- hook.call(instance, *args)
+ hook.call(*args)
end
end
end
diff --git a/lib/jekyll/liquid_renderer.rb b/lib/jekyll/liquid_renderer.rb
index 0edeb44b..70f7b0d1 100644
--- a/lib/jekyll/liquid_renderer.rb
+++ b/lib/jekyll/liquid_renderer.rb
@@ -15,7 +15,7 @@ module Jekyll
def file(filename)
filename = @site.in_source_dir(filename).sub(/\A#{Regexp.escape(@site.source)}\//, '')
- LiquidRenderer::File.new(self, filename).tap do |file|
+ LiquidRenderer::File.new(self, filename).tap do
@stats[filename] ||= {}
@stats[filename][:count] ||= 0
@stats[filename][:count] += 1
diff --git a/lib/jekyll/liquid_renderer/file.rb b/lib/jekyll/liquid_renderer/file.rb
index f91a5a2c..7dcca1b6 100644
--- a/lib/jekyll/liquid_renderer/file.rb
+++ b/lib/jekyll/liquid_renderer/file.rb
@@ -8,7 +8,7 @@ module Jekyll
def parse(content)
measure_time do
- @template = Liquid::Template.parse(content)
+ @template = Liquid::Template.parse(content, line_numbers: true)
end
self
diff --git a/lib/jekyll/liquid_renderer/table.rb b/lib/jekyll/liquid_renderer/table.rb
index 32b09cb3..e3e0c8af 100644
--- a/lib/jekyll/liquid_renderer/table.rb
+++ b/lib/jekyll/liquid_renderer/table.rb
@@ -69,10 +69,10 @@ module Jekyll
end
def data_for_table(n)
- sorted = @stats.sort_by{ |filename, file_stats| -file_stats[:time] }
+ sorted = @stats.sort_by { |_, file_stats| -file_stats[:time] }
sorted = sorted.slice(0, n)
- table = [[ 'Filename', 'Count', 'Bytes', 'Time' ]]
+ table = [%w(Filename Count Bytes Time)]
sorted.each do |filename, file_stats|
row = []
diff --git a/lib/jekyll/mime.types b/lib/jekyll/mime.types
index 4e33d137..15828b91 100644
--- a/lib/jekyll/mime.types
+++ b/lib/jekyll/mime.types
@@ -1,96 +1,800 @@
-# These are the same MIME types that GitHub Pages uses as of 26 January 2014
+# Woah there. Do not edit this file directly.
+# This file is generated automatically by script/vendor-mimes.
-text/html;charset=utf-8 html htm shtml
-text/css css
-text/xml;charset=utf-8 xml rss xsl xsd
-image/gif gif
-image/jpeg jpeg jpg
-application/x-javascript js
-application/atom+xml atom
-application/json json geojson topojson
-
-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
-text/vcard vcf vcard
-
-image/png png
-image/svg+xml svg
-image/svg+xml svgz
-image/tiff tif tiff
-image/vnd.wap.wbmp wbmp
-image/x-icon ico
-image/x-jng jng
-image/x-ms-bmp bmp
-
-application/vnd.ms-fontobject eot
-application/x-font-ttf ttf
-application/x-font-woff woff
-application/font-woff2 woff2
-font/opentype otf
-
-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
-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-cocoa cco
-application/x-chrome-extension crx
-application/x-java-archive-diff jardiff
-application/x-java-jnlp-file jnlp
-application/x-makeself run
-application/x-ms-application application
-application/x-ms-manifest manifest
-application/x-ms-vsto vsto
-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 deploy
-application/octet-stream dmg
-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/m4v m4v
-video/mp4 mp4
-video/mpeg mpeg mpg
-video/ogg ogg ogv
-video/quicktime mov
-video/webm webm
-video/x-flv flv
-video/x-mng mng
-video/x-ms-asf asx asf
-video/x-ms-wmv wmv
-video/x-msvideo avi
+application/andrew-inset ez
+application/applixware aw
+application/atom+xml atom
+application/atomcat+xml atomcat
+application/atomsvc+xml atomsvc
+application/bdoc bdoc
+application/ccxml+xml ccxml
+application/cdmi-capability cdmia
+application/cdmi-container cdmic
+application/cdmi-domain cdmid
+application/cdmi-object cdmio
+application/cdmi-queue cdmiq
+application/cu-seeme cu
+application/dash+xml mdp
+application/davmount+xml davmount
+application/docbook+xml dbk
+application/dssc+der dssc
+application/dssc+xml xdssc
+application/ecmascript ecma
+application/emma+xml emma
+application/epub+zip epub
+application/exi exi
+application/font-tdpfr pfr
+application/font-woff woff
+application/font-woff2 woff2
+application/gml+xml gml
+application/gpx+xml gpx
+application/gxf gxf
+application/hyperstudio stk
+application/inkml+xml ink inkml
+application/ipfix ipfix
+application/java-archive jar war ear
+application/java-serialized-object ser
+application/java-vm class
+application/javascript js
+application/json json map
+application/json5 json5
+application/jsonml+json jsonml
+application/ld+json jsonld
+application/lost+xml lostxml
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/mads+xml mads
+application/manifest+json webmanifest
+application/marc mrc
+application/marcxml+xml mrcx
+application/mathematica ma nb mb
+application/mathml+xml mathml
+application/mbox mbox
+application/mediaservercontrol+xml mscml
+application/metalink+xml metalink
+application/metalink4+xml meta4
+application/mets+xml mets
+application/mods+xml mods
+application/mp21 m21 mp21
+application/mp4 mp4s m4p
+application/msword doc dot
+application/mxf mxf
+application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy exe dll deb dmg iso img msi msp msm buffer
+application/oda oda
+application/oebps-package+xml opf
+application/ogg ogx
+application/omdoc+xml omdoc
+application/onenote onetoc onetoc2 onetmp onepkg
+application/oxps oxps
+application/patch-ops-error+xml xer
+application/pdf pdf
+application/pgp-encrypted pgp
+application/pgp-signature asc sig
+application/pics-rules prf
+application/pkcs10 p10
+application/pkcs7-mime p7m p7c
+application/pkcs7-signature p7s
+application/pkcs8 p8
+application/pkix-attr-cert ac
+application/pkix-cert cer
+application/pkix-crl crl
+application/pkix-pkipath pkipath
+application/pkixcmp pki
+application/pls+xml pls
+application/postscript ai eps ps
+application/prs.cww cww
+application/pskc+xml pskcxml
+application/rdf+xml rdf
+application/reginfo+xml rif
+application/relax-ng-compact-syntax rnc
+application/resource-lists+xml rl
+application/resource-lists-diff+xml rld
+application/rls-services+xml rs
+application/rpki-ghostbusters gbr
+application/rpki-manifest mft
+application/rpki-roa roa
+application/rsd+xml rsd
+application/rss+xml rss
+application/rtf rtf
+application/sbml+xml sbml
+application/scvp-cv-request scq
+application/scvp-cv-response scs
+application/scvp-vp-request spq
+application/scvp-vp-response spp
+application/sdp sdp
+application/set-payment-initiation setpay
+application/set-registration-initiation setreg
+application/shf+xml shf
+application/smil+xml smi smil
+application/sparql-query rq
+application/sparql-results+xml srx
+application/srgs gram
+application/srgs+xml grxml
+application/sru+xml sru
+application/ssdl+xml ssdl
+application/ssml+xml ssml
+application/tei+xml tei teicorpus
+application/thraud+xml tfi
+application/timestamped-data tsd
+application/vnd.3gpp.pic-bw-large plb
+application/vnd.3gpp.pic-bw-small psb
+application/vnd.3gpp.pic-bw-var pvb
+application/vnd.3gpp2.tcap tcap
+application/vnd.3m.post-it-notes pwn
+application/vnd.accpac.simply.aso aso
+application/vnd.accpac.simply.imp imp
+application/vnd.acucobol acu
+application/vnd.acucorp atc acutc
+application/vnd.adobe.air-application-installer-package+zip air
+application/vnd.adobe.formscentral.fcdt fcdt
+application/vnd.adobe.fxp fxp fxpl
+application/vnd.adobe.xdp+xml xdp
+application/vnd.adobe.xfdf xfdf
+application/vnd.ahead.space ahead
+application/vnd.airzip.filesecure.azf azf
+application/vnd.airzip.filesecure.azs azs
+application/vnd.amazon.ebook azw
+application/vnd.americandynamics.acc acc
+application/vnd.amiga.ami ami
+application/vnd.android.package-archive apk
+application/vnd.anser-web-certificate-issue-initiation cii
+application/vnd.anser-web-funds-transfer-initiation fti
+application/vnd.antix.game-component atx
+application/vnd.apple.installer+xml mpkg
+application/vnd.apple.mpegurl m3u8
+application/vnd.aristanetworks.swi swi
+application/vnd.astraea-software.iota iota
+application/vnd.audiograph aep
+application/vnd.blueice.multipass mpm
+application/vnd.bmi bmi
+application/vnd.businessobjects rep
+application/vnd.chemdraw+xml cdxml
+application/vnd.chipnuts.karaoke-mmd mmd
+application/vnd.cinderella cdy
+application/vnd.claymore cla
+application/vnd.cloanto.rp9 rp9
+application/vnd.clonk.c4group c4g c4d c4f c4p c4u
+application/vnd.cluetrust.cartomobile-config c11amc
+application/vnd.cluetrust.cartomobile-config-pkg c11amz
+application/vnd.commonspace csp
+application/vnd.contact.cmsg cdbcmsg
+application/vnd.cosmocaller cmc
+application/vnd.crick.clicker clkx
+application/vnd.crick.clicker.keyboard clkk
+application/vnd.crick.clicker.palette clkp
+application/vnd.crick.clicker.template clkt
+application/vnd.crick.clicker.wordbank clkw
+application/vnd.criticaltools.wbs+xml wbs
+application/vnd.ctc-posml pml
+application/vnd.cups-ppd ppd
+application/vnd.curl.car car
+application/vnd.curl.pcurl pcurl
+application/vnd.dart dart
+application/vnd.data-vision.rdz rdz
+application/vnd.dece.data uvf uvvf uvd uvvd
+application/vnd.dece.ttml+xml uvt uvvt
+application/vnd.dece.unspecified uvx uvvx
+application/vnd.dece.zip uvz uvvz
+application/vnd.denovo.fcselayout-link fe_launch
+application/vnd.dna dna
+application/vnd.dolby.mlp mlp
+application/vnd.dpgraph dpg
+application/vnd.dreamfactory dfac
+application/vnd.ds-keypoint kpxx
+application/vnd.dvb.ait ait
+application/vnd.dvb.service svc
+application/vnd.dynageo geo
+application/vnd.ecowin.chart mag
+application/vnd.enliven nml
+application/vnd.epson.esf esf
+application/vnd.epson.msf msf
+application/vnd.epson.quickanime qam
+application/vnd.epson.salt slt
+application/vnd.epson.ssf ssf
+application/vnd.eszigno3+xml es3 et3
+application/vnd.ezpix-album ez2
+application/vnd.ezpix-package ez3
+application/vnd.fdf fdf
+application/vnd.fdsn.mseed mseed
+application/vnd.fdsn.seed seed dataless
+application/vnd.flographit gph
+application/vnd.fluxtime.clip ftc
+application/vnd.framemaker fm frame maker book
+application/vnd.frogans.fnc fnc
+application/vnd.frogans.ltf ltf
+application/vnd.fsc.weblaunch fsc
+application/vnd.fujitsu.oasys oas
+application/vnd.fujitsu.oasys2 oa2
+application/vnd.fujitsu.oasys3 oa3
+application/vnd.fujitsu.oasysgp fg5
+application/vnd.fujitsu.oasysprs bh2
+application/vnd.fujixerox.ddd ddd
+application/vnd.fujixerox.docuworks xdw
+application/vnd.fujixerox.docuworks.binder xbd
+application/vnd.fuzzysheet fzs
+application/vnd.genomatix.tuxedo txd
+application/vnd.geogebra.file ggb
+application/vnd.geogebra.tool ggt
+application/vnd.geometry-explorer gex gre
+application/vnd.geonext gxt
+application/vnd.geoplan g2w
+application/vnd.geospace g3w
+application/vnd.gmx gmx
+application/vnd.google-earth.kml+xml kml
+application/vnd.google-earth.kmz kmz
+application/vnd.grafeq gqf gqs
+application/vnd.groove-account gac
+application/vnd.groove-help ghf
+application/vnd.groove-identity-message gim
+application/vnd.groove-injector grv
+application/vnd.groove-tool-message gtm
+application/vnd.groove-tool-template tpl
+application/vnd.groove-vcard vcg
+application/vnd.hal+xml hal
+application/vnd.handheld-entertainment+xml zmm
+application/vnd.hbci hbci
+application/vnd.hhe.lesson-player les
+application/vnd.hp-hpgl hpgl
+application/vnd.hp-hpid hpid
+application/vnd.hp-hps hps
+application/vnd.hp-jlyt jlt
+application/vnd.hp-pcl pcl
+application/vnd.hp-pclxl pclxl
+application/vnd.hydrostatix.sof-data sfd-hdstx
+application/vnd.ibm.minipay mpy
+application/vnd.ibm.modcap afp listafp list3820
+application/vnd.ibm.rights-management irm
+application/vnd.ibm.secure-container sc
+application/vnd.iccprofile icc icm
+application/vnd.igloader igl
+application/vnd.immervision-ivp ivp
+application/vnd.immervision-ivu ivu
+application/vnd.insors.igm igm
+application/vnd.intercon.formnet xpw xpx
+application/vnd.intergeo i2g
+application/vnd.intu.qbo qbo
+application/vnd.intu.qfx qfx
+application/vnd.ipunplugged.rcprofile rcprofile
+application/vnd.irepository.package+xml irp
+application/vnd.is-xpr xpr
+application/vnd.isac.fcs fcs
+application/vnd.jam jam
+application/vnd.jcp.javame.midlet-rms rms
+application/vnd.jisp jisp
+application/vnd.joost.joda-archive joda
+application/vnd.kahootz ktz ktr
+application/vnd.kde.karbon karbon
+application/vnd.kde.kchart chrt
+application/vnd.kde.kformula kfo
+application/vnd.kde.kivio flw
+application/vnd.kde.kontour kon
+application/vnd.kde.kpresenter kpr kpt
+application/vnd.kde.kspread ksp
+application/vnd.kde.kword kwd kwt
+application/vnd.kenameaapp htke
+application/vnd.kidspiration kia
+application/vnd.kinar kne knp
+application/vnd.koan skp skd skt skm
+application/vnd.kodak-descriptor sse
+application/vnd.las.las+xml lasxml
+application/vnd.llamagraphics.life-balance.desktop lbd
+application/vnd.llamagraphics.life-balance.exchange+xml lbe
+application/vnd.lotus-1-2-3 123
+application/vnd.lotus-approach apr
+application/vnd.lotus-freelance pre
+application/vnd.lotus-notes nsf
+application/vnd.lotus-organizer org
+application/vnd.lotus-screencam scm
+application/vnd.lotus-wordpro lwp
+application/vnd.macports.portpkg portpkg
+application/vnd.mcd mcd
+application/vnd.medcalcdata mc1
+application/vnd.mediastation.cdkey cdkey
+application/vnd.mfer mwf
+application/vnd.mfmp mfm
+application/vnd.micrografx.flo flo
+application/vnd.micrografx.igx igx
+application/vnd.mif mif
+application/vnd.mobius.daf daf
+application/vnd.mobius.dis dis
+application/vnd.mobius.mbk mbk
+application/vnd.mobius.mqy mqy
+application/vnd.mobius.msl msl
+application/vnd.mobius.plc plc
+application/vnd.mobius.txf txf
+application/vnd.mophun.application mpn
+application/vnd.mophun.certificate mpc
+application/vnd.mozilla.xul+xml xul
+application/vnd.ms-artgalry cil
+application/vnd.ms-cab-compressed cab
+application/vnd.ms-excel xls xlm xla xlc xlt xlw
+application/vnd.ms-excel.addin.macroenabled.12 xlam
+application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb
+application/vnd.ms-excel.sheet.macroenabled.12 xlsm
+application/vnd.ms-excel.template.macroenabled.12 xltm
+application/vnd.ms-fontobject eot
+application/vnd.ms-htmlhelp chm
+application/vnd.ms-ims ims
+application/vnd.ms-lrm lrm
+application/vnd.ms-officetheme thmx
+application/vnd.ms-pki.seccat cat
+application/vnd.ms-pki.stl stl
+application/vnd.ms-powerpoint ppt pps pot
+application/vnd.ms-powerpoint.addin.macroenabled.12 ppam
+application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm
+application/vnd.ms-powerpoint.slide.macroenabled.12 sldm
+application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm
+application/vnd.ms-powerpoint.template.macroenabled.12 potm
+application/vnd.ms-project mpp mpt
+application/vnd.ms-word.document.macroenabled.12 docm
+application/vnd.ms-word.template.macroenabled.12 dotm
+application/vnd.ms-works wps wks wcm wdb
+application/vnd.ms-wpl wpl
+application/vnd.ms-xpsdocument xps
+application/vnd.mseq mseq
+application/vnd.musician mus
+application/vnd.muvee.style msty
+application/vnd.mynfc taglet
+application/vnd.neurolanguage.nlu nlu
+application/vnd.nitf ntf nitf
+application/vnd.noblenet-directory nnd
+application/vnd.noblenet-sealer nns
+application/vnd.noblenet-web nnw
+application/vnd.nokia.n-gage.data ngdat
+application/vnd.nokia.n-gage.symbian.install n-gage
+application/vnd.nokia.radio-preset rpst
+application/vnd.nokia.radio-presets rpss
+application/vnd.novadigm.edm edm
+application/vnd.novadigm.edx edx
+application/vnd.novadigm.ext ext
+application/vnd.oasis.opendocument.chart odc
+application/vnd.oasis.opendocument.chart-template otc
+application/vnd.oasis.opendocument.database odb
+application/vnd.oasis.opendocument.formula odf
+application/vnd.oasis.opendocument.formula-template odft
+application/vnd.oasis.opendocument.graphics odg
+application/vnd.oasis.opendocument.graphics-template otg
+application/vnd.oasis.opendocument.image odi
+application/vnd.oasis.opendocument.image-template oti
+application/vnd.oasis.opendocument.presentation odp
+application/vnd.oasis.opendocument.presentation-template otp
+application/vnd.oasis.opendocument.spreadsheet ods
+application/vnd.oasis.opendocument.spreadsheet-template ots
+application/vnd.oasis.opendocument.text odt
+application/vnd.oasis.opendocument.text-master odm
+application/vnd.oasis.opendocument.text-template ott
+application/vnd.oasis.opendocument.text-web oth
+application/vnd.olpc-sugar xo
+application/vnd.oma.dd2+xml dd2
+application/vnd.openofficeorg.extension oxt
+application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
+application/vnd.openxmlformats-officedocument.presentationml.slide sldx
+application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
+application/vnd.openxmlformats-officedocument.presentationml.template potx
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
+application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
+application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
+application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
+application/vnd.osgeo.mapguide.package mgp
+application/vnd.osgi.dp dp
+application/vnd.osgi.subsystem esa
+application/vnd.palm pdb pqa oprc
+application/vnd.pawaafile paw
+application/vnd.pg.format str
+application/vnd.pg.osasli ei6
+application/vnd.picsel efif
+application/vnd.pmi.widget wg
+application/vnd.pocketlearn plf
+application/vnd.powerbuilder6 pbd
+application/vnd.previewsystems.box box
+application/vnd.proteus.magazine mgz
+application/vnd.publishare-delta-tree qps
+application/vnd.pvi.ptid1 ptid
+application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
+application/vnd.realvnc.bed bed
+application/vnd.recordare.musicxml mxl
+application/vnd.recordare.musicxml+xml musicxml
+application/vnd.rig.cryptonote cryptonote
+application/vnd.rim.cod cod
+application/vnd.rn-realmedia rm
+application/vnd.rn-realmedia-vbr rmvb
+application/vnd.route66.link66+xml link66
+application/vnd.sailingtracker.track st
+application/vnd.seemail see
+application/vnd.sema sema
+application/vnd.semd semd
+application/vnd.semf semf
+application/vnd.shana.informed.formdata ifm
+application/vnd.shana.informed.formtemplate itp
+application/vnd.shana.informed.interchange iif
+application/vnd.shana.informed.package ipk
+application/vnd.simtech-mindmapper twd twds
+application/vnd.smaf mmf
+application/vnd.smart.teacher teacher
+application/vnd.solent.sdkm+xml sdkm sdkd
+application/vnd.spotfire.dxp dxp
+application/vnd.spotfire.sfs sfs
+application/vnd.stardivision.calc sdc
+application/vnd.stardivision.draw sda
+application/vnd.stardivision.impress sdd
+application/vnd.stardivision.math smf
+application/vnd.stardivision.writer sdw vor
+application/vnd.stardivision.writer-global sgl
+application/vnd.stepmania.package smzip
+application/vnd.stepmania.stepchart sm
+application/vnd.sun.xml.calc sxc
+application/vnd.sun.xml.calc.template stc
+application/vnd.sun.xml.draw sxd
+application/vnd.sun.xml.draw.template std
+application/vnd.sun.xml.impress sxi
+application/vnd.sun.xml.impress.template sti
+application/vnd.sun.xml.math sxm
+application/vnd.sun.xml.writer sxw
+application/vnd.sun.xml.writer.global sxg
+application/vnd.sun.xml.writer.template stw
+application/vnd.sus-calendar sus susp
+application/vnd.svd svd
+application/vnd.symbian.install sis sisx
+application/vnd.syncml+xml xsm
+application/vnd.syncml.dm+wbxml bdm
+application/vnd.syncml.dm+xml xdm
+application/vnd.tao.intent-module-archive tao
+application/vnd.tcpdump.pcap pcap cap dmp
+application/vnd.tmobile-livetv tmo
+application/vnd.trid.tpt tpt
+application/vnd.triscape.mxs mxs
+application/vnd.trueapp tra
+application/vnd.ufdl ufd ufdl
+application/vnd.uiq.theme utz
+application/vnd.umajin umj
+application/vnd.unity unityweb
+application/vnd.uoml+xml uoml
+application/vnd.vcx vcx
+application/vnd.visio vsd vst vss vsw
+application/vnd.visionary vis
+application/vnd.vsf vsf
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo wtb
+application/vnd.wolfram.player nbp
+application/vnd.wordperfect wpd
+application/vnd.wqd wqd
+application/vnd.wt.stf stf
+application/vnd.xara xar
+application/vnd.xfdl xfdl
+application/vnd.yamaha.hv-dic hvd
+application/vnd.yamaha.hv-script hvs
+application/vnd.yamaha.hv-voice hvp
+application/vnd.yamaha.openscoreformat osf
+application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg
+application/vnd.yamaha.smaf-audio saf
+application/vnd.yamaha.smaf-phrase spf
+application/vnd.yellowriver-custom-menu cmp
+application/vnd.zul zir zirz
+application/vnd.zzazz.deck+xml zaz
+application/voicexml+xml vxml
+application/widget wgt
+application/winhlp hlp
+application/wsdl+xml wsdl
+application/wspolicy+xml wspolicy
+application/x-7z-compressed 7z
+application/x-abiword abw
+application/x-ace-compressed ace
+application/x-authorware-bin aab x32 u32 vox
+application/x-authorware-map aam
+application/x-authorware-seg aas
+application/x-bcpio bcpio
+application/x-bittorrent torrent
+application/x-blorb blb blorb
+application/x-bzip bz
+application/x-bzip2 bz2 boz
+application/x-cbr cbr cba cbt cbz cb7
+application/x-cdlink vcd
+application/x-cfs-compressed cfs
+application/x-chat chat
+application/x-chess-pgn pgn
+application/x-chrome-extension crx
+application/x-cocoa cco
+application/x-conference nsc
+application/x-cpio cpio
+application/x-csh csh
+application/x-debian-package udeb
+application/x-dgc-compressed dgc
+application/x-director dir dcr dxr cst cct cxt w3d fgd swa
+application/x-doom wad
+application/x-dtbncx+xml ncx
+application/x-dtbook+xml dtb
+application/x-dtbresource+xml res
+application/x-dvi dvi
+application/x-envoy evy
+application/x-eva eva
+application/x-font-bdf bdf
+application/x-font-ghostscript gsf
+application/x-font-linux-psf psf
+application/x-font-otf otf
+application/x-font-pcf pcf
+application/x-font-snf snf
+application/x-font-ttf ttf ttc
+application/x-font-type1 pfa pfb pfm afm
+application/x-freearc arc
+application/x-futuresplash spl
+application/x-gca-compressed gca
+application/x-glulx ulx
+application/x-gnumeric gnumeric
+application/x-gramps-xml gramps
+application/x-gtar gtar
+application/x-hdf hdf
+application/x-httpd-php php
+application/x-install-instructions install
+application/x-java-archive-diff jardiff
+application/x-java-jnlp-file jnlp
+application/x-latex latex
+application/x-lua-bytecode luac
+application/x-lzh-compressed lzh lha
+application/x-makeself run
+application/x-mie mie
+application/x-mobipocket-ebook prc mobi
+application/x-ms-application application
+application/x-ms-shortcut lnk
+application/x-ms-wmd wmd
+application/x-ms-wmz wmz
+application/x-ms-xbap xbap
+application/x-msaccess mdb
+application/x-msbinder obd
+application/x-mscardfile crd
+application/x-msclip clp
+application/x-msdownload com bat
+application/x-msmediaview mvb m13 m14
+application/x-msmetafile wmf emf emz
+application/x-msmoney mny
+application/x-mspublisher pub
+application/x-msschedule scd
+application/x-msterminal trm
+application/x-mswrite wri
+application/x-netcdf nc cdf
+application/x-ns-proxy-autoconfig pac
+application/x-nzb nzb
+application/x-perl pl pm
+application/x-pkcs12 p12 pfx
+application/x-pkcs7-certificates p7b spc
+application/x-pkcs7-certreqresp p7r
+application/x-rar-compressed rar
+application/x-redhat-package-manager rpm
+application/x-research-info-systems ris
+application/x-sea sea
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-silverlight-app xap
+application/x-sql sql
+application/x-stuffit sit
+application/x-stuffitx sitx
+application/x-subrip srt
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-t3vm-image t3
+application/x-tads gam
+application/x-tar tar
+application/x-tcl tcl tk
+application/x-tex tex
+application/x-tex-tfm tfm
+application/x-texinfo texinfo texi
+application/x-tgif obj
+application/x-ustar ustar
+application/x-wais-source src
+application/x-web-app-manifest+json webapp
+application/x-x509-ca-cert der crt pem
+application/x-xfig fig
+application/x-xliff+xml xlf
+application/x-xpinstall xpi
+application/x-xz xz
+application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8
+application/xaml+xml xaml
+application/xcap-diff+xml xdf
+application/xenc+xml xenc
+application/xhtml+xml xhtml xht
+application/xml xml xsl xsd
+application/xml-dtd dtd
+application/xop+xml xop
+application/xproc+xml xpl
+application/xslt+xml xslt
+application/xspf+xml xspf
+application/xv+xml mxml xhvml xvml xvm
+application/yang yang
+application/yin+xml yin
+application/zip zip
+audio/adpcm adp
+audio/basic au snd
+audio/midi mid midi kar rmi
+audio/mp4 mp4a m4a
+audio/mpeg mpga mp2 mp2a mp3 m2a m3a
+audio/ogg oga ogg spx
+audio/s3m s3m
+audio/silk sil
+audio/vnd.dece.audio uva uvva
+audio/vnd.digital-winds eol
+audio/vnd.dra dra
+audio/vnd.dts dts
+audio/vnd.dts.hd dtshd
+audio/vnd.lucent.voice lvp
+audio/vnd.ms-playready.media.pya pya
+audio/vnd.nuera.ecelp4800 ecelp4800
+audio/vnd.nuera.ecelp7470 ecelp7470
+audio/vnd.nuera.ecelp9600 ecelp9600
+audio/vnd.rip rip
+audio/wav wav
+audio/webm weba
+audio/x-aac aac
+audio/x-aiff aif aiff aifc
+audio/x-caf caf
+audio/x-flac flac
+audio/x-matroska mka
+audio/x-mpegurl m3u
+audio/x-ms-wax wax
+audio/x-ms-wma wma
+audio/x-pn-realaudio ram ra
+audio/x-pn-realaudio-plugin rmp
+audio/xm xm
+chemical/x-cdx cdx
+chemical/x-cif cif
+chemical/x-cmdf cmdf
+chemical/x-cml cml
+chemical/x-csml csml
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm cgm
+image/g3fax g3
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/ktx ktx
+image/png png
+image/prs.btif btif
+image/sgi sgi
+image/svg+xml svg svgz
+image/tiff tiff tif
+image/vnd.adobe.photoshop psd
+image/vnd.dece.graphic uvi uvvi uvg uvvg
+image/vnd.djvu djvu djv
+image/vnd.dvb.subtitle sub
+image/vnd.dwg dwg
+image/vnd.dxf dxf
+image/vnd.fastbidsheet fbs
+image/vnd.fpx fpx
+image/vnd.fst fst
+image/vnd.fujixerox.edmics-mmr mmr
+image/vnd.fujixerox.edmics-rlc rlc
+image/vnd.ms-modi mdi
+image/vnd.ms-photo wdp
+image/vnd.net-fpx npx
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff xif
+image/webp webp
+image/x-3ds 3ds
+image/x-cmu-raster ras
+image/x-cmx cmx
+image/x-freehand fh fhc fh4 fh5 fh7
+image/x-icon ico
+image/x-jng jng
+image/x-mrsid-image sid
+image/x-pcx pcx
+image/x-pict pic pct
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-tga tga
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/rfc822 eml mime
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.collada+xml dae
+model/vnd.dwf dwf
+model/vnd.gdl gdl
+model/vnd.gtw gtw
+model/vnd.mts mts
+model/vnd.vtu vtu
+model/vrml wrl vrml
+model/x3d+binary x3db x3dbz
+model/x3d+vrml x3dv x3dvz
+model/x3d+xml x3d x3dz
+text/cache-manifest appcache manifest
+text/calendar ics ifb
+text/coffeescript coffee litcoffee
+text/css css
+text/csv csv
+text/hjson hjson
+text/html html htm shtml
+text/jade jade
+text/jsx jsx
+text/less less
+text/mathml mml
+text/n3 n3
+text/plain txt text conf def list log in ini
+text/prs.lines.tag dsc
+text/richtext rtx
+text/sgml sgml sgm
+text/stylus stylus styl
+text/tab-separated-values tsv
+text/troff t tr roff man me ms
+text/turtle ttl
+text/uri-list uri uris urls
+text/vcard vcard
+text/vnd.curl curl
+text/vnd.curl.dcurl dcurl
+text/vnd.curl.mcurl mcurl
+text/vnd.curl.scurl scurl
+text/vnd.fly fly
+text/vnd.fmi.flexstor flx
+text/vnd.graphviz gv
+text/vnd.in3d.3dml 3dml
+text/vnd.in3d.spot spot
+text/vnd.sun.j2me.app-descriptor jad
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/vtt vtt
+text/x-asm s asm
+text/x-c c cc cxx cpp h hh dic
+text/x-component htc
+text/x-fortran f for f77 f90
+text/x-handlebars-template hbs
+text/x-java-source java
+text/x-lua lua
+text/x-markdown markdown md mkd
+text/x-nfo nfo
+text/x-opml opml
+text/x-pascal p pas
+text/x-processing pde
+text/x-sass sass
+text/x-scss scss
+text/x-setext etx
+text/x-sfv sfv
+text/x-uuencode uu
+text/x-vcalendar vcs
+text/x-vcard vcf
+text/yaml yaml yml
+video/3gpp 3gp 3gpp
+video/3gpp2 3g2
+video/h261 h261
+video/h263 h263
+video/h264 h264
+video/jpeg jpgv
+video/jpm jpm jpgm
+video/mj2 mj2 mjp2
+video/mp2t ts
+video/mp4 mp4 mp4v mpg4
+video/mpeg mpeg mpg mpe m1v m2v
+video/ogg ogv
+video/quicktime qt mov
+video/vnd.dece.hd uvh uvvh
+video/vnd.dece.mobile uvm uvvm
+video/vnd.dece.pd uvp uvvp
+video/vnd.dece.sd uvs uvvs
+video/vnd.dece.video uvv uvvv
+video/vnd.dvb.file dvb
+video/vnd.fvt fvt
+video/vnd.mpegurl mxu m4u
+video/vnd.ms-playready.media.pyv pyv
+video/vnd.uvvu.mp4 uvu uvvu
+video/vnd.vivo viv
+video/webm webm
+video/x-f4v f4v
+video/x-fli fli
+video/x-flv flv
+video/x-m4v m4v
+video/x-matroska mkv mk3d mks
+video/x-mng mng
+video/x-ms-asf asf asx
+video/x-ms-vob vob
+video/x-ms-wm wm
+video/x-ms-wmv wmv
+video/x-ms-wmx wmx
+video/x-ms-wvx wvx
+video/x-msvideo avi
+video/x-sgi-movie movie
+video/x-smv smv
+x-conference/x-cooltalk ice
\ No newline at end of file
diff --git a/lib/jekyll/page.rb b/lib/jekyll/page.rb
index f9040da8..6c402ee3 100644
--- a/lib/jekyll/page.rb
+++ b/lib/jekyll/page.rb
@@ -7,14 +7,27 @@ module Jekyll
attr_accessor :name, :ext, :basename
attr_accessor :data, :content, :output
+ alias_method :extname, :ext
+
+ FORWARD_SLASH = '/'.freeze
+
# Attributes for Liquid templates
- ATTRIBUTES_FOR_LIQUID = %w[
+ ATTRIBUTES_FOR_LIQUID = %w(
content
dir
name
path
url
- ]
+ )
+
+ # A set of extensions that are considered HTML or HTML-like so we
+ # should not alter them, this includes .xhtml through XHTM5.
+
+ HTML_EXTENSIONS = %W(
+ .html
+ .xhtml
+ .htm
+ )
# Initialize a new Page.
#
@@ -28,15 +41,14 @@ module Jekyll
@dir = dir
@name = name
-
process(name)
read_yaml(File.join(base, dir), name)
- data.default_proc = proc do |hash, key|
+ data.default_proc = proc do |_, key|
site.frontmatter_defaults.find(File.join(dir, name), type, key)
end
- Jekyll::Hooks.trigger self, :post_init
+ Jekyll::Hooks.trigger :pages, :post_init, self
end
# The generated directory into which the page will be placed
@@ -45,7 +57,12 @@ module Jekyll
#
# Returns the String destination directory.
def dir
- url[-1, 1] == '/' ? url : File.dirname(url)
+ if url.end_with?(FORWARD_SLASH)
+ url
+ else
+ url_dir = File.dirname(url)
+ url_dir.end_with?(FORWARD_SLASH) ? url_dir : "#{url_dir}/"
+ end
end
# The full path and filename of the post. Defined in the YAML of the post
@@ -53,8 +70,7 @@ module Jekyll
#
# Returns the String permalink or nil if none has been set.
def permalink
- return nil if data.nil? || data['permalink'].nil?
- data['permalink']
+ data.nil? ? nil : data['permalink']
end
# The template of the permalink.
@@ -98,7 +114,7 @@ module Jekyll
# Returns nothing.
def process(name)
self.ext = File.extname(name)
- self.basename = name[0 .. -ext.length - 1]
+ self.basename = name[0..-ext.length - 1]
end
# Add any necessary layouts to this post
@@ -108,12 +124,10 @@ module Jekyll
#
# Returns nothing.
def render(layouts, site_payload)
- payload = Utils.deep_merge_hashes({
- "page" => to_liquid,
- 'paginator' => pager.to_liquid
- }, site_payload)
+ site_payload["page"] = to_liquid
+ site_payload["paginator"] = pager.to_liquid
- do_layout(payload, layouts)
+ do_layout(site_payload, layouts)
end
# The path to the source file
@@ -135,8 +149,8 @@ module Jekyll
# Returns the destination file path String.
def destination(dest)
path = site.in_dest_dir(dest, URL.unescape_path(url))
- path = File.join(path, "index.html") if url.end_with?("/")
- path << output_ext unless path.end_with?(output_ext)
+ path = File.join(path, "index") if url.end_with?("/")
+ path << output_ext unless path.end_with? output_ext
path
end
@@ -147,12 +161,20 @@ module Jekyll
# Returns the Boolean of whether this Page is HTML or not.
def html?
- output_ext == '.html'
+ HTML_EXTENSIONS.include?(output_ext)
end
# Returns the Boolean of whether this Page is an index file or not.
def index?
basename == 'index'
end
+
+ def trigger_hooks(hook_name, *args)
+ Jekyll::Hooks.trigger :pages, hook_name, self, *args
+ end
+
+ def write?
+ true
+ end
end
end
diff --git a/lib/jekyll/plugin.rb b/lib/jekyll/plugin.rb
index 0207314c..e2a95168 100644
--- a/lib/jekyll/plugin.rb
+++ b/lib/jekyll/plugin.rb
@@ -1,20 +1,39 @@
module Jekyll
class Plugin
- PRIORITIES = { :lowest => -100,
- :low => -10,
- :normal => 0,
- :high => 10,
- :highest => 100 }
+ PRIORITIES = {
+ :low => -10,
+ :highest => 100,
+ :lowest => -100,
+ :normal => 0,
+ :high => 10
+ }
- # Fetch all the subclasses of this class and its subclasses' subclasses.
#
- # Returns an array of descendant classes.
- def self.descendants
- descendants = []
- ObjectSpace.each_object(singleton_class) do |k|
- descendants.unshift k unless k == self
+
+ def self.inherited(const)
+ return catch_inheritance(const) do |const_|
+ catch_inheritance(const_)
end
- descendants
+ end
+
+ #
+
+ def self.catch_inheritance(const)
+ const.define_singleton_method :inherited do |const_|
+ (@children ||= Set.new).add const_
+ if block_given?
+ yield const_
+ end
+ end
+ end
+
+ #
+
+ def self.descendants
+ @children ||= Set.new
+ out = @children.map(&:descendants)
+ out << self unless superclass == Plugin
+ Set.new(out).flatten
end
# Get or set the priority of this plugin. When called without an
diff --git a/lib/jekyll/plugin_manager.rb b/lib/jekyll/plugin_manager.rb
index 5ba0924f..502c4a73 100644
--- a/lib/jekyll/plugin_manager.rb
+++ b/lib/jekyll/plugin_manager.rb
@@ -24,12 +24,7 @@ module Jekyll
#
# Returns nothing.
def require_gems
- site.gems.each do |gem|
- if plugin_allowed?(gem)
- Jekyll.logger.debug("PluginManager:", "Requiring #{gem}")
- require gem
- end
- end
+ Jekyll::External.require_with_graceful_fail(site.gems.select { |gem| plugin_allowed?(gem) })
end
def self.require_from_bundler
@@ -70,10 +65,9 @@ module Jekyll
# Returns nothing.
def require_plugin_files
unless site.safe
- plugins_path.each do |plugins|
- Dir[File.join(plugins, "**", "*.rb")].sort.each do |f|
- require f
- end
+ plugins_path.each do |plugin_search_path|
+ plugin_files = Utils.safe_glob(plugin_search_path, File.join("**", "*.rb"))
+ Jekyll::External.require_with_graceful_fail(plugin_files)
end
end
end
@@ -82,21 +76,20 @@ module Jekyll
#
# Returns an Array of plugin search paths
def plugins_path
- if (site.config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
- [site.in_source_dir(site.config['plugins'])]
+ if site.config['plugins_dir'] == Jekyll::Configuration::DEFAULTS['plugins_dir']
+ [site.in_source_dir(site.config['plugins_dir'])]
else
- Array(site.config['plugins']).map { |d| File.expand_path(d) }
+ Array(site.config['plugins_dir']).map { |d| File.expand_path(d) }
end
end
def deprecation_checks
pagination_included = (site.config['gems'] || []).include?('jekyll-paginate') || defined?(Jekyll::Paginate)
if site.config['paginate'] && !pagination_included
- Jekyll::Deprecator.deprecation_message "You appear to have pagination " +
- "turned on, but you haven't included the `jekyll-paginate` gem. " +
+ Jekyll::Deprecator.deprecation_message "You appear to have pagination " \
+ "turned on, but you haven't included the `jekyll-paginate` gem. " \
"Ensure you have `gems: [jekyll-paginate]` in your configuration file."
end
end
-
end
end
diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb
deleted file mode 100644
index 252cca42..00000000
--- a/lib/jekyll/post.rb
+++ /dev/null
@@ -1,331 +0,0 @@
-module Jekyll
- class Post
- include Comparable
- include Convertible
-
- # Valid post name regex.
- MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
-
- EXCERPT_ATTRIBUTES_FOR_LIQUID = %w[
- title
- url
- dir
- date
- id
- categories
- next
- previous
- tags
- path
- ]
-
- # Attributes for Liquid templates
- ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID + %w[
- content
- excerpt
- excerpt_separator
- draft?
- ]
-
- # Post name validator. Post filenames must be like:
- # 2008-11-05-my-awesome-post.textile
- #
- # Returns true if valid, false if not.
- def self.valid?(name)
- name =~ MATCHER
- end
-
- attr_accessor :site
- attr_accessor :data, :extracted_excerpt, :content, :output, :ext
- attr_accessor :date, :slug, :tags, :categories
-
- attr_reader :name
-
- # 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(site, source, dir, name)
- @site = site
- @dir = dir
- @base = containing_dir(dir)
- @name = name
-
- self.categories = dir.split('/').reject { |x| x.empty? }
- process(name)
- read_yaml(@base, name)
-
- data.default_proc = proc do |hash, key|
- site.frontmatter_defaults.find(relative_path, type, key)
- end
-
- if data.key?('date')
- self.date = Utils.parse_date(data["date"].to_s, "Post '#{relative_path}' does not have a valid date in the YAML front matter.")
- end
-
- populate_categories
- populate_tags
-
- Jekyll::Hooks.trigger self, :post_init
- end
-
- def published?
- if data.key?('published') && data['published'] == false
- false
- else
- true
- end
- end
-
- def populate_categories
- categories_from_data = Utils.pluralized_array_from_hash(data, 'category', 'categories')
- self.categories = (
- Array(categories) + categories_from_data
- ).map { |c| c.to_s }.flatten.uniq
- end
-
- def populate_tags
- self.tags = Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
- end
-
- # Get the full path to the directory containing the post files
- def containing_dir(dir)
- site.in_source_dir(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 = 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
- data.fetch('excerpt') { extracted_excerpt.to_s }
- end
-
- # Public: the Post title, from the YAML Front-Matter or from the slug
- #
- # Returns the post title
- def title
- data.fetch('title') { titleized_slug }
- end
-
- # Public: the Post excerpt_separator, from the YAML Front-Matter or site default
- # excerpt_separator value
- #
- # Returns the post excerpt_separator
- def excerpt_separator
- (data['excerpt_separator'] || site.config['excerpt_separator']).to_s
- end
-
- # Turns the post slug into a suitable title
- def titleized_slug
- 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
- data.fetch('path') { 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].map(&:to_s).reject(&:empty?))
- end
-
- # 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)
- cmp = self.date <=> other.date
- if 0 == cmp
- cmp = self.slug <=> other.slug
- end
- return cmp
- end
-
- # Extract information from the post filename.
- #
- # name - The String filename of the post file.
- #
- # Returns nothing.
- def process(name)
- m, cats, date, slug, ext = *name.match(MATCHER)
- self.date = Utils.parse_date(date, "Post '#{relative_path}' does not have a valid date in the filename.")
- self.slug = slug
- self.ext = ext
- end
-
- # The generated directory into which the post will be placed
- # upon generation. This is derived from the permalink or, if
- # permalink is absent, set to the default date
- # e.g. "/2008/11/05/" if the permalink style is :date, otherwise nothing.
- #
- # Returns 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).
- #
- # Returns the String permalink.
- def permalink
- data && data['permalink']
- end
-
- def template
- case site.permalink_style
- when :pretty
- "/:categories/:year/:month/:day/:title/"
- when :none
- "/:categories/:title.html"
- when :date
- "/:categories/:year/:month/:day/:title.html"
- when :ordinal
- "/:categories/:year/:y_day/:title.html"
- else
- site.permalink_style.to_s
- end
- end
-
- # The generated relative url of this post.
- #
- # Returns the String url.
- def url
- @url ||= URL.new({
- :template => template,
- :placeholders => url_placeholders,
- :permalink => permalink
- }).to_s
- end
-
- # 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 => slug,
- :i_day => date.strftime("%-d"),
- :i_month => date.strftime("%-m"),
- :categories => (categories || []).map { |c| c.to_s.downcase }.uniq.join('/'),
- :short_month => date.strftime("%b"),
- :short_year => date.strftime("%y"),
- :y_day => date.strftime("%j"),
- :output_ext => output_ext
- }
- 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(dir, slug)
- end
-
- # Calculate related posts.
- #
- # Returns an Array of related Posts.
- def related_posts(posts)
- Jekyll::RelatedPosts.new(self).build
- end
-
- # Add any necessary layouts to this post.
- #
- # layouts - A Hash of {"name" => "layout"}.
- # site_payload - The site payload hash.
- #
- # Returns nothing.
- def render(layouts, site_payload)
- # construct payload
- payload = Utils.deep_merge_hashes({
- "site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
- "page" => to_liquid(self.class::EXCERPT_ATTRIBUTES_FOR_LIQUID)
- }, site_payload)
-
- if generate_excerpt?
- extracted_excerpt.do_layout(payload, {})
- end
-
- do_layout(payload.merge({"page" => to_liquid}), layouts)
- end
-
- # Obtain destination 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 = site.in_dest_dir(dest, URL.unescape_path(url))
- path = File.join(path, "index.html") if self.url.end_with?("/")
- path << output_ext unless path.end_with?(output_ext)
- path
- end
-
- # Returns the shorthand String identifier of this Post.
- def inspect
- ""
- end
-
- def next
- pos = site.posts.index {|post| post.equal?(self) }
- if pos && pos < site.posts.length - 1
- site.posts[pos + 1]
- else
- nil
- end
- end
-
- def previous
- pos = site.posts.index {|post| post.equal?(self) }
- if pos && pos > 0
- site.posts[pos - 1]
- else
- nil
- end
- end
-
- # Returns if this Post is a Draft
- def draft?
- is_a?(Jekyll::Draft)
- end
-
- protected
-
- def extract_excerpt
- if generate_excerpt?
- Jekyll::Excerpt.new(self)
- else
- ""
- end
- end
-
- def generate_excerpt?
- !excerpt_separator.empty?
- end
- end
-end
diff --git a/lib/jekyll/publisher.rb b/lib/jekyll/publisher.rb
index e86e96b6..cc739627 100644
--- a/lib/jekyll/publisher.rb
+++ b/lib/jekyll/publisher.rb
@@ -8,14 +8,14 @@ module Jekyll
can_be_published?(thing) && !hidden_in_the_future?(thing)
end
+ def hidden_in_the_future?(thing)
+ thing.respond_to?(:date) && !@site.future && thing.date.to_i > @site.time.to_i
+ end
+
private
def can_be_published?(thing)
thing.data.fetch('published', true) || @site.unpublished
end
-
- def hidden_in_the_future?(thing)
- thing.is_a?(Post) && !@site.future && thing.date > @site.time
- end
end
-end
\ No newline at end of file
+end
diff --git a/lib/jekyll/reader.rb b/lib/jekyll/reader.rb
index 892bc917..c9ded560 100644
--- a/lib/jekyll/reader.rb
+++ b/lib/jekyll/reader.rb
@@ -16,18 +16,18 @@ module Jekyll
@site.layouts = LayoutReader.new(site).read
read_directories
sort_files!
- @site.data = DataReader.new(site).read(site.config['data_source'])
+ @site.data = DataReader.new(site).read(site.config['data_dir'])
CollectionReader.new(site).read
end
# Sorts posts, pages, and static files.
def sort_files!
- site.posts.sort!
+ site.collections.values.each { |c| c.docs.sort! }
site.pages.sort_by!(&:name)
site.static_files.sort_by!(&:relative_path)
end
- # Recursively traverse directories to find posts, pages and static files
+ # Recursively traverse directories to find pages and static files
# that will become part of the site according to the rules in
# filter_entries.
#
@@ -38,9 +38,9 @@ module Jekyll
base = site.in_source_dir(dir)
dot = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) }
- dot_dirs = dot.select{ |file| File.directory?(@site.in_source_dir(base,file)) }
+ dot_dirs = dot.select { |file| File.directory?(@site.in_source_dir(base, file)) }
dot_files = (dot - dot_dirs)
- dot_pages = dot_files.select{ |file| Utils.has_yaml_header?(@site.in_source_dir(base,file)) }
+ dot_pages = dot_files.select { |file| Utils.has_yaml_header?(@site.in_source_dir(base, file)) }
dot_static_files = dot_files - dot_pages
retrieve_posts(dir)
@@ -56,8 +56,8 @@ module Jekyll
#
# Returns nothing.
def retrieve_posts(dir)
- site.posts.concat(PostReader.new(site).read(dir))
- site.posts.concat(DraftReader.new(site).read(dir)) if site.show_drafts
+ site.posts.docs.concat(PostReader.new(site).read_posts(dir))
+ site.posts.docs.concat(PostReader.new(site).read_drafts(dir)) if site.show_drafts
end
# Recursively traverse directories with the read_directories function.
@@ -67,12 +67,12 @@ module Jekyll
# dot_dirs - The Array of subdirectories in the dir.
#
# Returns nothing.
- def retrieve_dirs(base, dir, dot_dirs)
- dot_dirs.map { |file|
- dir_path = site.in_source_dir(dir,file)
+ def retrieve_dirs(_base, dir, dot_dirs)
+ dot_dirs.map do |file|
+ dir_path = site.in_source_dir(dir, file)
rel_path = File.join(dir, file)
@site.reader.read_directories(rel_path) unless @site.dest.sub(/\/$/, '') == dir_path
- }
+ end
end
# Retrieve all the pages from the current directory,
diff --git a/lib/jekyll/readers/collection_reader.rb b/lib/jekyll/readers/collection_reader.rb
index 04324fa1..062be42a 100644
--- a/lib/jekyll/readers/collection_reader.rb
+++ b/lib/jekyll/readers/collection_reader.rb
@@ -1,5 +1,7 @@
module Jekyll
class CollectionReader
+ SPECIAL_COLLECTIONS = %w(posts data).freeze
+
attr_reader :site, :content
def initialize(site)
@site = site
@@ -11,9 +13,8 @@ module Jekyll
# Returns nothing.
def read
site.collections.each do |_, collection|
- collection.read unless collection.label.eql?('data')
+ collection.read unless SPECIAL_COLLECTIONS.include?(collection.label)
end
end
-
end
-end
\ No newline at end of file
+end
diff --git a/lib/jekyll/readers/data_reader.rb b/lib/jekyll/readers/data_reader.rb
index cbb24be3..870fc2dc 100644
--- a/lib/jekyll/readers/data_reader.rb
+++ b/lib/jekyll/readers/data_reader.rb
@@ -50,13 +50,13 @@ module Jekyll
# Returns the contents of the data file.
def read_data_file(path)
case File.extname(path).downcase
- when '.csv'
- CSV.read(path, {
- :headers => true,
- :encoding => site.config['encoding']
- }).map(&:to_hash)
- else
- SafeYAML.load_file(path)
+ when '.csv'
+ CSV.read(path, {
+ :headers => true,
+ :encoding => site.config['encoding']
+ }).map(&:to_hash)
+ else
+ SafeYAML.load_file(path)
end
end
diff --git a/lib/jekyll/readers/draft_reader.rb b/lib/jekyll/readers/draft_reader.rb
deleted file mode 100644
index d62029b2..00000000
--- a/lib/jekyll/readers/draft_reader.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-module Jekyll
- class DraftReader
- attr_reader :site, :unfiltered_content
- def initialize(site)
- @site = site
- @unfiltered_content = Array.new
- end
-
- # Read all the files in //_drafts and create a new Draft
- # object with each one.
- #
- # dir - The String relative path of the directory to read.
- #
- # Returns nothing.
- def read(dir)
- @unfiltered_content = read_content(dir, '_drafts')
- @unfiltered_content.select{ |draft| site.publisher.publish?(draft) }
- end
-
- # Read all the content files from //magic_dir
- # and return them with the type klass.
- #
- # dir - The String relative path of the directory to read.
- # magic_dir - The String relative directory to ,
- # looks for content here.
- # klass - The return type of the content.
- #
- # Returns klass type of content files
- def read_content(dir, magic_dir)
- @site.reader.get_entries(dir, magic_dir).map do |entry|
- Draft.new(site, site.source, dir, entry) if Draft.valid?(entry)
- end.reject do |entry|
- entry.nil?
- end
- end
- end
-end
diff --git a/lib/jekyll/readers/layout_reader.rb b/lib/jekyll/readers/layout_reader.rb
index a8466beb..f0620294 100644
--- a/lib/jekyll/readers/layout_reader.rb
+++ b/lib/jekyll/readers/layout_reader.rb
@@ -38,11 +38,11 @@ module Jekyll
end
def layout_directory_inside_source
- site.in_source_dir(site.config['layouts'])
+ site.in_source_dir(site.config['layouts_dir'])
end
def layout_directory_in_cwd
- dir = Jekyll.sanitized_path(Dir.pwd, site.config['layouts'])
+ dir = Jekyll.sanitized_path(Dir.pwd, site.config['layouts_dir'])
if File.directory?(dir) && !site.safe
dir
else
diff --git a/lib/jekyll/readers/page_reader.rb b/lib/jekyll/readers/page_reader.rb
index 099ebf13..97748c01 100644
--- a/lib/jekyll/readers/page_reader.rb
+++ b/lib/jekyll/readers/page_reader.rb
@@ -4,7 +4,7 @@ module Jekyll
def initialize(site, dir)
@site = site
@dir = dir
- @unfiltered_content = Array.new
+ @unfiltered_content = []
end
# Read all the files in // for Yaml header and create a new Page
@@ -14,8 +14,8 @@ module Jekyll
#
# Returns an array of static pages.
def read(files)
- files.map{ |page| @unfiltered_content << Page.new(@site, @site.source, @dir, page) }
- @unfiltered_content.select{ |page| site.publisher.publish?(page) }
+ files.map { |page| @unfiltered_content << Page.new(@site, @site.source, @dir, page) }
+ @unfiltered_content.select { |page| site.publisher.publish?(page) }
end
end
end
diff --git a/lib/jekyll/readers/post_reader.rb b/lib/jekyll/readers/post_reader.rb
index 73bdd85d..f7a44ca7 100644
--- a/lib/jekyll/readers/post_reader.rb
+++ b/lib/jekyll/readers/post_reader.rb
@@ -3,18 +3,44 @@ module Jekyll
attr_reader :site, :unfiltered_content
def initialize(site)
@site = site
- @unfiltered_content = Array.new
end
- # Read all the files in //_posts and create a new Post
+ # Read all the files in //_drafts and create a new
+ # Document object with each one.
+ #
+ # dir - The String relative path of the directory to read.
+ #
+ # Returns nothing.
+ def read_drafts(dir)
+ read_publishable(dir, '_drafts', Document::DATELESS_FILENAME_MATCHER)
+ end
+
+ # Read all the files in //_posts and create a new Document
# object with each one.
#
# dir - The String relative path of the directory to read.
#
# Returns nothing.
- def read(dir)
- @unfiltered_content = read_content(dir, '_posts')
- @unfiltered_content.select{ |post| site.publisher.publish?(post) }
+ def read_posts(dir)
+ read_publishable(dir, '_posts', Document::DATE_FILENAME_MATCHER)
+ end
+
+ # Read all the files in // and create a new
+ # Document object with each one insofar as it matches the regexp matcher.
+ #
+ # dir - The String relative path of the directory to read.
+ #
+ # Returns nothing.
+ def read_publishable(dir, magic_dir, matcher)
+ read_content(dir, magic_dir, matcher).tap do |docs|
+ docs.each(&:read)
+ end.select do |doc|
+ site.publisher.publish?(doc).tap do |will_publish|
+ if !will_publish && site.publisher.hidden_in_the_future?(doc)
+ Jekyll.logger.debug "Skipping:", "#{doc.relative_path} has a future date"
+ end
+ end
+ end
end
# Read all the content files from //magic_dir
@@ -26,12 +52,15 @@ module Jekyll
# klass - The return type of the content.
#
# Returns klass type of content files
- def read_content(dir, magic_dir)
+ def read_content(dir, magic_dir, matcher)
@site.reader.get_entries(dir, magic_dir).map do |entry|
- Post.new(site, site.source, dir, entry) if Post.valid?(entry)
- end.reject do |entry|
- entry.nil?
- end
+ next unless entry =~ matcher
+ path = @site.in_source_dir(File.join(dir, magic_dir, entry))
+ Document.new(path, {
+ :site => @site,
+ :collection => @site.posts
+ })
+ end.reject(&:nil?)
end
end
end
diff --git a/lib/jekyll/readers/static_file_reader.rb b/lib/jekyll/readers/static_file_reader.rb
index 279bea46..8def1365 100644
--- a/lib/jekyll/readers/static_file_reader.rb
+++ b/lib/jekyll/readers/static_file_reader.rb
@@ -4,7 +4,7 @@ module Jekyll
def initialize(site, dir)
@site = site
@dir = dir
- @unfiltered_content = Array.new
+ @unfiltered_content = []
end
# Read all the files in // for Yaml header and create a new Page
@@ -14,7 +14,7 @@ module Jekyll
#
# Returns an array of static files.
def read(files)
- files.map{ |file| @unfiltered_content << StaticFile.new(@site, @site.source, @dir, file)}
+ files.map { |file| @unfiltered_content << StaticFile.new(@site, @site.source, @dir, file) }
@unfiltered_content
end
end
diff --git a/lib/jekyll/regenerator.rb b/lib/jekyll/regenerator.rb
index 18a54ae3..20522350 100644
--- a/lib/jekyll/regenerator.rb
+++ b/lib/jekyll/regenerator.rb
@@ -17,8 +17,8 @@ module Jekyll
# Returns a boolean.
def regenerate?(document)
case document
- when Post, Page
- document.asset_file? || document.data['regenerate'] ||
+ when Page
+ document.asset_file? || document.data['regenerate'] ||
source_modified_or_dest_missing?(
site.in_source_dir(document.relative_path), document.destination(@site.dest)
)
@@ -62,7 +62,6 @@ module Jekyll
clear_cache
end
-
# Clear just the cache
#
# Returns nothing
@@ -70,13 +69,12 @@ module Jekyll
@cache = {}
end
-
# Checks if the source has been modified or the
# destination is missing
#
# returns a boolean
def source_modified_or_dest_missing?(source_path, dest_path)
- modified?(source_path) || (dest_path and !File.exist?(dest_path))
+ modified?(source_path) || (dest_path && !File.exist?(dest_path))
end
# Checks if a path's (or one of its dependencies)
@@ -87,10 +85,10 @@ module Jekyll
return true if disabled?
# objects that don't have a path are always regenerated
- return true if path.nil?
+ return true if path.nil?
# Check for path in cache
- if cache.has_key? path
+ if cache.key? path
return cache[path]
end
@@ -117,9 +115,9 @@ module Jekyll
#
# Returns nothing.
def add_dependency(path, dependency)
- return if (metadata[path].nil? || @disabled)
+ return if metadata[path].nil? || @disabled
- if !metadata[path]["deps"].include? dependency
+ unless metadata[path]["deps"].include? dependency
metadata[path]["deps"] << dependency
add(dependency) unless metadata.include?(dependency)
end
@@ -130,8 +128,8 @@ module Jekyll
#
# Returns nothing.
def write_metadata
- File.open(metadata_file, 'wb') do |f|
- f.write(Marshal.dump(metadata))
+ unless disabled?
+ File.binwrite(metadata_file, Marshal.dump(metadata))
end
end
@@ -146,7 +144,7 @@ module Jekyll
#
# Returns a Boolean (true for disabled, false for enabled).
def disabled?
- @disabled = site.full_rebuild? if @disabled.nil?
+ @disabled = !site.incremental? if @disabled.nil?
@disabled
end
@@ -157,20 +155,21 @@ module Jekyll
#
# Returns the read metadata.
def read_metadata
- @metadata = if !disabled? && File.file?(metadata_file)
- content = File.read(metadata_file)
+ @metadata =
+ if !disabled? && File.file?(metadata_file)
+ content = File.binread(metadata_file)
- begin
- Marshal.load(content)
- rescue TypeError
- SafeYAML.load(content)
- rescue ArgumentError => e
- Jekyll.logger.warn("Failed to load #{metadata_file}: #{e}")
+ begin
+ Marshal.load(content)
+ rescue TypeError
+ SafeYAML.load(content)
+ rescue ArgumentError => e
+ Jekyll.logger.warn("Failed to load #{metadata_file}: #{e}")
+ {}
+ end
+ else
{}
end
- else
- {}
- end
end
end
end
diff --git a/lib/jekyll/related_posts.rb b/lib/jekyll/related_posts.rb
index 9666b52e..51ae8d8f 100644
--- a/lib/jekyll/related_posts.rb
+++ b/lib/jekyll/related_posts.rb
@@ -1,6 +1,5 @@
module Jekyll
class RelatedPosts
-
class << self
attr_accessor :lsi
end
@@ -14,7 +13,7 @@ module Jekyll
end
def build
- return [] unless site.posts.size > 1
+ return [] unless site.posts.docs.size > 1
if site.lsi
build_index
@@ -24,13 +23,12 @@ module Jekyll
end
end
-
def build_index
self.class.lsi ||= begin
lsi = ClassifierReborn::LSI.new(:auto_rebuild => false)
display("Populating LSI...")
- site.posts.each do |x|
+ site.posts.docs.each do |x|
lsi.add_item(x)
end
@@ -46,7 +44,7 @@ module Jekyll
end
def most_recent_posts
- @most_recent_posts ||= (site.posts.reverse - [post]).first(10)
+ @most_recent_posts ||= (site.posts.docs.reverse - [post]).first(10)
end
def display(output)
diff --git a/lib/jekyll/renderer.rb b/lib/jekyll/renderer.rb
index ca79e5a8..7d20d452 100644
--- a/lib/jekyll/renderer.rb
+++ b/lib/jekyll/renderer.rb
@@ -2,13 +2,12 @@
module Jekyll
class Renderer
-
- attr_reader :document, :site, :site_payload
+ attr_reader :document, :site, :payload
def initialize(site, document, site_payload = nil)
- @site = site
- @document = document
- @site_payload = site_payload
+ @site = site
+ @document = document
+ @payload = site_payload || site.site_payload
end
# Determine which converters to use based on this document's
@@ -23,7 +22,7 @@ module Jekyll
#
# Returns the output extname including the leading period.
def output_ext
- converters.first.output_ext(document.extname)
+ @output_ext ||= (permalink_ext || converter_output_ext)
end
######################
@@ -31,31 +30,45 @@ module Jekyll
######################
def run
- payload = Utils.deep_merge_hashes({
- "page" => document.to_liquid
- }, site_payload || site.site_payload)
+ Jekyll.logger.debug "Rendering:", document.relative_path
- Jekyll::Hooks.trigger document, :pre_render, payload
+ payload["page"] = document.to_liquid
- info = {
- filters: [Jekyll::Filters],
- registers: { :site => site, :page => payload['page'] }
- }
+ if document.respond_to? :pager
+ payload["paginator"] = document.pager.to_liquid
+ end
+
+ if document.is_a?(Document) && document.collection.label == 'posts'
+ payload['site']['related_posts'] = document.related_posts
+ else
+ payload['site']['related_posts'] = nil
+ end
# render and transform content (this becomes the final content of the object)
- payload["highlighter_prefix"] = converters.first.highlighter_prefix
- payload["highlighter_suffix"] = converters.first.highlighter_suffix
+ payload['highlighter_prefix'] = converters.first.highlighter_prefix
+ payload['highlighter_suffix'] = converters.first.highlighter_suffix
+
+ Jekyll.logger.debug "Pre-Render Hooks:", document.relative_path
+ document.trigger_hooks(:pre_render, payload)
+
+ info = {
+ :filters => [Jekyll::Filters],
+ :registers => { :site => site, :page => payload['page'] }
+ }
output = document.content
if document.render_with_liquid?
+ Jekyll.logger.debug "Rendering Liquid:", document.relative_path
output = render_liquid(output, payload, info, document.path)
end
+ Jekyll.logger.debug "Rendering Markup:", document.relative_path
output = convert(output)
document.content = output
if document.place_in_layout?
+ Jekyll.logger.debug "Rendering Layout:", document.relative_path
place_in_layouts(
output,
payload,
@@ -125,20 +138,15 @@ module Jekyll
used = Set.new([layout])
while layout
- payload = Utils.deep_merge_hashes(
- payload,
- {
- "content" => output,
- "page" => document.to_liquid,
- "layout" => layout.data
- }
- )
+ payload['content'] = output
+ payload['page'] = document.to_liquid
+ payload['layout'] = Utils.deep_merge_hashes(payload['layout'] || {}, layout.data)
output = render_liquid(
layout.content,
payload,
info,
- File.join(site.config['layouts'], layout.name)
+ File.join(site.config['layouts_dir'], layout.name)
)
# Add layout to dependency tree
@@ -159,5 +167,27 @@ module Jekyll
output
end
+ private
+
+ def permalink_ext
+ if document.permalink && !document.permalink.end_with?("/")
+ permalink_ext = File.extname(document.permalink)
+ permalink_ext unless permalink_ext.empty?
+ end
+ end
+
+ def converter_output_ext
+ if output_exts.size == 1
+ output_exts.last
+ else
+ output_exts[-2]
+ end
+ end
+
+ def output_exts
+ @output_exts ||= converters.map do |c|
+ c.output_ext(document.extname)
+ end.compact
+ end
end
end
diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb
index a1ea8644..72d42ad9 100644
--- a/lib/jekyll/site.rb
+++ b/lib/jekyll/site.rb
@@ -4,7 +4,7 @@ require 'csv'
module Jekyll
class Site
attr_reader :source, :dest, :config
- attr_accessor :layouts, :posts, :pages, :static_files, :drafts,
+ attr_accessor :layouts, :pages, :static_files, :drafts,
:exclude, :include, :lsi, :highlighter, :permalink_style,
:time, :future, :unpublished, :safe, :plugins, :limit_posts,
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts,
@@ -19,8 +19,8 @@ module Jekyll
def initialize(config)
@config = config.clone
- %w[safe lsi highlighter baseurl exclude include future unpublished
- show_drafts limit_posts keep_files gems].each do |opt|
+ %w(safe lsi highlighter baseurl exclude include future unpublished
+ show_drafts limit_posts keep_files gems).each do |opt|
self.send("#{opt}=", config[opt])
end
@@ -74,7 +74,6 @@ module Jekyll
def reset
self.time = (config['time'] ? Utils.parse_date(config['time'].to_s, "Invalid time in _config.yml.") : Time.now)
self.layouts = {}
- self.posts = []
self.pages = []
self.static_files = []
self.data = {}
@@ -86,7 +85,7 @@ module Jekyll
raise ArgumentError, "limit_posts must be a non-negative number"
end
- Jekyll::Hooks.trigger self, :after_reset
+ Jekyll::Hooks.trigger :site, :after_reset, self
end
# Load necessary libraries, plugins, converters, and generators.
@@ -144,7 +143,7 @@ module Jekyll
def read
reader.read
limit_posts!
- Jekyll::Hooks.trigger self, :post_read
+ Jekyll::Hooks.trigger :site, :post_read, self
end
# Run each of the Generators.
@@ -164,22 +163,25 @@ module Jekyll
payload = site_payload
- Jekyll::Hooks.trigger self, :pre_render, payload
+ Jekyll::Hooks.trigger :site, :pre_render, self, payload
- collections.each do |label, collection|
+ collections.each do |_, collection|
collection.docs.each do |document|
if regenerator.regenerate?(document)
document.output = Jekyll::Renderer.new(self, document, payload).run
- Jekyll::Hooks.trigger document, :post_render
+ document.trigger_hooks(:post_render)
end
end
end
- [posts, pages].flatten.each do |page_or_post|
- if regenerator.regenerate?(page_or_post)
- page_or_post.render(layouts, payload)
+ pages.flatten.each do |page|
+ if regenerator.regenerate?(page)
+ page.output = Jekyll::Renderer.new(self, page, payload).run
+ page.trigger_hooks(:post_render)
end
end
+
+ Jekyll::Hooks.trigger :site, :post_render, self, payload
rescue Errno::ENOENT
# ignore missing layout dir
end
@@ -195,11 +197,15 @@ module Jekyll
#
# Returns nothing.
def write
- each_site_file { |item|
+ each_site_file do |item|
item.write(dest) if regenerator.regenerate?(item)
- }
+ end
regenerator.write_metadata
- Jekyll::Hooks.trigger self, :post_write
+ Jekyll::Hooks.trigger :site, :post_write, self
+ end
+
+ def posts
+ collections['posts'] ||= Collection.new(self, 'posts')
end
# Construct a Hash of Posts indexed by the specified Post attribute.
@@ -219,7 +225,7 @@ module Jekyll
# Build a hash map based on the specified post attribute ( post attr =>
# array of posts ) then sort each array in reverse order.
hash = Hash.new { |h, key| h[key] = [] }
- posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
+ posts.docs.each { |p| p.data[post_attr].each { |t| hash[t] << p } if p.data[post_attr] }
hash.values.each { |posts| posts.sort!.reverse! }
hash
end
@@ -254,47 +260,25 @@ module Jekyll
# "tags" - The Hash of tag values and Posts.
# See Site#post_attr_hash for type info.
def site_payload
- {
- "jekyll" => {
- "version" => Jekyll::VERSION,
- "environment" => Jekyll.env
- },
- "site" => Utils.deep_merge_hashes(config,
- Utils.deep_merge_hashes(Hash[collections.map{|label, coll| [label, coll.docs]}], {
- "time" => time,
- "posts" => posts.sort { |a, b| b <=> a },
- "pages" => pages,
- "static_files" => static_files,
- "html_pages" => pages.select { |page| page.html? || page.url.end_with?("/") },
- "categories" => post_attr_hash('categories'),
- "tags" => post_attr_hash('tags'),
- "collections" => collections.values.map(&:to_liquid),
- "documents" => documents,
- "data" => site_data
- }))
- }
+ Drops::UnifiedPayloadDrop.new self
end
# Get the implementation class for the given Converter.
- #
- # klass - The Class of the Converter to fetch.
- #
# Returns the Converter instance implementing the given Converter.
+ # klass - The Class of the Converter to fetch.
+
def find_converter_instance(klass)
- converters.find { |c| c.class == klass } || proc { raise "No converter for #{klass}" }.call
+ converters.find { |klass_| klass_.instance_of?(klass) } || \
+ raise("No Converters found for #{klass}")
end
+ # klass - class or module containing the subclasses.
+ # Returns array of instances of subclasses of parameter.
# 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
+ # passed in as argument.
+
def instantiate_subclasses(klass)
- klass.descendants.select do |c|
- !safe || c.safe
- end.sort.map do |c|
+ klass.descendants.select { |c| !safe || c.safe }.sort.map do |c|
c.new(config)
end
end
@@ -305,10 +289,10 @@ module Jekyll
# Returns
def relative_permalinks_are_deprecated
if config['relative_permalinks']
- Jekyll.logger.abort_with "Since v3.0, permalinks for pages" +
- " in subfolders must be relative to the" +
- " site source directory, not the parent" +
- " directory. Check http://jekyllrb.com/docs/upgrading/"+
+ Jekyll.logger.abort_with "Since v3.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."
end
end
@@ -330,7 +314,7 @@ module Jekyll
end
def each_site_file
- %w(posts pages static_files docs_to_write).each do |type|
+ %w(pages static_files docs_to_write).each do |type|
send(type).each do |item|
yield item
end
@@ -348,8 +332,8 @@ module Jekyll
# Whether to perform a full rebuild without incremental regeneration
#
# Returns a Boolean: true for a full rebuild, false for normal build
- def full_rebuild?(override = {})
- override['full_rebuild'] || config['full_rebuild']
+ def incremental?(override = {})
+ override['incremental'] || config['incremental']
end
# Returns the publisher or creates a new publisher if it doesn't
@@ -391,8 +375,8 @@ module Jekyll
# Returns nothing
def limit_posts!
if limit_posts > 0
- limit = posts.length < limit_posts ? posts.length : limit_posts
- self.posts = posts[-limit, limit]
+ limit = posts.docs.length < limit_posts ? posts.docs.length : limit_posts
+ self.posts.docs = posts.docs[-limit, limit]
end
end
diff --git a/lib/jekyll/static_file.rb b/lib/jekyll/static_file.rb
index 48fa34c5..0ed0fbfe 100644
--- a/lib/jekyll/static_file.rb
+++ b/lib/jekyll/static_file.rb
@@ -1,7 +1,7 @@
module Jekyll
class StaticFile
# The cache of last modification times [path] -> mtime.
- @@mtimes = Hash.new
+ @@mtimes = {}
attr_reader :relative_path, :extname
@@ -75,7 +75,7 @@ module Jekyll
def write(dest)
dest_path = destination(dest)
- return false if File.exist?(dest_path) and !modified?
+ return false if File.exist?(dest_path) && !modified?
@@mtimes[path] = mtime
FileUtils.mkdir_p(File.dirname(dest_path))
@@ -90,7 +90,7 @@ module Jekyll
#
# Returns nothing.
def self.reset_cache
- @@mtimes = Hash.new
+ @@mtimes = {}
nil
end
@@ -104,12 +104,12 @@ module Jekyll
def placeholders
{
- collection: @collection.label,
- path: relative_path[
+ :collection => @collection.label,
+ :path => relative_path[
@collection.relative_directory.size..relative_path.size],
- output_ext: '',
- name: '',
- title: '',
+ :output_ext => '',
+ :name => '',
+ :title => ''
}
end
@@ -118,13 +118,13 @@ module Jekyll
# be overriden in the collection's configuration in _config.yml.
def url
@url ||= if @collection.nil?
- relative_path
- else
- ::Jekyll::URL.new({
- template: @collection.url_template,
- placeholders: placeholders,
- })
- end.to_s.gsub /\/$/, ''
+ relative_path
+ else
+ ::Jekyll::URL.new({
+ :template => @collection.url_template,
+ :placeholders => placeholders
+ })
+ end.to_s.gsub(/\/$/, '')
end
# Returns the type of the collection if present, nil otherwise.
diff --git a/lib/jekyll/stevenson.rb b/lib/jekyll/stevenson.rb
index 9a9f412e..d6dd5434 100644
--- a/lib/jekyll/stevenson.rb
+++ b/lib/jekyll/stevenson.rb
@@ -5,7 +5,7 @@ module Jekyll
@level = DEBUG
@default_formatter = Formatter.new
@logdev = $stdout
- @formatter = proc do |severity, datetime, progname, msg|
+ @formatter = proc do |_, _, _, msg|
"#{msg}"
end
end
@@ -14,7 +14,7 @@ module Jekyll
severity ||= UNKNOWN
@logdev = set_logdevice(severity)
- if @logdev.nil? or severity < @level
+ if @logdev.nil? || severity < @level
return true
end
progname ||= @progname
diff --git a/lib/jekyll/tags/highlight.rb b/lib/jekyll/tags/highlight.rb
index e644146f..a7dbd519 100644
--- a/lib/jekyll/tags/highlight.rb
+++ b/lib/jekyll/tags/highlight.rb
@@ -13,21 +13,21 @@ module Jekyll
def initialize(tag_name, markup, tokens)
super
if markup.strip =~ SYNTAX
- @lang = $1.downcase
- @options = {}
- if defined?($2) && $2 != ''
+ @lang = Regexp.last_match(1).downcase
+ @highlight_options = {}
+ if defined?(Regexp.last_match(2)) && Regexp.last_match(2) != ''
# Split along 3 possible forms -- key="", key=value, or key
- $2.scan(/(?:\w="[^"]*"|\w=\w|\w)+/) do |opt|
+ Regexp.last_match(2).scan(/(?:\w="[^"]*"|\w=\w|\w)+/) do |opt|
key, value = opt.split('=')
# If a quoted list, convert to array
if value && value.include?("\"")
- value.gsub!(/"/, "")
+ value.delete!('"')
value = value.split
end
- @options[key.to_sym] = value || true
+ @highlight_options[key.to_sym] = value || true
end
end
- @options[:linenos] = "inline" if @options.key?(:linenos) and @options[:linenos] == true
+ @highlight_options[:linenos] = "inline" if @highlight_options.key?(:linenos) && @highlight_options[:linenos] == true
else
raise SyntaxError.new <<-eos
Syntax Error in tag 'highlight' while parsing the following markup:
@@ -48,13 +48,13 @@ eos
output =
case context.registers[:site].highlighter
- when 'pygments'
- render_pygments(code, is_safe)
- when 'rouge'
- render_rouge(code)
- else
- render_codehighlighter(code)
- end
+ when 'pygments'
+ render_pygments(code, is_safe)
+ when 'rouge'
+ render_rouge(code)
+ else
+ render_codehighlighter(code)
+ end
rendered_output = add_code_tag(output)
prefix + rendered_output + suffix
@@ -64,11 +64,11 @@ eos
if is_safe
Hash[[
[:startinline, opts.fetch(:startinline, nil)],
- [:hl_linenos, opts.fetch(:hl_linenos, nil)],
+ [:hl_lines, opts.fetch(:hl_lines, nil)],
[:linenos, opts.fetch(:linenos, nil)],
[:encoding, opts.fetch(:encoding, 'utf-8')],
[:cssclass, opts.fetch(:cssclass, nil)]
- ].reject {|f| f.last.nil? }]
+ ].reject { |f| f.last.nil? }]
else
opts
end
@@ -80,7 +80,7 @@ eos
highlighted_code = Pygments.highlight(
code,
:lexer => @lang,
- :options => sanitized_opts(@options, is_safe)
+ :options => sanitized_opts(@highlight_options, is_safe)
)
if highlighted_code.nil?
@@ -88,7 +88,7 @@ eos
puts
Jekyll.logger.error code
puts
- Jekyll.logger.error "While attempting to convert the above code, Pygments.rb" +
+ Jekyll.logger.error "While attempting to convert the above code, Pygments.rb" \
" returned an unacceptable value."
Jekyll.logger.error "This is usually a timeout problem solved by running `jekyll build` again."
raise ArgumentError.new("Pygments.rb returned an unacceptable value when attempting to highlight some code.")
@@ -99,7 +99,7 @@ eos
def render_rouge(code)
Jekyll::External.require_with_graceful_fail('rouge')
- formatter = Rouge::Formatters::HTML.new(line_numbers: @options[:linenos], wrap: false)
+ formatter = Rouge::Formatters::HTML.new(:line_numbers => @highlight_options[:linenos], :wrap => false)
lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
formatter.format(lexer.lex(code))
end
@@ -110,12 +110,11 @@ eos
def add_code_tag(code)
code_attributes = [
- "class=\"language-#{@lang.to_s.gsub('+', '-')}\"",
- "data-lang=\"#{@lang.to_s}\""
+ "class=\"language-#{@lang.to_s.tr('+', '-')}\"",
+ "data-lang=\"#{@lang}\""
].join(" ")
"
#{code.chomp}
"
end
-
end
end
end
diff --git a/lib/jekyll/tags/include.rb b/lib/jekyll/tags/include.rb
index cbc59d44..847e6638 100644
--- a/lib/jekyll/tags/include.rb
+++ b/lib/jekyll/tags/include.rb
@@ -12,21 +12,19 @@ module Jekyll
end
class IncludeTag < Liquid::Tag
-
attr_reader :includes_dir
VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
- VARIABLE_SYNTAX = /(?[^{]*\{\{\s*(?[\w\-\.]+)\s*(\|.*)?\}\}[^\s}]*)(?.*)/
+ VARIABLE_SYNTAX = /(?[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)(?.*)/
def initialize(tag_name, markup, tokens)
super
- @includes_dir = tag_includes_dir
matched = markup.strip.match(VARIABLE_SYNTAX)
if matched
@file = matched['variable'].strip
@params = matched['params'].strip
else
- @file, @params = markup.strip.split(' ', 2);
+ @file, @params = markup.strip.split(' ', 2)
end
validate_params if @params
@tag_name = tag_name
@@ -44,12 +42,12 @@ module Jekyll
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
+ match[2].gsub(/\\"/, '"')
+ elsif match[3]
+ match[3].gsub(/\\'/, "'")
+ elsif match[4]
+ context[match[4]]
+ end
params[match[1]] = value
end
@@ -58,7 +56,7 @@ module Jekyll
def validate_file_name(file)
if file !~ /^[a-zA-Z0-9_\/\.-]+$/ || file =~ /\.\// || file =~ /\/\./
- raise ArgumentError.new <<-eos
+ raise ArgumentError.new <<-eos
Invalid syntax for include tag. File contains invalid characters or sequences:
#{file}
@@ -100,12 +98,13 @@ eos
end
end
- def tag_includes_dir
- '_includes'.freeze
+ def tag_includes_dir(context)
+ context.registers[:site].config['includes_dir'].freeze
end
def render(context)
site = context.registers[:site]
+ @includes_dir = tag_includes_dir(context)
dir = resolved_includes_dir(context)
file = render_variable(context) || @file
@@ -115,7 +114,7 @@ eos
validate_path(path, dir, site.safe)
# Add include to dependency tree
- if context.registers[:page] and context.registers[:page].has_key? "path"
+ if context.registers[:page] && context.registers[:page].key?("path")
site.regenerator.add_dependency(
site.in_source_dir(context.registers[:page]["path"]),
path
@@ -123,7 +122,7 @@ eos
end
begin
- partial = site.liquid_renderer.file(path).parse(read_file(path, context))
+ partial = load_cached_partial(path, context)
context.stack do
context['include'] = parse_params(context) if @params
@@ -134,6 +133,17 @@ eos
end
end
+ def load_cached_partial(path, context)
+ context.registers[:cached_partials] ||= {}
+ cached_partial = context.registers[:cached_partials]
+
+ if cached_partial.key?(path)
+ cached_partial[path]
+ else
+ cached_partial[path] = context.registers[:site].liquid_renderer.file(path).parse(read_file(path, context))
+ end
+ end
+
def resolved_includes_dir(context)
context.registers[:site].in_source_dir(@includes_dir)
end
@@ -161,7 +171,7 @@ eos
end
class IncludeRelativeTag < IncludeTag
- def tag_includes_dir
+ def tag_includes_dir(context)
'.'.freeze
end
diff --git a/lib/jekyll/tags/post_url.rb b/lib/jekyll/tags/post_url.rb
index ce97642f..b05d056b 100644
--- a/lib/jekyll/tags/post_url.rb
+++ b/lib/jekyll/tags/post_url.rb
@@ -7,22 +7,30 @@ module Jekyll
def initialize(name)
@name = name
+
all, @path, @date, @slug = *name.sub(/^\//, "").match(MATCHER)
- raise ArgumentError.new("'#{name}' does not contain valid date and/or title.") unless all
+ unless all
+ raise Jekyll::Errors::InvalidPostNameError,
+ "'#{name}' does not contain valid date and/or title."
+ end
@name_regex = /^#{path}#{date}-#{slug}\.[^.]+/
end
+ def post_date
+ @post_date ||= Utils.parse_date(date,
+ "\"#{date}\" does not contain valid date and/or title.")
+ end
+
def ==(other)
- other.name.match(@name_regex)
+ other.basename.match(@name_regex)
end
def deprecated_equality(other)
- date = Utils.parse_date(name, "'#{name}' does not contain valid date and/or title.")
slug == post_slug(other) &&
- date.year == other.date.year &&
- date.month == other.date.month &&
- date.day == other.date.day
+ post_date.year == other.date.year &&
+ post_date.month == other.date.month &&
+ post_date.day == other.date.day
end
private
@@ -32,11 +40,11 @@ module Jekyll
#
# Returns the post slug with the subdirectory (relative to _posts)
def post_slug(other)
- path = other.name.split("/")[0...-1].join("/")
+ path = other.basename.split("/")[0...-1].join("/")
if path.nil? || path == ""
- other.slug
+ other.data['slug']
else
- path + '/' + other.slug
+ path + '/' + other.data['slug']
end
end
end
@@ -47,11 +55,13 @@ module Jekyll
@orig_post = post.strip
begin
@post = PostComparer.new(@orig_post)
- rescue
- raise ArgumentError.new <<-eos
+ rescue => e
+ raise Jekyll::Errors::PostURLError, <<-eos
Could not parse name of post "#{@orig_post}" in tag 'post_url'.
Make sure the post exists and the name is correct.
+
+#{e.class}: #{e.message}
eos
end
end
@@ -59,26 +69,23 @@ eos
def render(context)
site = context.registers[:site]
- site.posts.each do |p|
- if @post == p
- return p.url
- end
+ site.posts.docs.each do |p|
+ return p.url if @post == p
end
# New matching method did not match, fall back to old method
# with deprecation warning if this matches
- site.posts.each do |p|
- if @post.deprecated_equality p
- Jekyll::Deprecator.deprecation_message "A call to '{{ post_url #{name} }}' did not match " +
- "a post using the new matching method of checking name " +
- "(path-date-slug) equality. Please make sure that you " +
- "change this tag to match the post's name exactly."
- return p.url
- end
+ site.posts.docs.each do |p|
+ next unless @post.deprecated_equality p
+ Jekyll::Deprecator.deprecation_message "A call to '{{ post_url #{@post.name} }}' did not match " \
+ "a post using the new matching method of checking name " \
+ "(path-date-slug) equality. Please make sure that you " \
+ "change this tag to match the post's name exactly."
+ return p.url
end
- raise ArgumentError.new <<-eos
+ raise Jekyll::Errors::PostURLError, <<-eos
Could not find post "#{@orig_post}" in tag 'post_url'.
Make sure the post exists and the name is correct.
diff --git a/lib/jekyll/url.rb b/lib/jekyll/url.rb
index 14b70631..09975e3d 100644
--- a/lib/jekyll/url.rb
+++ b/lib/jekyll/url.rb
@@ -11,7 +11,6 @@ require 'uri'
#
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
@@ -59,6 +58,14 @@ module Jekyll
#
# Returns the unsanitized String URL
def generate_url(template)
+ if @placeholders.is_a? Drops::UrlDrop
+ generate_url_from_drop(template)
+ else
+ generate_url_from_hash(template)
+ end
+ end
+
+ def generate_url_from_hash(template)
@placeholders.inject(template) do |result, token|
break result if result.index(':').nil?
if token.last.nil?
@@ -70,20 +77,22 @@ module Jekyll
end
end
- # Returns a sanitized String URL
- def sanitize_url(in_url)
- url = in_url \
- # Remove all double slashes
- .gsub(/\/\//, '/') \
- # Remove every URL segment that consists solely of dots
- .split('/').reject{ |part| part =~ /^\.+$/ }.join('/') \
- # Always add a leading slash
- .gsub(/\A([^\/])/, '/\1')
+ def generate_url_from_drop(template)
+ template.gsub(/:([a-z_]+)/.freeze) do |match|
+ replacement = @placeholders.public_send(match.sub(':'.freeze, ''.freeze))
+ if replacement.nil?
+ ''.freeze
+ else
+ self.class.escape_path(replacement)
+ end
+ end.gsub(/\/\//.freeze, '/'.freeze)
+ end
- # Append a trailing slash to the URL if the unsanitized URL had one
- url << "/" if in_url.end_with?("/")
+ # Returns a sanitized String URL, stripping "../../" and multiples of "/",
+ # as well as the beginning "/" so we can enforce and ensure it.
- url
+ def sanitize_url(str)
+ "/" + str.gsub(/\/{2,}/, "/").gsub(/\.+\/|\A\/+/, "")
end
# Escapes a path to be a valid URL path segment
diff --git a/lib/jekyll/utils.rb b/lib/jekyll/utils.rb
index cc01c8cc..179981ec 100644
--- a/lib/jekyll/utils.rb
+++ b/lib/jekyll/utils.rb
@@ -1,13 +1,37 @@
+
module Jekyll
- module Utils extend self
+ module Utils
+ extend self
autoload :Platforms, 'jekyll/utils/platforms'
+ autoload :Ansi, "jekyll/utils/ansi"
# Constants for use in #slugify
- SLUGIFY_MODES = %w{raw default pretty}
+ SLUGIFY_MODES = %w(raw default pretty)
SLUGIFY_RAW_REGEXP = Regexp.new('\\s+').freeze
SLUGIFY_DEFAULT_REGEXP = Regexp.new('[^[:alnum:]]+').freeze
SLUGIFY_PRETTY_REGEXP = Regexp.new("[^[:alnum:]._~!$&'()+,;=@]+").freeze
+ # Takes an indented string and removes the preceding spaces on each line
+
+ def strip_heredoc(str)
+ str.gsub(/^[ \t]{#{(str.scan(/^[ \t]*(?=\S)/).min || "").size}}/, "")
+ end
+
+ # Takes a slug and turns it into a simple title.
+
+ def titleize_slug(slug)
+ slug.split("-").map! do |val|
+ val.capitalize
+ end.join(" ")
+ end
+
+ # Non-destructive version of deep_merge_hashes! See that method.
+ #
+ # Returns the merged hashes.
+ def deep_merge_hashes(master_hash, other_hash)
+ deep_merge_hashes!(master_hash.dup, other_hash)
+ end
+
# Merges a master hash with another hash, recursively.
#
# master_hash - the "parent" hash whose values will be overridden
@@ -17,21 +41,26 @@ module Jekyll
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
#
# Thanks to whoever made it.
- def deep_merge_hashes(master_hash, other_hash)
- target = master_hash.dup
-
- other_hash.each_key do |key|
- if other_hash[key].is_a? Hash and target[key].is_a? Hash
- target[key] = Utils.deep_merge_hashes(target[key], other_hash[key])
- next
+ def deep_merge_hashes!(target, overwrite)
+ target.merge!(overwrite) do |key, old_val, new_val|
+ if new_val.nil?
+ old_val
+ else
+ mergable?(old_val) && mergable?(new_val) ? deep_merge_hashes(old_val, new_val) : new_val
end
+ end
- target[key] = other_hash[key]
+ if target.respond_to?(:default_proc) && overwrite.respond_to?(:default_proc) && target.default_proc.nil?
+ target.default_proc = overwrite.default_proc
end
target
end
+ def mergable?(value)
+ value.is_a?(Hash) || value.is_a?(Drops::Drop)
+ end
+
# Read array from the supplied hash favouring the singular key
# and then the plural key, and handling any nil entries.
#
@@ -47,7 +76,7 @@ module Jekyll
end
def value_from_singular_key(hash, key)
- hash[key] if (hash.key?(key) || (hash.default_proc && hash[key]))
+ hash[key] if hash.key?(key) || (hash.default_proc && hash[key])
end
def value_from_plural_key(hash, key)
@@ -98,24 +127,28 @@ module Jekyll
def parse_date(input, msg = "Input could not be parsed.")
Time.parse(input).localtime
rescue ArgumentError
- raise Errors::FatalException.new("Invalid date '#{input}': " + msg)
+ raise Errors::InvalidDateError, "Invalid date '#{input}': #{msg}"
end
# Determines whether a given file has
#
# Returns true if the YAML front matter is present.
def has_yaml_header?(file)
- !!(File.open(file, 'rb') { |f| f.read(5) } =~ /\A---\r?\n/)
+ !!(File.open(file, 'rb') { |f| f.readline } =~ /\A---\s*\r?\n/)
+ rescue EOFError
+ false
end
# Slugify a filename or title.
#
# string - the filename or title to slugify
# mode - how string is slugified
+ # cased - whether to replace all uppercase letters with their
+ # lowercase counterparts
#
- # When mode is "none", return the given string in lowercase.
+ # When mode is "none", return the given string.
#
- # When mode is "raw", return the given string in lowercase,
+ # When mode is "raw", return the given string,
# with every sequence of spaces characters replaced with a hyphen.
#
# When mode is "default" or nil, non-alphabetic characters are
@@ -124,6 +157,9 @@ module Jekyll
# When mode is "pretty", some non-alphabetic characters (._~!$&'()+,;=@)
# are not replaced with hyphen.
#
+ # If cased is true, all uppercase letters in the result string are
+ # replaced with their lowercase counterparts.
+ #
# Examples:
# slugify("The _config.yml file")
# # => "the-config-yml-file"
@@ -131,31 +167,39 @@ module Jekyll
# slugify("The _config.yml file", "pretty")
# # => "the-_config.yml-file"
#
+ # slugify("The _config.yml file", "pretty", true)
+ # # => "The-_config.yml file"
+ #
# Returns the slugified string.
- def slugify(string, mode=nil)
+ def slugify(string, mode: nil, cased: false)
mode ||= 'default'
return nil if string.nil?
- return string.downcase unless SLUGIFY_MODES.include?(mode)
- # Replace each character sequence with a hyphen
- re = case mode
- when 'raw'
- SLUGIFY_RAW_REGEXP
- when 'default'
- SLUGIFY_DEFAULT_REGEXP
- when 'pretty'
- # "._~!$&'()+,;=@" is human readable (not URI-escaped) in URL
- # and is allowed in both extN and NTFS.
- SLUGIFY_PRETTY_REGEXP
+ unless SLUGIFY_MODES.include?(mode)
+ return cased ? string : string.downcase
end
- string.
- # Strip according to the mode
- gsub(re, '-').
- # Remove leading/trailing hyphen
- gsub(/^\-|\-$/i, '').
- # Downcase
- downcase
+ # Replace each character sequence with a hyphen
+ re =
+ case mode
+ when 'raw'
+ SLUGIFY_RAW_REGEXP
+ when 'default'
+ SLUGIFY_DEFAULT_REGEXP
+ when 'pretty'
+ # "._~!$&'()+,;=@" is human readable (not URI-escaped) in URL
+ # and is allowed in both extN and NTFS.
+ SLUGIFY_PRETTY_REGEXP
+ end
+
+ # Strip according to the mode
+ slug = string.gsub(re, '-')
+
+ # Remove leading/trailing hyphen
+ slug.gsub!(/^\-|\-$/i, '')
+
+ slug.downcase! unless cased
+ slug
end
# Add an appropriate suffix to template so that it matches the specified
@@ -198,5 +242,47 @@ module Jekyll
template
end
+ # Work the same way as Dir.glob but seperating the input into two parts
+ # ('dir' + '/' + 'pattern') to make sure the first part('dir') does not act
+ # as a pattern.
+ #
+ # For example, Dir.glob("path[/*") always returns an empty array,
+ # because the method fails to find the closing pattern to '[' which is ']'
+ #
+ # Examples:
+ # safe_glob("path[", "*")
+ # # => ["path[/file1", "path[/file2"]
+ #
+ # safe_glob("path", "*", File::FNM_DOTMATCH)
+ # # => ["path/.", "path/..", "path/file1"]
+ #
+ # safe_glob("path", ["**", "*"])
+ # # => ["path[/file1", "path[/folder/file2"]
+ #
+ # dir - the dir where glob will be executed under
+ # (the dir will be included to each result)
+ # patterns - the patterns (or the pattern) which will be applied under the dir
+ # flags - the flags which will be applied to the pattern
+ #
+ # Returns matched pathes
+ def safe_glob(dir, patterns, flags = 0)
+ return [] unless Dir.exist?(dir)
+ pattern = File.join(Array patterns)
+ return [dir] if pattern.empty?
+ Dir.chdir(dir) do
+ Dir.glob(pattern, flags).map { |f| File.join(dir, f) }
+ end
+ end
+
+ # Returns merged option hash for File.read of self.site (if exists)
+ # and a given param
+ def merged_file_read_opts(site, opts)
+ merged = (site ? site.file_read_opts : {}).merge(opts)
+ if merged["encoding"] && !merged["encoding"].start_with?("bom|")
+ merged["encoding"].insert(0, "bom|")
+ end
+ merged
+ end
+
end
end
diff --git a/lib/jekyll/utils/ansi.rb b/lib/jekyll/utils/ansi.rb
new file mode 100644
index 00000000..933b4323
--- /dev/null
+++ b/lib/jekyll/utils/ansi.rb
@@ -0,0 +1,59 @@
+# Frozen-string-literal: true
+# Copyright: 2015 Jekyll - MIT License
+# Encoding: utf-8
+
+module Jekyll
+ module Utils
+ module Ansi
+ extend self
+
+ ESCAPE = format("%c", 27)
+ MATCH = /#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m/ix.freeze
+ COLORS = {
+ :red => 31,
+ :green => 32,
+ :black => 30,
+ :magenta => 35,
+ :yellow => 33,
+ :white => 37,
+ :blue => 34,
+ :cyan => 36
+ }
+
+ # Strip ANSI from the current string. It also strips cursor stuff,
+ # well some of it, and it also strips some other stuff that a lot of
+ # the other ANSI strippers don't.
+
+ def strip(str)
+ str.gsub MATCH, ""
+ end
+
+ #
+
+ def has?(str)
+ !!(str =~ MATCH)
+ end
+
+ # Reset the color back to the default color so that you do not leak any
+ # colors when you move onto the next line. This is probably normally
+ # used as part of a wrapper so that we don't leak colors.
+
+ def reset(str = "")
+ @ansi_reset ||= format("%c[0m", 27)
+ "#{@ansi_reset}#{str}"
+ end
+
+ # SEE: `self::COLORS` for a list of methods. They are mostly
+ # standard base colors supported by pretty much any xterm-color, we do
+ # not need more than the base colors so we do not include them.
+ # Actually... if I'm honest we don't even need most of the
+ # base colors.
+
+ COLORS.each do |color, num|
+ define_method color do |str|
+ "#{format("%c", 27)}[#{num}m#{str}#{reset}"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/utils/platforms.rb b/lib/jekyll/utils/platforms.rb
index 83858a07..d431021f 100644
--- a/lib/jekyll/utils/platforms.rb
+++ b/lib/jekyll/utils/platforms.rb
@@ -1,6 +1,7 @@
module Jekyll
module Utils
- module Platforms extend self
+ module Platforms
+ extend self
# Provides jruby? and mri? which respectively detect these two types of
# tested Engines we support, in the future we might probably support the
@@ -18,7 +19,6 @@ module Jekyll
{ :windows? => /mswin|mingw|cygwin/, :linux? => /linux/, \
:osx? => /darwin|mac os/, :unix? => /solaris|bsd/ }.each do |k, v|
-
define_method k do
!!(
RbConfig::CONFIG["host_os"] =~ v
diff --git a/lib/jekyll/version.rb b/lib/jekyll/version.rb
index 1e416f05..ba9ee238 100644
--- a/lib/jekyll/version.rb
+++ b/lib/jekyll/version.rb
@@ -1,3 +1,3 @@
module Jekyll
- VERSION = '3.0.0.pre.beta8'
+ VERSION = '3.1.2'
end
diff --git a/lib/site_template/_config.yml b/lib/site_template/_config.yml
index f4151011..1c5e5bc9 100644
--- a/lib/site_template/_config.yml
+++ b/lib/site_template/_config.yml
@@ -1,3 +1,10 @@
+# Welcome to Jekyll!
+#
+# This config file is meant for settings that affect your whole blog, values
+# which you are expected to set up once and rarely need to edit after that.
+# For technical reasons, this file is *NOT* reloaded automatically when you use
+# 'jekyll serve'. If you change this file, please restart the server process.
+
# Site settings
title: Your awesome title
email: your-email@domain.com
diff --git a/lib/site_template/_includes/footer.html b/lib/site_template/_includes/footer.html
index 8fa89ba9..1e4b2bc9 100644
--- a/lib/site_template/_includes/footer.html
+++ b/lib/site_template/_includes/footer.html
@@ -2,12 +2,12 @@
+## Custom WEBRick Headers
+
+You can provide custom headers for your site by adding them to `_config.yml`
+
+{% highlight yaml %}
+# File: _config.yml
+webrick:
+ headers:
+ My-Header: My-Value
+ My-Other-Header: My-Other-Value
+{% endhighlight %}
+
+### Defaults
+
+We only provide one default and that's a Content-Type header that disables
+caching in development so that you don't have to fight with Chrome's aggressive
+caching when you are in development mode.
+
+## Specifying a Jekyll environment at build time
+
+In the build (or serve) arguments, you can specify a Jekyll environment and value. The build will then apply this value in any conditional statements in your content.
+
+For example, suppose you set this conditional statement in your code:
+
+{% highlight liquid %}
+{% raw %}
+{% if jekyll.environment == "production" %}
+ {% include disqus.html %}
+{% endif %}
+{% endraw %}
+{% endhighlight %}
+
+When you build your Jekyll site, the content inside the `if` statement won't be run unless you also specify a `production` environment in the build command, like this:
+
+{% highlight sh %}
+JEKYLL_ENV=production jekyll build
+{% endhighlight %}
+
+Specifying an environment value allows you to make certain content available only within specific environments.
+
+The default value for `JEKYLL_ENV` is `development`. Therefore if you omit `JEKYLL_ENV` from the build arguments, the default value will be `JEKYLL_ENV=development`. Any content inside `{% raw %}{% if jekyll.environment == "development" %}{% endraw %}` tags will automatically appear in the build.
+
+Your environment values can be anything you want (not just `development` or `production`). Some elements you might want to hide in development environments include Disqus comment forms or Google Analytics. Conversely, you might want to expose an "Edit me in GitHub" button in a development environment but not include it in production environments.
+
+By specifying the option in the build command, you avoid having to change values in your configuration files when moving from one environment to another.
+
## Front Matter defaults
Using [YAML Front Matter](../frontmatter/) is one way that you can specify configuration in the pages and posts for your site. Setting things like a default layout, or customizing the title, or specifying a more precise date/time for the post can all be added to your page or post front matter.
@@ -399,7 +489,7 @@ With these defaults, all posts would use the `my-site` layout. Any html files th
{% highlight yaml %}
collections:
- my_collection:
- output: true
+ output: true
defaults:
-
@@ -410,13 +500,14 @@ defaults:
layout: "default"
{% endhighlight %}
-In this example the `layout` is set to `default` inside the [collection](../collections/) with the name `my_collection`.
+In this example, the `layout` is set to `default` inside the
+[collection](../collections/) with the name `my_collection`.
### Precedence
Jekyll will apply all of the configuration settings you specify in the `defaults` section of your `_config.yml` file. However, you can choose to override settings from other scope/values pair by specifying a more specific path for the scope.
-You can see that in the last example above. First, we set the default layout to `my-site`. Then, using a more specific path, we set the default layout for files in the `projects/` path to `project`. This can be done with any value that you would set in the page or post front matter.
+You can see that in the second to last example above. First, we set the default layout to `my-site`. Then, using a more specific path, we set the default layout for files in the `projects/` path to `project`. This can be done with any value that you would set in the page or post front matter.
Finally, if you set defaults in the site configuration by adding a `defaults` section to your `_config.yml` file, you can override those settings in a post or page file. All you need to do is specify the settings in the post or page front matter. For example:
@@ -465,12 +556,13 @@ file or on the command-line.
{% highlight yaml %}
# Where things are
-source: .
-destination: ./_site
-plugins: ./_plugins
-layouts: ./_layouts
-data_source: ./_data
-collections: null
+source: .
+destination: ./_site
+plugins_dir: ./_plugins
+layouts_dir: ./_layouts
+data_dir: ./_data
+includes_dir: ./_includes
+collections: null
# Handling Reading
safe: false
@@ -483,7 +575,7 @@ markdown_ext: "markdown,mkdown,mkdn,mkd,md"
# Filtering Content
show_drafts: null
limit_posts: 0
-future: true
+future: false
unpublished: false
# Plugins
@@ -495,6 +587,7 @@ markdown: kramdown
highlighter: rouge
lsi: false
excerpt_separator: "\n\n"
+incremental: false
# Serving
detach: false
@@ -586,7 +679,7 @@ extensions are:
### Kramdown
In addition to the defaults mentioned above, you can also turn on recognition
-of Github Flavored Markdown by passing an `input` option with a value of "GFM".
+of GitHub Flavored Markdown by passing an `input` option with a value of "GFM".
For example, in your `_config.yml`:
@@ -614,9 +707,41 @@ class Jekyll::Converters::Markdown::MyCustomProcessor
end
{% endhighlight %}
-Once you've created your class and have it properly setup either as a plugin in
-the `_plugins` folder or as a gem, specify it in your `_config.yml`:
+Once you've created your class and have it properly set up either as a plugin
+in the `_plugins` folder or as a gem, specify it in your `_config.yml`:
{% highlight yaml %}
markdown: MyCustomProcessor
{% endhighlight %}
+
+## Incremental Regeneration
+
+
Incremental regeneration is still an experimental feature
+
+ While incremental regeneration will work for the most common cases, it will
+ not work correctly in every scenario. Please be extremely cautious when
+ using the feature, and report any problems not listed below by
+ opening an issue on GitHub.
+
+
+
+Incremental regeneration helps shorten build times by only generating documents
+and pages that were updated since the previous build. It does this by keeping
+track of both file modification times and inter-document dependencies in the
+`.jekyll-metadata` file.
+
+Under the current implementation, incremental regeneration will only generate a
+document or page if either it, or one of its dependencies, is modified. Currently,
+the only types of dependencies tracked are includes (using the
+{% raw %}`{% include %}`{% endraw %} tag) and layouts. This means that plain
+references to other documents (for example, the common case of iterating over
+`site.posts` in a post listings page) will not be detected as a dependency.
+
+To remedy some of these shortfalls, putting `regenerate: true` in the front-matter
+of a document will force Jekyll to regenerate it regardless of whether it has been
+modified. Note that this will generate the specified document only; references
+to other documents' contents will not work since they won't be re-rendered.
+
+Incremental regeneration can be enabled via the `--incremental` flag (`-I` for
+short) from the command-line or by setting `incremental: true` in your
+configuration file.
diff --git a/site/_docs/continuous-integration.md b/site/_docs/continuous-integration.md
index 18506077..587ecdab 100644
--- a/site/_docs/continuous-integration.md
+++ b/site/_docs/continuous-integration.md
@@ -31,9 +31,11 @@ does ensure things are built properly.
When testing Jekyll output, there is no better tool than [html-proofer][2].
This tool checks your resulting site to ensure all links and images exist.
-Utilize it either with the convenient `htmlproof` command-line executable,
+Utilize it either with the convenient `htmlproofer` command-line executable,
or write a Ruby script which utilizes the gem.
+Save the commands you want to run and succeed in a file: `./script/cibuild`
+
### The HTML Proofer Executable
{% highlight bash %}
@@ -41,12 +43,18 @@ or write a Ruby script which utilizes the gem.
set -e # halt script on error
bundle exec jekyll build
-bundle exec htmlproof ./_site
+bundle exec htmlproofer ./_site
{% endhighlight %}
Some options can be specified via command-line switches. Check out the
`html-proofer` README for more information about these switches, or run
-`htmlproof --help` locally.
+`htmlproofer --help` locally.
+
+For example to avoid testing external sites, use this command:
+
+{% highlight bash %}
+$ bundle exec htmlproofer ./_site --disable-external
+{% endhighlight %}
### The HTML Proofer Library
@@ -72,7 +80,7 @@ with Ruby and requires RubyGems to install, we use the Ruby language build
environment. Below is a sample `.travis.yml` file, followed by
an explanation of each line.
-**Note:** You will need a Gemfile as well, [Travis will automatically install](http://docs.travis-ci.com/user/languages/ruby/#Dependency-Management) the dependencies based on the referenced gems:
+**Note:** You will need a Gemfile as well, [Travis will automatically install](https://docs.travis-ci.com/user/languages/ruby/#Dependency-Management) the dependencies based on the referenced gems:
{% highlight ruby %}
source "https://rubygems.org"
@@ -81,15 +89,21 @@ gem "jekyll"
gem "html-proofer"
{% endhighlight %}
+Your `.travis.yml` file should look like this:
{% highlight yaml %}
language: ruby
rvm:
- 2.1
-# Assume bundler is being used, install step will run `bundle install`.
+
+before_script:
+ - chmod +x ./script/cibuild # or do this locally and commit
+
+# Assume bundler is being used, therefore
+# the `install` step will run `bundle install` by default.
script: ./script/cibuild
-# branch whitelist
+# branch whitelist, only for GitHub Pages
branches:
only:
- gh-pages # test the gh-pages branch
@@ -98,6 +112,8 @@ branches:
env:
global:
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true # speeds up installation of html-proofer
+
+sudo: false # route your build to the container-based infrastructure for a faster build
{% endhighlight %}
Ok, now for an explanation of each line:
@@ -118,6 +134,16 @@ RVM is a popular Ruby Version Manager (like rbenv, chruby, etc). This
directive tells Travis the Ruby version to use when running your test
script.
+{% highlight yaml %}
+before_script:
+ - chmod +x ./script/cibuild
+{% endhighlight %}
+
+The build script file needs to have the *executable* attribute set or
+Travis will fail with a permission denied error. You can also run this
+locally and commit the permissions directly, thus rendering this step
+irrelevant.
+
{% highlight yaml %}
script: ./script/cibuild
{% endhighlight %}
@@ -130,13 +156,13 @@ incantation here directly:
{% highlight yaml %}
install: gem install jekyll html-proofer
-script: jekyll build && htmlproof ./_site
+script: jekyll build && htmlproofer ./_site
{% endhighlight %}
The `script` directive can be absolutely any valid shell command.
{% highlight yaml %}
-# branch whitelist
+# branch whitelist, only for GitHub Pages
branches:
only:
- gh-pages # test the gh-pages branch
@@ -152,7 +178,8 @@ a pull request flow for proposing changes, you may wish to enforce a
convention for your builds such that all branches containing edits are
prefixed, exemplified above with the `/pages-(.*)/` regular expression.
-The `branches` directive is completely optional.
+The `branches` directive is completely optional. Travis will build from every
+push to any branch of your repo if leave it out.
{% highlight yaml %}
env:
@@ -177,10 +204,30 @@ environment variable `NOKOGIRI_USE_SYSTEM_LIBRARIES` to `true`.
exclude: [vendor]
{% endhighlight %}
+By default you should supply the `sudo: false` command to Travis. This command
+explicitly tells Travis to run your build on Travis's [container-based
+ infrastructure](https://docs.travis-ci.com/user/workers/container-based-infrastructure/#Routing-your-build-to-container-based-infrastructure). Running on the container-based infrastructure can often times
+speed up your build. If you have any trouble with your build, or if your build
+does need `sudo` access, modify the line to `sudo: required`.
+
+{% highlight yaml %}
+sudo: false
+{% endhighlight %}
+
+### Troubleshooting
+
+**Travis error:** *"You are trying to install in deployment mode after changing
+your Gemfile. Run bundle install elsewhere and add the updated Gemfile.lock
+to version control."*
+
+**Workaround:** Either run `bundle install` locally and commit your changes to
+`Gemfile.lock`, or remove the `Gemfile.lock` file from your repository and add
+an entry in the `.gitignore` file to avoid it from being checked in again.
+
### Questions?
This entire guide is open-source. Go ahead and [edit it][3] if you have a
fix or [ask for help][4] if you run into trouble and need some help.
[3]: https://github.com/jekyll/jekyll/edit/master/site/_docs/continuous-integration.md
-[4]: https://github.com/jekyll/jekyll-help#how-do-i-ask-a-question
+[4]: http://jekyllrb.com/help/
diff --git a/site/_docs/contributing.md b/site/_docs/contributing.md
index 150525fb..67dc954b 100644
--- a/site/_docs/contributing.md
+++ b/site/_docs/contributing.md
@@ -1,132 +1,127 @@
---
-layout: docs
title: Contributing
-permalink: /docs/contributing/
+layout: docs
+permalink: "/docs/contributing/"
+note: This file is autogenerated. Edit /.github/CONTRIBUTING.markdown instead.
---
-So you've got an awesome idea to throw into Jekyll. Great! Please keep the
-following in mind:
+Hi there! Interested in contributing to Jekyll? We'd love your help. Jekyll is an open source project, built one contribution at a time by users like you.
-* 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](https://github.com/thoughtbot/shoulda/tree/master) and
- [RSpec Mocks](https://github.com/rspec/rspec-mocks/).
-* 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.
+## Where to get help or report a problem
-
-
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.
-
-
+* If you have a question about using Jekyll, start a discussion on [Jekyll Talk](https://talk.jekyllrb.com).
+* If you think you've found a bug within a Jekyll plugin, open an issue in that plugin's repository.
+* If you think you've found a bug within Jekyll itself, [open an issue](https://github.com/jekyll/jekyll/issues/new)
+* More resources are listed on our [Help page](https://jekyllrb.com/help/)
-Test Dependencies
------------------
+## Ways to contribute
-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!
+Whether you're a developer, a designer, or just a Jekyll devotee, there are lots of ways to contribute. Here's a few ideas:
-{% highlight bash %}
-$ bundle
-{% endhighlight %}
+* [Install Jekyll on your computer](https://jekyllrb.com/docs/installation/) and kick the tires. Does it work? Does it do what you'd expect? If not, [open an issue](https://github.com/jekyll/jekyll/issues/new) and let us know.
+* Comment on some of the project's [open issues](https://github.com/jekyll/jekyll/issues). Have you experienced the same problem? Know a work around? Do you have a suggestion for how the feature could be better?
+* Read through [the documentation](https://jekyllrb.com/docs/home/), and click the "improve this page" button, any time you see something confusing, or have a suggestion for something that could be improved.
+* Browse through [the Jekyll discussion forum](https://talk.jekyllrb.com/), and lend a hand answering questions. There's a good chance you've already experienced what another user is experiencing.
+* Find [an open issue](https://github.com/jekyll/jekyll/issues) (especially [those labeled `help-wanted`](https://github.com/jekyll/jekyll/issues?q=is%3Aopen+is%3Aissue+label%3Ahelp-wanted)), and submit a proposed fix. If it's your first pull request, we promise we won't bite, and are glad to answer any questions.
+* Help evaluate [open pull requests](https://github.com/jekyll/jekyll/pulls), by testing the changes locally and reviewing what's proposed.
-Before you start, run the tests and make sure that they pass (to confirm your
-environment is configured properly):
+## Submitting a pull request
-{% highlight bash %}
-$ bundle exec rake test
-$ bundle exec rake features
-{% endhighlight %}
+### Pull requests generally
-Workflow
---------
+* The smaller the proposed change, the better. If you'd like to propose two unrelated changes, submit two pull requests.
-Here's the most direct way to get your work merged into the project:
+* The more information, the better. Make judicious use of the pull request body. Describe what changes were made, why you made them, and what impact they will have for users.
-* Fork the project.
-* Clone down your fork:
+* Pull request are easy and fun. If this is your first pull request, it may help to [understand GitHub Flow](https://guides.github.com/introduction/flow/)
-{% highlight bash %}
-git clone git://github.com//jekyll.git
-{% endhighlight %}
+* If you're submitting a code contribution, be sure to read the [code contributions](#code-contributions) section below.
-* Create a topic branch to contain your change:
+### Submitting a pull request via github.com
-{% highlight bash %}
-git checkout -b my_awesome_feature
-{% endhighlight %}
+Many small changes can be made entirely through the github.com web interface.
+1. Navigate to the file within [`jekyll/jekyll`](https://github.com/jekyll/jekyll) that you'd like to edit
+2. Click the pencil icon in the top right corner to edit the file
+3. Make your proposed changes
+4. Click "Propose file change"
+5. Click "Create pull request"
+6. Add a descriptive title and detailed description for your proposed change. The more information the better.
+7. Click "Create pull request"
-* 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:
+That's it! You'll be automatically subscribed to receive updates as others review your proposed change and provide feedback.
-{% highlight bash %}
-git push origin my_awesome_feature
-{% endhighlight %}
+### Submitting a pull request via Git command line
-* Create a pull request against jekyll/jekyll:master and describe what your
- change does and the why you think it should be merged.
+1. Fork the project by clicking "Fork" in the top right corner of [`jekyll/jekyll`](https://github.com/jekyll/jekyll)
+2. Clone the repository lcoally `git clone https://github.com//jekyll`
+3. Create a new, descriptively named branch to contain your change ( `git checkout -b my-awesome-feature` ).
+4. Hack away, add tests. Not necessarily in that order.
+5. Make sure everything still passes by running `script/cibuild` (see [the tests section](#running-tests-locally) below)
+6. Push the branch up ( `git push origin my-awesome-feature` ).
+7. Create a pull request by visiting https://github.com//jekyll/ and following the instructions at the top of the screen.
-Updating Documentation
-----------------------
+## Proposing updates to the 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.
+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.
+### How to submit changes
-All documentation pull requests should be directed at `master`. Pull
-requests directed at another branch will not be accepted.
+You can find the documentation for jekyllrb.com in the [site](https://github.com/jekyll/jekyll/tree/master/site) directory. See the section above, [submitting a pull request](#submitting-a-pull-request) for information on how to propose a change.
-The [Jekyll wiki]({{ site.repository }}/wiki) on GitHub
-can be freely updated without a pull request as all
-GitHub users have access.
+One gotcha, all pull requests should be directed at the `master` branch (the default branch).
-If you want to add your plugin to the [list of plugins](/docs/plugins/#available-plugins),
-please submit a pull request modifying the [plugins page source
-file]({{ site.repository }}/blob/master/site/_docs/plugins.md) by adding a
-link to your plugin under the proper subheading depending upon its type.
+### Adding plugins
-Gotchas
--------
+If you want to add your plugin to the [list of plugins](https://jekyllrb.com/docs/plugins/#available-plugins), please submit a pull request modifying the [plugins page source file](site/_docs/plugins.md) by adding a link to your plugin under the proper subheading depending upon its type.
-* 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 jekyll/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.
+## Code Contributions
-
-
Let us know what could be better!
-
- Both using and hacking on Jekyll should be fun, simple, and easy, so if for
- some reason you find it’s a pain, please create an issue on
- GitHub describing your experience so we can make it better.
-
-
+Interesting in submitting a pull request? Awesome. Read on. There's a few common gotchas that we'd love to help you avoid.
+
+### Tests and documentation
+
+Any time you propose a code change, you should also include updates to the documentation and tests within the same pull request.
+
+#### Documentation
+
+If your contribution changes any Jekyll behavior, make sure to update the documentation. Documentation lives in the `site/_docs` folder (spoiler alert: it's a Jekyll site!). If the docs are missing information, please feel free to add it in. Great docs make a great project. Include changes to the documentation within your pull request, and once merged, `jekyllrb.com` will be updated.
+
+#### Tests
+
+* If you're creating a small fix or patch to an existing feature, a simple test if more than enough. You can usually copy/paste from an existing example in the `tests` folder, but if you need to can find out about our tests suites [Shoulda](https://github.com/thoughtbot/shoulda/tree/master) and [RSpec-Mocks](https://github.com/rspec/rspec-mocks).
+
+* If it's a brand new feature, create a new [Cucumber](https://github.com/cucumber/cucumber/) feature, reusing existing steps where appropriate.
+
+### Code contributions generally
+
+* Jekyll follows the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby).
+
+* Don't bump the Gem version in your pull request (if you don't know what that means, you probably didn't).
+
+## Running tests locally
+
+### Test Dependencies
+
+To run the test suite and build the gem you'll need to install Jekyll's dependencies by running the following command:
+
+ $ script/bootstrap
+
+Before you make any changes, run the tests and make sure that they pass (to confirm your environment is configured properly):
+
+ $ script/cibuild
+
+If you are only updating a file in `test/`, you can use the command:
+
+ $ script/test test/blah_test.rb
+
+If you are only updating a `.feature` file, you can use the command:
+
+ $ script/cucumber features/blah.feature
+
+Both `script/test` and `script/cucumber` can be run without arguments to
+run its entire respective suite.
+
+## A thank you
+
+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/site/_docs/datafiles.md b/site/_docs/datafiles.md
index afa54b8f..4fd85b48 100644
--- a/site/_docs/datafiles.md
+++ b/site/_docs/datafiles.md
@@ -33,8 +33,8 @@ of code in your Jekyll templates:
In `_data/members.yml`:
{% highlight yaml %}
-- name: Tom Preston-Werner
- github: mojombo
+- name: Eric Mill
+ github: konklone
- name: Parker Moore
github: parkr
@@ -47,7 +47,7 @@ Or `_data/members.csv`:
{% highlight text %}
name,github
-Tom Preston-Werner,mojombo
+Eric Mill,konklone
Parker Moore,parkr
Liu Fengyun,liufengyun
{% endhighlight %}
diff --git a/site/_docs/deployment-methods.md b/site/_docs/deployment-methods.md
index d9dd7ea2..f10b48b7 100644
--- a/site/_docs/deployment-methods.md
+++ b/site/_docs/deployment-methods.md
@@ -25,7 +25,8 @@ There are also a number of ways to easily automate the deployment of a Jekyll si
### 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
+If you store your Jekyll site in [Git](https://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/).
@@ -84,16 +85,102 @@ host your site directly on a CDN or file host like S3.
Setup steps are fully documented
[in the `jekyll-hook` repo](https://github.com/developmentseed/jekyll-hook).
+### Static Publisher
+
+[Static Publisher](https://github.com/static-publisher/static-publisher) is another automated deployment option with a server listening for webhook posts, though it's not tied to GitHub specifically. It has a one-click deploy to Heroku, it can watch multiple projects from one server, it has an easy to user admin interface and can publish to either S3 or to a git repository (e.g. gh-pages).
+
### Rake
-Another way to deploy your Jekyll site is to use [Rake](https://github.com/jimweirich/rake), [HighLine](https://github.com/JEG2/highline), and
+Another way to deploy your Jekyll site is to use [Rake](https://github.com/ruby/rake), [HighLine](https://github.com/JEG2/highline), and
[Net::SSH](https://github.com/net-ssh/net-ssh). 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).
+
+### scp
+
+Once you’ve generated the `_site` directory, you can easily scp it using a
+`tasks/deploy` shell script similar to [this deploy script][]. You’d obviously
+need to change the values to reflect your site’s details. There is even [a
+matching TextMate command][] that will help you run this script.
+
+[this deploy script here]: https://github.com/henrik/henrik.nyh.se/blob/master/script/deploy
+
+[a matching TextMate command]: https://gist.github.com/henrik/214959
+
### 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](https://github.com/henrik/henrik.nyh.se/blob/master/script/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.
+Once you’ve generated the `_site` directory, you can easily rsync it using a `tasks/deploy` shell script similar to [this deploy script here](https://github.com/vitalyrepin/vrepinblog/blob/master/transfer.sh). You’d obviously need to change the values to reflect your site’s details.
+Certificate-based authorization is another way to simplify the publishing
+process. It makes sense to restrict rsync access only to the directory which it is supposed to sync. This can be done using rrsync.
+
+#### Step 1: Install rrsync to your home folder (server-side)
+
+If it is not already installed by your host, you can do it yourself:
+
+- [Download rrsync](https://ftp.samba.org/pub/unpacked/rsync/support/rrsync)
+- Place it in the `bin` subdirectory of your home folder (`~/bin`)
+- Make it executable (`chmod +x`)
+
+#### Step 2: Set up certificate-based SSH access (server side)
+
+This [process](https://wiki.gentoo.org/wiki/SSH#Passwordless_Authentication) is
+described in several places online. What is different from the typical approach
+is to put the restriction to certificate-based authorization in
+`~/.ssh/authorized_keys`. Then, launch `rrsync` and supply
+it with the folder it shall have read-write access to:
+
+{% highlight bash %}
+command="$HOME/bin/rrsync ",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa
+{% endhighlight %}
+
+`` is the path to your site. E.g., `~/public_html/you.org/blog-html/`.
+
+#### Step 3: Rsync (client-side)
+
+Add the `deploy` script to the site source folder:
+
+{% highlight bash %}
+#!/bin/sh
+
+rsync -crvz --rsh=ssh -p2222' --delete-after --delete-excluded @:
+{% endhighlight %}
+
+Command line parameters are:
+
+- `--rsh=ssh -p2222` — The port for SSH access. It is required if
+your host uses a different port than the default (e.g, HostGator)
+- `` — The name of the local output folder (defaults to `_site`)
+- `` — The username for your hosting account
+- `` — Your hosting server
+
+Using this setup, you might run the following command:
+
+{% highlight bash %}
+rsync -crvz --rsh='ssh -p2222' --delete-after --delete-excluded _site/ hostuser@example.org:
+{% endhighlight %}
+
+Don't forget the column `:` after server name!
+
+#### Step 4 (Optional): Exclude the transfer script from being copied to the output folder.
+
+This step is recommended if you use these instructions to deploy your site. If
+you put the `deploy` script in the root folder of your project, Jekyll will
+copy it to the output folder. This behavior can be changed in `_config.yml`.
+
+Just add the following line:
+
+{% highlight yaml %}
+# Do not copy these files to the output directory
+exclude: ["deploy"]
+{% endhighlight %}
+
+Alternatively, you can use an `rsync-exclude.txt` file to control which files will be transferred to your server.
+
+#### Done!
+
+Now it's possible to publish your website simply by running the `deploy`
+script. If your SSH certificate is [passphrase-protected](https://martin.kleppmann.com/2013/05/24/improving-security-of-ssh-private-keys.html), you will be asked to enter it when the
+script executes.
## Rack-Jekyll
@@ -124,3 +211,17 @@ for that](https://github.com/openshift-cartridges/openshift-jekyll-cartridge).
ProTip™: Use GitHub Pages for zero-hassle Jekyll hosting
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 host your Jekyll-powered website for free.
+
+## Kickster
+
+Use [Kickster](http://kickster.nielsenramon.com/) for easy (automated) deploys to GitHub Pages when using unsupported plugins on GitHub Pages.
+
+Kickster provides a basic Jekyll project setup packed with web best practises and useful optimization tools increasing your overall project quality. Kickster ships with automated and worry-free deployment scripts for GitHub Pages.
+
+Setting up Kickster is very easy, just install the gem and you are good to go. More documentation can here found [here](https://github.com/nielsenramon/kickster#kickster). If you do not want to use the gem or start a new project you can just copy paste the deployment scripts for [Travis CI](https://github.com/nielsenramon/kickster/tree/master/snippets/travis) or [Circle CI](https://github.com/nielsenramon/kickster#automated-deployment-with-circle-ci).
+
+## Aerobatic
+
+[Aerobatic](https://www.aerobatic.com) is an add-on for Bitbucket that brings GitHub Pages style functionality to Bitbucket users. It includes continuous deployment, custom domains with a wildcard SSL cert, CDN, basic auth, and staging branches all in the box.
+
+Automating the build and deployment of a Jekyll site is just as simple as GitHub Pages - push your changes to your repo (excluding the `_site` directory) and within seconds a build will be triggered and your built site deployed to our highly- available, globally distributed hosting service. The build process will even install and execute custom Ruby plugins. See our [Jekyll docs](https://www.aerobatic.com/docs/static-generators#jekyll) for more details.
diff --git a/site/_docs/extras.md b/site/_docs/extras.md
index 2af6a305..5abd0d73 100644
--- a/site/_docs/extras.md
+++ b/site/_docs/extras.md
@@ -9,7 +9,13 @@ may want to install, depending on how you plan to use Jekyll.
## Math Support
-Kramdown comes with optional support for LaTeX to PNG rendering via [MathJax](http://www.mathjax.org/) within math blocks. See the Kramdown documentation on [math blocks](http://kramdown.gettalong.org/syntax.html#math-blocks) and [math support](http://kramdown.gettalong.org/converter/html.html#math-support) for more details.
+Kramdown comes with optional support for LaTeX to PNG rendering via [MathJax](https://www.mathjax.org) within math blocks. See the Kramdown documentation on [math blocks](http://kramdown.gettalong.org/syntax.html#math-blocks) and [math support](http://kramdown.gettalong.org/converter/html.html#math-support) for more details. MathJax requires you to include JavaScript or CSS to render the LaTeX, e.g.
+
+{% highlight html %}
+
+{% endhighlight %}
+
+For more information about getting started, check out [this excellent blog post](http://gastonsanchez.com/opinion/2014/02/16/Mathjax-with-jekyll/).
## Alternative Markdown Processors
diff --git a/site/_docs/frontmatter.md b/site/_docs/frontmatter.md
index 7d27dc07..755f0bc6 100644
--- a/site/_docs/frontmatter.md
+++ b/site/_docs/frontmatter.md
@@ -108,8 +108,8 @@ front matter of a page or post.
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 YAML list or a
- space-separated string.
+ href="https://en.wikipedia.org/wiki/YAML#Lists">YAML list or a
+ comma-separated string.
@@ -123,7 +123,7 @@ front matter of a page or post.
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.
+ comma-separated string.
diff --git a/site/_docs/github-pages.md b/site/_docs/github-pages.md
index 86e9682a..cfe8822a 100644
--- a/site/_docs/github-pages.md
+++ b/site/_docs/github-pages.md
@@ -4,12 +4,37 @@ title: GitHub Pages
permalink: /docs/github-pages/
---
-[GitHub Pages](http://pages.github.com) are public web pages for users,
+[GitHub Pages](https://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.
+Never built a website with GitHub Pages before? [See this marvelous guide by
+Jonathan McGlone to get you up and running](http://jmcglone.com/guides/github-pages/).
+This guide will teach you what you need to know about Git, GitHub, and Jekyll to
+create your very own website on GitHub Pages.
+
+### 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. In order to assure your
+site builds properly, use `site.github.url` in your URL's.
+
+{% highlight html %}
+{% raw %}
+
+
+
+{{ page.title }}
+{% endraw %}
+{% endhighlight %}
+
+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 resolve properly.
+
## Deploying Jekyll to GitHub Pages
GitHub Pages work by looking at certain branches of repositories on GitHub.
@@ -41,6 +66,16 @@ gem 'github-pages', versions['github-pages']
This will ensure that when you run bundle install, you
have the correct version of the github-pages gem.
+
+ If that fails, simplify it:
+
+{% highlight ruby %}
+source 'https://rubygems.org'
+
+gem 'github-pages'
+{% endhighlight %}
+
+ And be sure to run bundle update often.
@@ -82,42 +117,16 @@ branch]({{ site.repository }}/tree/gh-pages) of the same repository.
Source Files Must be in the Root Directory
-Github Pages overrides the “Site Source” configuration value, so if you locate your files anywhere other than the root directory, your site may not build correctly.
+GitHub Pages overrides the “Site Source” configuration value, so if you locate your files anywhere other than the root directory, your site may not build correctly.
-
-### 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.
-
diff --git a/site/_docs/history.md b/site/_docs/history.md
index 346dc131..175a3b1a 100644
--- a/site/_docs/history.md
+++ b/site/_docs/history.md
@@ -1,9 +1,515 @@
---
-layout: docs
title: History
+layout: docs
permalink: "/docs/history/"
+note: This file is autogenerated. Edit /History.markdown instead.
---
+## 3.1.2 / 2016-02-19
+{: #v3-1-2}
+
+### Minor Enhancements
+{: #minor-enhancements-v3-1-2}
+
+- Include `.rubocop.yml` in Gem ([#4437]({{ site.repository }}/issues/4437))
+- `LiquidRenderer#parse`: parse with line numbers. ([#4452]({{ site.repository }}/issues/4452))
+- Add consistency to the no-subcommand deprecation message ([#4505]({{ site.repository }}/issues/4505))
+
+### Bug Fixes
+{: #bug-fixes-v3-1-2}
+
+- Fix syntax highlighting in kramdown by making `[@config](https://github.com/config)` accessible in the Markdown converter. ([#4428]({{ site.repository }}/issues/4428))
+- `Jekyll.sanitized_path`: sanitizing a questionable path should handle tildes ([#4492]({{ site.repository }}/issues/4492))
+- Fix `titleize` so already capitalized words are not dropped ([#4525]({{ site.repository }}/issues/4525))
+- Permalinks which end in a slash should always output HTML ([#4546]({{ site.repository }}/issues/4546))
+
+### Development Fixes
+{: #development-fixes-v3-1-2}
+
+- Require at least cucumber version 2.1.0 ([#4514]({{ site.repository }}/issues/4514))
+
+### Site Enhancements
+{: #site-enhancements-v3-1-2}
+
+- Add jekyll-toc plugin ([#4429]({{ site.repository }}/issues/4429))
+- Docs: Quickstart - added documentation about the `--force` option ([#4410]({{ site.repository }}/issues/4410))
+- Fix broken links to the Code of Conduct ([#4436]({{ site.repository }}/issues/4436))
+- Upgrade notes: mention trailing slash in permalink; fixes [#4440]({{ site.repository }}/issues/4440) ([#4455]({{ site.repository }}/issues/4455))
+- Add hooks to the plugin categories toc ([#4463]({{ site.repository }}/issues/4463))
+- [add note] Jekyll 3 requires newer version of Ruby. ([#4461]({{ site.repository }}/issues/4461))
+- Fix typo in upgrading docs ([#4473]({{ site.repository }}/issues/4473))
+- Add note about upgrading documentation on jekyllrb.com/help/ ([#4484]({{ site.repository }}/issues/4484))
+- Update Rake link ([#4496]({{ site.repository }}/issues/4496))
+- Update & prune the short list of example sites ([#4374]({{ site.repository }}/issues/4374))
+- Added amp-jekyll plugin to plugins docs ([#4517]({{ site.repository }}/issues/4517))
+- A few grammar fixes ([#4512]({{ site.repository }}/issues/4512))
+- Correct a couple mistakes in structure.md ([#4522]({{ site.repository }}/issues/4522))
+
+
+## 3.1.1 / 2016-01-29
+{: #v3-1-1}
+
+### Meta
+
+- Update the Code of Conduct to the latest version ([#4402]({{ site.repository }}/issues/4402))
+
+### Bug Fixes
+{: #bug-fixes-v3-1-1}
+
+- `Page#dir`: ensure it ends in a slash ([#4403]({{ site.repository }}/issues/4403))
+- Add `Utils.merged_file_read_opts` to unify reading & strip the BOM ([#4404]({{ site.repository }}/issues/4404))
+- `Renderer#output_ext`: honor folders when looking for ext ([#4401]({{ site.repository }}/issues/4401))
+
+### Development Fixes
+{: #development-fixes-v3-1-1}
+
+- Suppress stdout in liquid profiling test ([#4409]({{ site.repository }}/issues/4409))
+
+
+## 3.1.0 / 2016-01-23
+{: #v3-1-0}
+
+### Minor Enhancements
+{: #minor-enhancements-v3-1-0}
+
+- Use `Liquid::Drop`s instead of `Hash`es in `#to_liquid` ([#4277]({{ site.repository }}/issues/4277))
+- Add 'sample' Liquid filter Equivalent to Array#sample functionality ([#4223]({{ site.repository }}/issues/4223))
+- Cache parsed include file to save liquid parsing time. ([#4120]({{ site.repository }}/issues/4120))
+- Slightly speed up url sanitization and handle multiples of ///. ([#4168]({{ site.repository }}/issues/4168))
+- Print debug message when a document is skipped from reading ([#4180]({{ site.repository }}/issues/4180))
+- Include tag should accept multiple variables in the include name ([#4183]({{ site.repository }}/issues/4183))
+- Add `-o` option to serve command which opens server URL ([#4144]({{ site.repository }}/issues/4144))
+- Add CodeClimate platform for better code quality. ([#4220]({{ site.repository }}/issues/4220))
+- General improvements for WEBrick via jekyll serve such as SSL & custom headers ([#4224]({{ site.repository }}/issues/4224), [#4228]({{ site.repository }}/issues/4228))
+- Add a default charset to content-type on webrick. ([#4231]({{ site.repository }}/issues/4231))
+- Switch `PluginManager` to use `require_with_graceful_fail` for better UX ([#4233]({{ site.repository }}/issues/4233))
+- Allow quoted date in front matter defaults ([#4184]({{ site.repository }}/issues/4184))
+- Add a Jekyll doctor warning for URLs that only differ by case ([#3171]({{ site.repository }}/issues/3171))
+- drops: create one base Drop class which can be set as mutable or not ([#4285]({{ site.repository }}/issues/4285))
+- drops: provide `#to_h` to allow for hash introspection ([#4281]({{ site.repository }}/issues/4281))
+- Shim subcommands with indication of gem possibly required so users know how to use them ([#4254]({{ site.repository }}/issues/4254))
+- Add smartify Liquid filter for SmartyPants ([#4323]({{ site.repository }}/issues/4323))
+- Raise error on empty permalink ([#4361]({{ site.repository }}/issues/4361))
+- Refactor Page#permalink method ([#4389]({{ site.repository }}/issues/4389))
+
+### Bug Fixes
+{: #bug-fixes-v3-1-0}
+
+- Pass build options into `clean` command ([#4177]({{ site.repository }}/issues/4177))
+- Allow users to use .htm and .xhtml (XHTML5.) ([#4160]({{ site.repository }}/issues/4160))
+- Prevent Shell Injection. ([#4200]({{ site.repository }}/issues/4200))
+- Convertible should make layout data accessible via `layout` instead of `page` ([#4205]({{ site.repository }}/issues/4205))
+- Avoid using `Dir.glob` with absolute path to allow special characters in the path ([#4150]({{ site.repository }}/issues/4150))
+- Handle empty config files ([#4052]({{ site.repository }}/issues/4052))
+- Rename `[@options](https://github.com/options)` so that it does not impact Liquid. ([#4173]({{ site.repository }}/issues/4173))
+- utils/drops: update Drop to support `Utils.deep_merge_hashes` ([#4289]({{ site.repository }}/issues/4289))
+- Make sure jekyll/drops/drop is loaded first. ([#4292]({{ site.repository }}/issues/4292))
+- Convertible/Page/Renderer: use payload hash accessor & setter syntax for backwards-compatibility ([#4311]({{ site.repository }}/issues/4311))
+- Drop: fix hash setter precendence ([#4312]({{ site.repository }}/issues/4312))
+- utils: `has_yaml_header?` should accept files with extraneous spaces ([#4290]({{ site.repository }}/issues/4290))
+- Escape html from site.title and page.title in site template ([#4307]({{ site.repository }}/issues/4307))
+- Allow custom file extensions if defined in `permalink` YAML front matter ([#4314]({{ site.repository }}/issues/4314))
+- Fix deep_merge_hashes! handling of drops and hashes ([#4359]({{ site.repository }}/issues/4359))
+- Page should respect output extension of its permalink ([#4373]({{ site.repository }}/issues/4373))
+- Disable auto-regeneration when running server detached ([#4376]({{ site.repository }}/issues/4376))
+- Drop#[]: only use public_send for keys in the content_methods array ([#4388]({{ site.repository }}/issues/4388))
+- Extract title from filename successfully when no date. ([#4195]({{ site.repository }}/issues/4195))
+
+### Development Fixes
+{: #development-fixes-v3-1-0}
+
+- `jekyll-docs` should be easily release-able ([#4152]({{ site.repository }}/issues/4152))
+- Allow use of Cucumber 2.1 or greater ([#4181]({{ site.repository }}/issues/4181))
+- Modernize Kramdown for Markdown converter. ([#4109]({{ site.repository }}/issues/4109))
+- Change TestDoctorCommand to JekyllUnitTest... ([#4263]({{ site.repository }}/issues/4263))
+- Create namespaced rake tasks in separate `.rake` files under `lib/tasks` ([#4282]({{ site.repository }}/issues/4282))
+- markdown: refactor for greater readability & efficiency ([#3771]({{ site.repository }}/issues/3771))
+- Fix many Rubocop style errors ([#4301]({{ site.repository }}/issues/4301))
+- Fix spelling of "GitHub" in docs and history ([#4322]({{ site.repository }}/issues/4322))
+- Reorganize and cleanup the Gemfile, shorten required depends. ([#4318]({{ site.repository }}/issues/4318))
+- Remove script/rebund. ([#4341]({{ site.repository }}/issues/4341))
+- Implement codeclimate platform ([#4340]({{ site.repository }}/issues/4340))
+- Remove ObectSpace dumping and start using inherited, it's faster. ([#4342]({{ site.repository }}/issues/4342))
+- Add script/travis so all people can play with Travis-CI images. ([#4338]({{ site.repository }}/issues/4338))
+- Move Cucumber to using RSpec-Expections and furthering JRuby support. ([#4343]({{ site.repository }}/issues/4343))
+- Rearrange Cucumber and add some flair. ([#4347]({{ site.repository }}/issues/4347))
+- Remove old FIXME ([#4349]({{ site.repository }}/issues/4349))
+- Clean up the Gemfile (and keep all the necessary dependencies) ([#4350]({{ site.repository }}/issues/4350))
+
+### Site Enhancements
+{: #site-enhancements-v3-1-0}
+
+- Add three plugins to directory ([#4163]({{ site.repository }}/issues/4163))
+- Add upgrading docs from 2.x to 3.x ([#4157]({{ site.repository }}/issues/4157))
+- Add `protect_email` to the plugins index. ([#4169]({{ site.repository }}/issues/4169))
+- Add `jekyll-deploy` to list of third-party plugins ([#4179]({{ site.repository }}/issues/4179))
+- Clarify plugin docs ([#4154]({{ site.repository }}/issues/4154))
+- Add Kickster to deployment methods in documentation ([#4190]({{ site.repository }}/issues/4190))
+- Add DavidBurela's tutorial for Windows to Windows docs page ([#4210]({{ site.repository }}/issues/4210))
+- Change GitHub code block to highlight tag to avoid it overlaps parent div ([#4121]({{ site.repository }}/issues/4121))
+- Update FormKeep link to be something more specific to Jekyll ([#4243]({{ site.repository }}/issues/4243))
+- Remove example Roger Chapman site, as the domain doesn't exist ([#4249]({{ site.repository }}/issues/4249))
+- Added configuration options for `draft_posts` to configuration docs ([#4251]({{ site.repository }}/issues/4251))
+- Fix checklist in `_assets.md` ([#4259]({{ site.repository }}/issues/4259))
+- Add Markdown examples to Pages docs ([#4275]({{ site.repository }}/issues/4275))
+- Add jekyll-paginate-category to list of third-party plugins ([#4273]({{ site.repository }}/issues/4273))
+- Add `jekyll-responsive_image` to list of third-party plugins ([#4286]({{ site.repository }}/issues/4286))
+- Add `jekyll-commonmark` to list of third-party plugins ([#4299]({{ site.repository }}/issues/4299))
+- Add documentation for incremental regeneration ([#4293]({{ site.repository }}/issues/4293))
+- Add note about removal of relative permalink support in upgrading docs ([#4303]({{ site.repository }}/issues/4303))
+- Add Pro Tip to use front matter variable to create clean URLs ([#4296]({{ site.repository }}/issues/4296))
+- Fix grammar in the documentation for posts. ([#4330]({{ site.repository }}/issues/4330))
+- Add documentation for smartify Liquid filter ([#4333]({{ site.repository }}/issues/4333))
+- Fixed broken link to blog on using mathjax with jekyll ([#4344]({{ site.repository }}/issues/4344))
+- Documentation: correct reference in Precedence section of Configuration docs ([#4355]({{ site.repository }}/issues/4355))
+- Add [@jmcglone](https://github.com/jmcglone)'s guide to github-pages doc page ([#4364]({{ site.repository }}/issues/4364))
+- Added the Wordpress2Jekyll Wordpress plugin ([#4377]({{ site.repository }}/issues/4377))
+- Add Contentful Extension to list of third-party plugins ([#4390]({{ site.repository }}/issues/4390))
+- Correct Minor spelling error ([#4394]({{ site.repository }}/issues/4394))
+
+
+## 3.0.3 / 2016-02-08
+{: #v3-0-3}
+
+### Bug Fixes
+{: #bug-fixes-v3-0-3}
+
+- Fix extension weirdness with folders ([#4493]({{ site.repository }}/issues/4493))
+- EntryFilter: only include 'excluded' log on excluded files ([#4479]({{ site.repository }}/issues/4479))
+- `Jekyll.sanitized_path`: escape tildes before sanitizing a questionable path ([#4468]({{ site.repository }}/issues/4468))
+- `LiquidRenderer#parse`: parse with line numbers ([#4453]({{ site.repository }}/issues/4453))
+- `Document#<=>`: protect against nil comparison in dates. ([#4446]({{ site.repository }}/issues/4446))
+
+
+## 3.0.2 / 2016-01-20
+{: #v3-0-2}
+
+### Bug Fixes
+{: #bug-fixes-v3-0-2}
+
+- Document: throw a useful error when an invalid date is given ([#4378]({{ site.repository }}/issues/4378))
+
+
+## 3.0.1 / 2015-11-17
+{: #v3-0-1}
+
+### Bug Fixes
+{: #bug-fixes-v3-0-1}
+
+- Document: only superdirectories of the collection are categories ([#4110]({{ site.repository }}/issues/4110))
+- `Convertible#render_liquid` should use `render!` to cause failure on bad Liquid ([#4077]({{ site.repository }}/issues/4077))
+- Don't generate `.jekyll-metadata` in non-incremental build ([#4079]({{ site.repository }}/issues/4079))
+- Set `highlighter` config val to `kramdown.syntax_highlighter` ([#4090]({{ site.repository }}/issues/4090))
+- Align hooks implementation with documentation ([#4104]({{ site.repository }}/issues/4104))
+- Fix the deprecation warning in the doctor command ([#4114]({{ site.repository }}/issues/4114))
+- Fix case in `:title` and add `:slug` which is downcased ([#4100]({{ site.repository }}/issues/4100))
+
+### Development Fixes
+{: #development-fixes-v3-0-1}
+
+- Fix test warnings when doing rake {test,spec} or script/test ([#4078]({{ site.repository }}/issues/4078))
+
+### Site Enhancements
+{: #site-enhancements-v3-0-1}
+
+- Update normalize.css to v3.0.3. ([#4085]({{ site.repository }}/issues/4085))
+- Update Font Awesome to v4.4.0. ([#4086]({{ site.repository }}/issues/4086))
+- Adds a note about installing the jekyll-gist gem to make gist tag work ([#4101]({{ site.repository }}/issues/4101))
+- Align hooks documentation with implementation ([#4104]({{ site.repository }}/issues/4104))
+- Add Jekyll Flickr Plugin to the list of third party plugins ([#4111]({{ site.repository }}/issues/4111))
+- Remove link to now-deleted blog post ([#4125]({{ site.repository }}/issues/4125))
+- Update the liquid syntax in the pagination docs ([#4130]({{ site.repository }}/issues/4130))
+- Add jekyll-language-plugin to plugins.md ([#4134]({{ site.repository }}/issues/4134))
+- Updated to reflect feedback in [#4129]({{ site.repository }}/issues/4129) ([#4137]({{ site.repository }}/issues/4137))
+- Clarify assets.md based on feedback of [#4129]({{ site.repository }}/issues/4129) ([#4142]({{ site.repository }}/issues/4142))
+- Re-correct the liquid syntax in the pagination docs ([#4140]({{ site.repository }}/issues/4140))
+
+
+## 3.0.0 / 2015-10-26
+{: #v3-0-0}
+
+### Major Enhancements
+{: #major-enhancements-v3-0-0}
+
+- Liquid profiler (i.e. know how fast or slow your templates render) ([#3762]({{ site.repository }}/issues/3762))
+- Incremental regeneration ([#3116]({{ site.repository }}/issues/3116))
+- Add Hooks: a new kind of plugin ([#3553]({{ site.repository }}/issues/3553))
+- Upgrade to Liquid 3.0.0 ([#3002]({{ site.repository }}/issues/3002))
+- `site.posts` is now a Collection instead of an Array ([#4055]({{ site.repository }}/issues/4055))
+- Add basic support for JRuby (commit: 0f4477)
+- Drop support for Ruby 1.9.3. ([#3235]({{ site.repository }}/issues/3235))
+- Support Ruby v2.2 ([#3234]({{ site.repository }}/issues/3234))
+- Support RDiscount 2 ([#2767]({{ site.repository }}/issues/2767))
+- Remove most runtime deps ([#3323]({{ site.repository }}/issues/3323))
+- Move to Rouge as default highlighter ([#3323]({{ site.repository }}/issues/3323))
+- Mimic GitHub Pages `.html` extension stripping behavior in WEBrick ([#3452]({{ site.repository }}/issues/3452))
+- Always include file extension on output files ([#3490]({{ site.repository }}/issues/3490))
+- Improved permalinks for pages and collections ([#3538]({{ site.repository }}/issues/3538))
+- Sunset (i.e. remove) Maruku ([#3655]({{ site.repository }}/issues/3655))
+- Remove support for relative permalinks ([#3679]({{ site.repository }}/issues/3679))
+- Iterate over `site.collections` as an array instead of a hash. ([#3670]({{ site.repository }}/issues/3670))
+- Adapt StaticFile for collections, config defaults ([#3823]({{ site.repository }}/issues/3823))
+- Add a Code of Conduct for the Jekyll project ([#3925]({{ site.repository }}/issues/3925))
+- Added permalink time variables ([#3990]({{ site.repository }}/issues/3990))
+- Add `--incremental` flag to enable incremental regen (disabled by default) ([#4059]({{ site.repository }}/issues/4059))
+
+### Minor Enhancements
+{: #minor-enhancements-v3-0-0}
+
+- Deprecate access to Document#data properties and Collection#docs methods ([#4058]({{ site.repository }}/issues/4058))
+- Sort static files just once, and call `site_payload` once for all collections ([#3204]({{ site.repository }}/issues/3204))
+- Separate `jekyll docs` and optimize external gem handling ([#3241]({{ site.repository }}/issues/3241))
+- Improve `Site#getConverterImpl` and call it `Site#find_converter_instance` ([#3240]({{ site.repository }}/issues/3240))
+- Use relative path for `path` Liquid variable in Documents for consistency ([#2908]({{ site.repository }}/issues/2908))
+- Generalize `Utils#slugify` for any scripts ([#3047]({{ site.repository }}/issues/3047))
+- Added basic microdata to post template in site template ([#3189]({{ site.repository }}/issues/3189))
+- Store log messages in an array of messages. ([#3244]({{ site.repository }}/issues/3244))
+- Allow collection documents to override `output` property in front matter ([#3172]({{ site.repository }}/issues/3172))
+- Keep file modification times between builds for static files ([#3220]({{ site.repository }}/issues/3220))
+- Only downcase mixed-case categories for the URL ([#2571]({{ site.repository }}/issues/2571))
+- Added per post `excerpt_separator` functionality ([#3274]({{ site.repository }}/issues/3274))
+- Allow collections YAML to end with three dots ([#3134]({{ site.repository }}/issues/3134))
+- Add mode parameter to `slugify` Liquid filter ([#2918]({{ site.repository }}/issues/2918))
+- Perf: `Markdown#matches` should avoid regexp ([#3321]({{ site.repository }}/issues/3321))
+- Perf: Use frozen regular expressions for `Utils#slugify` ([#3321]({{ site.repository }}/issues/3321))
+- Split off Textile support into jekyll-textile-converter ([#3319]({{ site.repository }}/issues/3319))
+- Improve the navigation menu alignment in the site template on small screens ([#3331]({{ site.repository }}/issues/3331))
+- Show the regeneration time after the initial generation ([#3378]({{ site.repository }}/issues/3378))
+- Site template: Switch default font to Helvetica Neue ([#3376]({{ site.repository }}/issues/3376))
+- Make the `include` tag a teensy bit faster. ([#3391]({{ site.repository }}/issues/3391))
+- Add `pkill -f jekyll` to ways to kill. ([#3397]({{ site.repository }}/issues/3397))
+- Site template: collapsed, variable-driven font declaration ([#3360]({{ site.repository }}/issues/3360))
+- Site template: Don't always show the scrollbar in code blocks ([#3419]({{ site.repository }}/issues/3419))
+- Site template: Remove undefined `text` class from `p` element ([#3440]({{ site.repository }}/issues/3440))
+- Site template: Optimize text rendering for legibility ([#3382]({{ site.repository }}/issues/3382))
+- Add `draft?` method to identify if Post is a Draft & expose to Liquid ([#3456]({{ site.repository }}/issues/3456))
+- Write regeneration metadata even on full rebuild ([#3464]({{ site.repository }}/issues/3464))
+- Perf: Use `String#end_with?("/")` instead of regexp when checking paths ([#3516]({{ site.repository }}/issues/3516))
+- Docs: document 'ordinal' built-in permalink style ([#3532]({{ site.repository }}/issues/3532))
+- Upgrade liquid-c to 3.x ([#3531]({{ site.repository }}/issues/3531))
+- Use consistent syntax for deprecation warning ([#3535]({{ site.repository }}/issues/3535))
+- Added build --destination and --source flags ([#3418]({{ site.repository }}/issues/3418))
+- Site template: remove unused `page.meta` attribute ([#3537]({{ site.repository }}/issues/3537))
+- Improve the error message when sorting null objects ([#3520]({{ site.repository }}/issues/3520))
+- Added liquid-md5 plugin ([#3598]({{ site.repository }}/issues/3598))
+- Documentation: RR replaced with RSpec Mocks ([#3600]({{ site.repository }}/issues/3600))
+- Documentation: Fix subpath. ([#3599]({{ site.repository }}/issues/3599))
+- Create 'tmp' dir for test_tags if it doesn't exist ([#3609]({{ site.repository }}/issues/3609))
+- Extract reading of data from `Site` to reduce responsibilities. ([#3545]({{ site.repository }}/issues/3545))
+- Removed the word 'Jekyll' a few times from the comments ([#3617]({{ site.repository }}/issues/3617))
+- `bin/jekyll`: with no args, exit with exit code 1 ([#3619]({{ site.repository }}/issues/3619))
+- Incremental build if destination file missing ([#3614]({{ site.repository }}/issues/3614))
+- Static files `mtime` liquid should return a `Time` obj ([#3596]({{ site.repository }}/issues/3596))
+- Use `Jekyll::Post`s for both LSI indexing and lookup. ([#3629]({{ site.repository }}/issues/3629))
+- Add `charset=utf-8` for HTML and XML pages in WEBrick ([#3649]({{ site.repository }}/issues/3649))
+- Set log level to debug when verbose flag is set ([#3665]({{ site.repository }}/issues/3665))
+- Added a mention on the Gemfile to complete the instructions ([#3671]({{ site.repository }}/issues/3671))
+- Perf: Cache `Document#to_liquid` and invalidate where necessary ([#3693]({{ site.repository }}/issues/3693))
+- Perf: `Jekyll::Cleaner#existing_files`: Call `keep_file_regex` and `keep_dirs` only once, not once per iteration ([#3696]({{ site.repository }}/issues/3696))
+- Omit jekyll/jekyll-help from list of resources. ([#3698]({{ site.repository }}/issues/3698))
+- Add basic `jekyll doctor` test to detect fsnotify (OSX) anomalies. ([#3704]({{ site.repository }}/issues/3704))
+- Added talk.jekyllrb.com to "Have questions?" ([#3694]({{ site.repository }}/issues/3694))
+- Performance: Sort files only once ([#3707]({{ site.repository }}/issues/3707))
+- Performance: Marshal metadata ([#3706]({{ site.repository }}/issues/3706))
+- Upgrade highlight wrapper from `div` to `figure` ([#3779]({{ site.repository }}/issues/3779))
+- Upgrade mime-types to `~> 2.6` ([#3795]({{ site.repository }}/issues/3795))
+- Update windows.md with Ruby version info ([#3818]({{ site.repository }}/issues/3818))
+- Make the directory for includes configurable ([#3782]({{ site.repository }}/issues/3782))
+- Rename directory configurations to match `*_dir` convention for consistency ([#3782]({{ site.repository }}/issues/3782))
+- Internal: trigger hooks by owner symbol ([#3871]({{ site.repository }}/issues/3871))
+- Update MIME types from mime-db ([#3933]({{ site.repository }}/issues/3933))
+- Add header to site template `_config.yml` for clarity & direction ([#3997]({{ site.repository }}/issues/3997))
+- Site template: add timezone offset to post date frontmatter ([#4001]({{ site.repository }}/issues/4001))
+- Make a constant for the regex to find hidden files ([#4032]({{ site.repository }}/issues/4032))
+- Site template: refactor github & twitter icons into includes ([#4049]({{ site.repository }}/issues/4049))
+- Site template: add background to Kramdown Rouge-ified backtick code blocks ([#4053]({{ site.repository }}/issues/4053))
+
+### Bug Fixes
+{: #bug-fixes-v3-0-0}
+
+- `post_url`: fix access deprecation warning & fix deprecation msg ([#4060]({{ site.repository }}/issues/4060))
+- Perform jekyll-paginate deprecation warning correctly. ([#3580]({{ site.repository }}/issues/3580))
+- Make permalink parsing consistent with pages ([#3014]({{ site.repository }}/issues/3014))
+- `time()`pre-filter method should accept a `Date` object ([#3299]({{ site.repository }}/issues/3299))
+- Remove unneeded end tag for `link` in site template ([#3236]({{ site.repository }}/issues/3236))
+- Kramdown: Use `enable_coderay` key instead of `use_coderay` ([#3237]({{ site.repository }}/issues/3237))
+- Unescape `Document` output path ([#2924]({{ site.repository }}/issues/2924))
+- Fix nav items alignment when on multiple rows ([#3264]({{ site.repository }}/issues/3264))
+- Highlight: Only Strip Newlines/Carriage Returns, not Spaces ([#3278]({{ site.repository }}/issues/3278))
+- Find variables in front matter defaults by searching with relative file path. ([#2774]({{ site.repository }}/issues/2774))
+- Allow variables (e.g `:categories`) in YAML front matter permalinks ([#3320]({{ site.repository }}/issues/3320))
+- Handle nil URL placeholders in permalinks ([#3325]({{ site.repository }}/issues/3325))
+- Template: Fix nav items alignment when in "burger" mode ([#3329]({{ site.repository }}/issues/3329))
+- Template: Remove `!important` from nav SCSS introduced in [#3329]({{ site.repository }}/issues/3329) ([#3375]({{ site.repository }}/issues/3375))
+- The `:title` URL placeholder for collections should be the filename slug. ([#3383]({{ site.repository }}/issues/3383))
+- Trim the generate time diff to just 3 places past the decimal place ([#3415]({{ site.repository }}/issues/3415))
+- The highlight tag should only clip the newlines before and after the *entire* block, not in between ([#3401]({{ site.repository }}/issues/3401))
+- highlight: fix problem with linenos and rouge. ([#3436]({{ site.repository }}/issues/3436))
+- `Site#read_data_file`: read CSV's with proper file encoding ([#3455]({{ site.repository }}/issues/3455))
+- Ignore `.jekyll-metadata` in site template ([#3496]({{ site.repository }}/issues/3496))
+- Template: Point documentation link to the documentation pages ([#3502]({{ site.repository }}/issues/3502))
+- Removed the trailing slash from the example `/blog` baseurl comment ([#3485]({{ site.repository }}/issues/3485))
+- Clear the regenerator cache every time we process ([#3592]({{ site.repository }}/issues/3592))
+- Readd (bring back) minitest-profile ([#3628]({{ site.repository }}/issues/3628))
+- Add WOFF2 font MIME type to Jekyll server MIME types ([#3647]({{ site.repository }}/issues/3647))
+- Be smarter about extracting the extname in `StaticFile` ([#3632]({{ site.repository }}/issues/3632))
+- Process metadata for all dependencies ([#3608]({{ site.repository }}/issues/3608))
+- Show error message if the YAML front matter on a page/post is invalid. ([#3643]({{ site.repository }}/issues/3643))
+- Upgrade redcarpet to 3.2 (Security fix: OSVDB-120415) ([#3652]({{ site.repository }}/issues/3652))
+- Create #mock_expects that goes directly to RSpec Mocks. ([#3658]({{ site.repository }}/issues/3658))
+- Open `.jekyll-metadata` in binary mode to read binary Marshal data ([#3713]({{ site.repository }}/issues/3713))
+- Incremental regeneration: handle deleted, renamed, and moved dependencies ([#3717]({{ site.repository }}/issues/3717))
+- Fix typo on line 19 of pagination.md ([#3760]({{ site.repository }}/issues/3760))
+- Fix it so that 'blog.html' matches 'blog.html' ([#3732]({{ site.repository }}/issues/3732))
+- Remove occasionally-problematic `ensure` in `LiquidRenderer` ([#3811]({{ site.repository }}/issues/3811))
+- Fixed an unclear code comment in site template SCSS ([#3837]({{ site.repository }}/issues/3837))
+- Fix reading of binary metadata file ([#3845]({{ site.repository }}/issues/3845))
+- Remove var collision with site template header menu iteration variable ([#3838]({{ site.repository }}/issues/3838))
+- Change non-existent `hl_linenos` to `hl_lines` to allow passthrough in safe mode ([#3787]({{ site.repository }}/issues/3787))
+- Add missing flag to disable the watcher ([#3820]({{ site.repository }}/issues/3820))
+- Update CI guide to include more direct explanations of the flow ([#3891]({{ site.repository }}/issues/3891))
+- Set `future` to `false` in the default config ([#3892]({{ site.repository }}/issues/3892))
+- filters: `where` should compare stringified versions of input & comparator ([#3935]({{ site.repository }}/issues/3935))
+- Read build options for `jekyll clean` command ([#3828]({{ site.repository }}/issues/3828))
+- Fix [#3970]({{ site.repository }}/issues/3970): Use Gem::Version to compare versions, not `>`.
+- Abort if no subcommand. Fixes confusing message. ([#3992]({{ site.repository }}/issues/3992))
+- Whole-post excerpts should match the post content ([#4004]({{ site.repository }}/issues/4004))
+- Change default font weight to 400 to fix bold/strong text issues ([#4050]({{ site.repository }}/issues/4050))
+- Document: Only auto-generate the excerpt if it's not overridden ([#4062]({{ site.repository }}/issues/4062))
+- Utils: `deep_merge_hashes` should also merge `default_proc` (45f69bb)
+- Defaults: compare paths in `applies_path?` as `String`s to avoid confusion (7b81f00)
+
+### Development Fixes
+{: #development-fixes-v3-0-0}
+
+- Remove loader.rb and "modernize" `script/test`. ([#3574]({{ site.repository }}/issues/3574))
+- Improve the grammar in the documentation ([#3233]({{ site.repository }}/issues/3233))
+- Update the LICENSE text to match the MIT license exactly ([#3253]({{ site.repository }}/issues/3253))
+- Update rake task `site:publish` to fix minor bugs. ([#3254]({{ site.repository }}/issues/3254))
+- Switch to shields.io for the README badges. ([#3255]({{ site.repository }}/issues/3255))
+- Use `FileList` instead of `Dir.glob` in `site:publish` rake task ([#3261]({{ site.repository }}/issues/3261))
+- Fix test script to be platform-independent ([#3279]({{ site.repository }}/issues/3279))
+- Instead of symlinking `/tmp`, create and symlink a local `tmp` in the tests ([#3258]({{ site.repository }}/issues/3258))
+- Fix some spacing ([#3312]({{ site.repository }}/issues/3312))
+- Fix comment typo in `lib/jekyll/frontmatter_defaults.rb` ([#3322]({{ site.repository }}/issues/3322))
+- Move all `regenerate?` checking to `Regenerator` ([#3326]({{ site.repository }}/issues/3326))
+- Factor out a `read_data_file` call to keep things clean ([#3380]({{ site.repository }}/issues/3380))
+- Proof the site with CircleCI. ([#3427]({{ site.repository }}/issues/3427))
+- Update LICENSE to 2015. ([#3477]({{ site.repository }}/issues/3477))
+- Upgrade tests to use Minitest ([#3492]({{ site.repository }}/issues/3492))
+- Remove trailing whitespace ([#3497]({{ site.repository }}/issues/3497))
+- Use `fixture_site` for Document tests ([#3511]({{ site.repository }}/issues/3511))
+- Remove adapters deprecation warning ([#3529]({{ site.repository }}/issues/3529))
+- Minor fixes to `url.rb` to follow GitHub style guide ([#3544]({{ site.repository }}/issues/3544))
+- Minor changes to resolve deprecation warnings ([#3547]({{ site.repository }}/issues/3547))
+- Convert remaining textile test documents to markdown ([#3528]({{ site.repository }}/issues/3528))
+- Migrate the tests to use rspec-mocks ([#3552]({{ site.repository }}/issues/3552))
+- Remove `activesupport` ([#3612]({{ site.repository }}/issues/3612))
+- Added tests for `Jekyll:StaticFile` ([#3633]({{ site.repository }}/issues/3633))
+- Force minitest version to 5.5.1 ([#3657]({{ site.repository }}/issues/3657))
+- Update the way cucumber accesses Minitest assertions ([#3678]({{ site.repository }}/issues/3678))
+- Add `script/rubyprof` to generate cachegrind callgraphs ([#3692]({{ site.repository }}/issues/3692))
+- Upgrade cucumber to 2.x ([#3795]({{ site.repository }}/issues/3795))
+- Update Kramdown. ([#3853]({{ site.repository }}/issues/3853))
+- Updated the scripts shebang for portability ([#3858]({{ site.repository }}/issues/3858))
+- Update JRuby testing to 9K ([3ab386f](https://github.com/jekyll/jekyll/commit/3ab386f1b096be25a24fe038fc70fd0fb08d545d))
+- Organize dependencies into dev and test groups. ([#3852]({{ site.repository }}/issues/3852))
+- Contributing.md should refer to `script/cucumber` ([#3894]({{ site.repository }}/issues/3894))
+- Update contributing documentation to reflect workflow updates ([#3895]({{ site.repository }}/issues/3895))
+- Add script to vendor mime types ([#3933]({{ site.repository }}/issues/3933))
+- Ignore .bundle dir in SimpleCov ([#4033]({{ site.repository }}/issues/4033))
+
+### Site Enhancements
+{: #site-enhancements-v3-0-0}
+
+- Add 'info' labels to certain notes in collections docs ([#3601]({{ site.repository }}/issues/3601))
+- Remove extra spaces, make the last sentence less awkward in permalink docs ([#3603]({{ site.repository }}/issues/3603))
+- Update the permalinks documentation to reflect the updates for 3.0 ([#3556]({{ site.repository }}/issues/3556))
+- Add blog post announcing Jekyll Help ([#3523]({{ site.repository }}/issues/3523))
+- Add Jekyll Talk to Help page on site ([#3518]({{ site.repository }}/issues/3518))
+- Change Ajax pagination resource link to use HTTPS ([#3570]({{ site.repository }}/issues/3570))
+- Fixing the default host on docs ([#3229]({{ site.repository }}/issues/3229))
+- Add `jekyll-thumbnail-filter` to list of third-party plugins ([#2790]({{ site.repository }}/issues/2790))
+- Add link to 'Adding Ajax pagination to Jekyll' to Resources page ([#3186]({{ site.repository }}/issues/3186))
+- Add a Resources link to tutorial on building dynamic navbars ([#3185]({{ site.repository }}/issues/3185))
+- Semantic structure improvements to the post and page layouts ([#3251]({{ site.repository }}/issues/3251))
+- Add new AsciiDoc plugin to list of third-party plugins. ([#3277]({{ site.repository }}/issues/3277))
+- Specify that all transformable collection documents must contain YAML front matter ([#3271]({{ site.repository }}/issues/3271))
+- Assorted accessibility fixes ([#3256]({{ site.repository }}/issues/3256))
+- Update configuration docs to mention `keep_files` for `destination` ([#3288]({{ site.repository }}/issues/3288), [#3296]({{ site.repository }}/issues/3296))
+- Break when we successfully generate nav link to save CPU cycles. ([#3291]({{ site.repository }}/issues/3291))
+- Update usage docs to mention `keep_files` and a warning about `destination` cleaning ([#3295]({{ site.repository }}/issues/3295))
+- Add logic to automatically generate the `next_section` and `prev_section` navigation items ([#3292]({{ site.repository }}/issues/3292))
+- Some small fixes for the Plugins TOC. ([#3306]({{ site.repository }}/issues/3306))
+- Added versioning comment to configuration file ([#3314]({{ site.repository }}/issues/3314))
+- Add `jekyll-minifier` to list of third-party plugins ([#3333]({{ site.repository }}/issues/3333))
+- Add blog post about the Jekyll meet-up ([#3332]({{ site.repository }}/issues/3332))
+- Use `highlight` Liquid tag instead of the four-space tabs for code ([#3336]({{ site.repository }}/issues/3336))
+- 3.0.0.beta1 release post ([#3346]({{ site.repository }}/issues/3346))
+- Add `twa` to the list of third-party plugins ([#3384]({{ site.repository }}/issues/3384))
+- Remove extra spaces ([#3388]({{ site.repository }}/issues/3388))
+- Fix small grammar errors on a couple pages ([#3396]({{ site.repository }}/issues/3396))
+- Fix typo on Templates docs page ([#3420]({{ site.repository }}/issues/3420))
+- s/three/four for plugin type list ([#3424]({{ site.repository }}/issues/3424))
+- Release jekyllrb.com as a locally-compiled site. ([#3426]({{ site.repository }}/issues/3426))
+- Add a jekyllrb.com/help page which elucidates places from which to get help ([#3428]({{ site.repository }}/issues/3428))
+- Remove extraneous dash on Plugins doc page which caused a formatting error ([#3431]({{ site.repository }}/issues/3431))
+- Fix broken link to Jordan Thornquest's website. ([#3438]({{ site.repository }}/issues/3438))
+- Change the link to an extension ([#3457]({{ site.repository }}/issues/3457))
+- Fix Twitter link on the help page ([#3466]({{ site.repository }}/issues/3466))
+- Fix wording in code snippet highlighting section ([#3475]({{ site.repository }}/issues/3475))
+- Add a `/` to `paginate_path` in the Pagination documentation ([#3479]({{ site.repository }}/issues/3479))
+- Add a link on all the docs pages to "Improve this page". ([#3510]({{ site.repository }}/issues/3510))
+- Add jekyll-auto-image generator to the list of third-party plugins ([#3489]({{ site.repository }}/issues/3489))
+- Replace link to the proposed `picture` element spec ([#3530]({{ site.repository }}/issues/3530))
+- Add frontmatter date formatting information ([#3469]({{ site.repository }}/issues/3469))
+- Improve consistency and clarity of plugins options note ([#3546]({{ site.repository }}/issues/3546))
+- Add permalink warning to pagination docs ([#3551]({{ site.repository }}/issues/3551))
+- Fix grammar in Collections docs API stability warning ([#3560]({{ site.repository }}/issues/3560))
+- Restructure `excerpt_separator` documentation for clarity ([#3550]({{ site.repository }}/issues/3550))
+- Fix accidental line break in collections docs ([#3585]({{ site.repository }}/issues/3585))
+- Add information about the `.jekyll-metadata` file ([#3597]({{ site.repository }}/issues/3597))
+- Document addition of variable parameters to an include ([#3581]({{ site.repository }}/issues/3581))
+- Add `jekyll-files` to the list of third-party plugins. ([#3586]({{ site.repository }}/issues/3586))
+- Define the `install` step in the CI example `.travis.yml` ([#3622]({{ site.repository }}/issues/3622))
+- Expand collections documentation. ([#3638]({{ site.repository }}/issues/3638))
+- Add the "warning" note label to excluding `vendor` in the CI docs page ([#3623]({{ site.repository }}/issues/3623))
+- Upgrade pieces of the Ugrading guide for Jekyll 3 ([#3607]({{ site.repository }}/issues/3607))
+- Showing how to access specific data items ([#3468]({{ site.repository }}/issues/3468))
+- Clarify pagination works from within HTML files ([#3467]({{ site.repository }}/issues/3467))
+- Add note to `excerpt_separator` documentation that it can be set globally ([#3667]({{ site.repository }}/issues/3667))
+- Fix some names on Troubleshooting page ([#3683]({{ site.repository }}/issues/3683))
+- Add `remote_file_content` tag plugin to list of third-party plugins ([#3691]({{ site.repository }}/issues/3691))
+- Update the Redcarpet version on the Configuration page. ([#3743]({{ site.repository }}/issues/3743))
+- Update the link in the welcome post to point to Jekyll Talk ([#3745]({{ site.repository }}/issues/3745))
+- Update link for navbars with data attributes tutorial ([#3728]({{ site.repository }}/issues/3728))
+- Add `jekyll-asciinema` to list of third-party plugins ([#3750]({{ site.repository }}/issues/3750))
+- Update pagination example to be agnostic to first pagination dir ([#3763]({{ site.repository }}/issues/3763))
+- Detailed instructions for rsync deployment method ([#3848]({{ site.repository }}/issues/3848))
+- Add Jekyll Portfolio Generator to list of plugins ([#3883]({{ site.repository }}/issues/3883))
+- Add `site.html_files` to variables docs ([#3880]({{ site.repository }}/issues/3880))
+- Add Static Publisher tool to list of deployment methods ([#3865]({{ site.repository }}/issues/3865))
+- Fix a few typos. ([#3897]({{ site.repository }}/issues/3897))
+- Add `jekyll-youtube` to the list of third-party plugins ([#3931]({{ site.repository }}/issues/3931))
+- Add Views Router plugin ([#3950]({{ site.repository }}/issues/3950))
+- Update install docs (Core dependencies, Windows reqs, etc) ([#3769]({{ site.repository }}/issues/3769))
+- Use Jekyll Feed for jekyllrb.com ([#3736]({{ site.repository }}/issues/3736))
+- Add jekyll-umlauts to plugins.md ($3966)
+- Troubleshooting: fix broken link, add other mac-specific info ([#3968]({{ site.repository }}/issues/3968))
+- Add a new site for learning purposes ([#3917]({{ site.repository }}/issues/3917))
+- Added documentation for Jekyll environment variables ([#3989]({{ site.repository }}/issues/3989))
+- Fix broken configuration documentation page ([#3994]({{ site.repository }}/issues/3994))
+- Add troubleshooting docs for installing on El Capitan ([#3999]({{ site.repository }}/issues/3999))
+- Add Lazy Tweet Embedding to the list of third-party plugins ([#4015]({{ site.repository }}/issues/4015))
+- Add installation instructions for 2 of 3 options for plugins ([#4013]({{ site.repository }}/issues/4013))
+- Add alternative jekyll gem installation instructions ([#4018]({{ site.repository }}/issues/4018))
+- Fix a few typos and formatting problems. ([#4022]({{ site.repository }}/issues/4022))
+- Fix pretty permalink example ([#4029]({{ site.repository }}/issues/4029))
+- Note that `_config.yml` is not reloaded during regeneration ([#4034]({{ site.repository }}/issues/4034))
+- Apply code block figure syntax to blocks in CONTRIBUTING ([#4046]({{ site.repository }}/issues/4046))
+- Add jekyll-smartify to the list of third-party plugins ([#3572]({{ site.repository }}/issues/3572))
+
+
## 2.5.3 / 2014-12-22
{: #v2-5-3}
@@ -101,8 +607,7 @@ permalink: "/docs/history/"
- Strip newlines in site template `` description. ([#2982]({{ site.repository }}/issues/2982))
- Add link to atom feed in `head` of site template files ([#2996]({{ site.repository }}/issues/2996))
- Performance optimizations ([#2994]({{ site.repository }}/issues/2994))
-- Use `Hash#each_key` instead of `Hash#keys.each` to speed up iteration
- over hash keys. ([#3017]({{ site.repository }}/issues/3017))
+- Use `Hash#each_key` instead of `Hash#keys.each` to speed up iteration over hash keys. ([#3017]({{ site.repository }}/issues/3017))
- Further minor performance enhancements. ([#3022]({{ site.repository }}/issues/3022))
- Add 'b' and 's' aliases for build and serve, respectively ([#3065]({{ site.repository }}/issues/3065))
@@ -110,8 +615,7 @@ permalink: "/docs/history/"
{: #bug-fixes-v2-5-0}
- Fix Rouge's RedCarpet plugin interface integration ([#2951]({{ site.repository }}/issues/2951))
-- Remove `--watch` from the site template blog post since it defaults
- to watching in in 2.4.0 ([#2922]({{ site.repository }}/issues/2922))
+- Remove `--watch` from the site template blog post since it defaults to watching in in 2.4.0 ([#2922]({{ site.repository }}/issues/2922))
- Fix code for media query mixin in site template ([#2946]({{ site.repository }}/issues/2946))
- Allow post URL's to have `.htm` extensions ([#2925]({{ site.repository }}/issues/2925))
- `Utils.slugify`: Don't create new objects when gsubbing ([#2997]({{ site.repository }}/issues/2997))
@@ -141,7 +645,7 @@ permalink: "/docs/history/"
- Add Big Footnotes for Kramdown plugin to list of third-party plugins ([#2916]({{ site.repository }}/issues/2916))
- Remove warning regarding GHP use of singular types for front matter defaults ([#2919]({{ site.repository }}/issues/2919))
- Fix quote character typo in site documentation for templates ([#2917]({{ site.repository }}/issues/2917))
-- Point Liquid links to Liquid’s Github wiki ([#2887]({{ site.repository }}/issues/2887))
+- Point Liquid links to Liquid’s GitHub wiki ([#2887]({{ site.repository }}/issues/2887))
- Add HTTP Basic Auth (.htaccess) plugin to list of third-party plugins ([#2931]({{ site.repository }}/issues/2931))
- (Minor) Grammar & `_config.yml` filename fixes ([#2911]({{ site.repository }}/issues/2911))
- Added `mathml.rb` to the list of third-party plugins. ([#2937]({{ site.repository }}/issues/2937))
@@ -197,11 +701,9 @@ permalink: "/docs/history/"
- Document the `name` variable for collection permalinks ([#2829]({{ site.repository }}/issues/2829))
- Adds info about installing jekyll in current dir ([#2839]({{ site.repository }}/issues/2839))
-- Remove deprecated `jekyll-projectlist` plugin from list of third-party
- plugins ([#2742]({{ site.repository }}/issues/2742))
+- Remove deprecated `jekyll-projectlist` plugin from list of third-party plugins ([#2742]({{ site.repository }}/issues/2742))
- Remove tag plugins that are built in to Jekyll ([#2751]({{ site.repository }}/issues/2751))
-- Add `markdown-writer` package for Atom Editor to list of third-party
- plugins ([#2763]({{ site.repository }}/issues/2763))
+- Add `markdown-writer` package for Atom Editor to list of third-party plugins ([#2763]({{ site.repository }}/issues/2763))
- Fix typo in site documentation for collections ([#2764]({{ site.repository }}/issues/2764))
- Fix minor typo on plugins docs page ([#2765]({{ site.repository }}/issues/2765))
- Replace markdown with HTML in `sass_dir` note on assets page ([#2791]({{ site.repository }}/issues/2791))
@@ -301,8 +803,7 @@ permalink: "/docs/history/"
{: #site-enhancements-v2-2-0}
- Update Kramdown urls ([#2588]({{ site.repository }}/issues/2588))
-- Add `Jekyll::AutolinkEmail` and `Jekyll::GitMetadata` to the list of
- third-party plugins ([#2596]({{ site.repository }}/issues/2596))
+- Add `Jekyll::AutolinkEmail` and `Jekyll::GitMetadata` to the list of third-party plugins ([#2596]({{ site.repository }}/issues/2596))
- Fix a bunch of broken links in the site ([#2601]({{ site.repository }}/issues/2601))
- Replace dead links with working links ([#2611]({{ site.repository }}/issues/2611))
- Add jekyll-hook to deployment methods ([#2617]({{ site.repository }}/issues/2617))
@@ -346,12 +847,10 @@ permalink: "/docs/history/"
- Allow subdirectories in `_data` ([#2395]({{ site.repository }}/issues/2395))
- Extract Pagination Generator into gem: `jekyll-paginate` ([#2455]({{ site.repository }}/issues/2455))
- Utilize `date_to_rfc822` filter in site template ([#2437]({{ site.repository }}/issues/2437))
-- Add categories, last build datetime, and generator to site template
- feed ([#2438]({{ site.repository }}/issues/2438))
+- Add categories, last build datetime, and generator to site template feed ([#2438]({{ site.repository }}/issues/2438))
- Configurable, replaceable Logger-compliant logger ([#2444]({{ site.repository }}/issues/2444))
- Extract `gist` tag into a separate gem ([#2469]({{ site.repository }}/issues/2469))
-- Add `collection` attribute to `Document#to_liquid` to access the
- document's collection label. ([#2436]({{ site.repository }}/issues/2436))
+- Add `collection` attribute to `Document#to_liquid` to access the document's collection label. ([#2436]({{ site.repository }}/issues/2436))
- Upgrade listen to `2.7.6 <= x < 3.0.0` ([#2492]({{ site.repository }}/issues/2492))
- Allow configuration of different Twitter and GitHub usernames in site template ([#2485]({{ site.repository }}/issues/2485))
- Bump Pygments to v0.6.0 ([#2504]({{ site.repository }}/issues/2504))
@@ -377,8 +876,7 @@ permalink: "/docs/history/"
- Allow front matter defaults to set post categories ([#2373]({{ site.repository }}/issues/2373))
- Fix command in subcommand deprecation warning ([#2457]({{ site.repository }}/issues/2457))
- Keep all parent directories of files/dirs in `keep_files` ([#2458]({{ site.repository }}/issues/2458))
-- When using RedCarpet and Rouge without Rouge installed, fixed erroneous
- error which stated that redcarpet was missing, not rouge. ([#2464]({{ site.repository }}/issues/2464))
+- When using RedCarpet and Rouge without Rouge installed, fixed erroneous error which stated that redcarpet was missing, not rouge. ([#2464]({{ site.repository }}/issues/2464))
- Ignore *all* directories and files that merit it on auto-generation ([#2459]({{ site.repository }}/issues/2459))
- Before copying file, explicitly remove the old one ([#2535]({{ site.repository }}/issues/2535))
- Merge file system categories with categories from YAML. ([#2531]({{ site.repository }}/issues/2531))
@@ -409,8 +907,7 @@ permalink: "/docs/history/"
- Prevent table from extending parent width in permalink style table ([#2424]({{ site.repository }}/issues/2424))
- Add collections to info about pagination support ([#2389]({{ site.repository }}/issues/2389))
- Add `jekyll_github_sample` plugin to list of third-party plugins ([#2463]({{ site.repository }}/issues/2463))
-- Clarify documentation around front matter defaults and add details
- about defaults for collections. ([#2439]({{ site.repository }}/issues/2439))
+- Clarify documentation around front matter defaults and add details about defaults for collections. ([#2439]({{ site.repository }}/issues/2439))
- Add Jekyll Project Version Tag to list of third-party plugins ([#2468]({{ site.repository }}/issues/2468))
- Use `https` for GitHub links across whole site ([#2470]({{ site.repository }}/issues/2470))
- Add StickerMule + Jekyll post ([#2476]({{ site.repository }}/issues/2476))
@@ -429,13 +926,11 @@ permalink: "/docs/history/"
### Bug Fixes
{: #bug-fixes-v2-0-3}
-- Properly prefix links in site template with URL or baseurl depending upon
- need. ([#2319]({{ site.repository }}/issues/2319))
+- Properly prefix links in site template with URL or baseurl depending upon need. ([#2319]({{ site.repository }}/issues/2319))
- Update gist tag comments and error message to require username ([#2326]({{ site.repository }}/issues/2326))
- Fix `permalink` setting in site template ([#2331]({{ site.repository }}/issues/2331))
- Don't fail if any of the path objects are nil ([#2325]({{ site.repository }}/issues/2325))
-- Instantiate all descendants for converters and generators, not just
- direct subclasses ([#2334]({{ site.repository }}/issues/2334))
+- Instantiate all descendants for converters and generators, not just direct subclasses ([#2334]({{ site.repository }}/issues/2334))
- Replace all instances of `site.name` with `site.title` in site template ([#2324]({{ site.repository }}/issues/2324))
- `Jekyll::Filters#time` now accepts UNIX timestamps in string or number form ([#2339]({{ site.repository }}/issues/2339))
- Use `item_property` for `where` filter so it doesn't break on collections ([#2359]({{ site.repository }}/issues/2359))
@@ -482,17 +977,16 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v2-0-0}
+
- Add "Collections" feature ([#2199]({{ site.repository }}/issues/2199))
- Add gem-based plugin whitelist to safe mode ([#1657]({{ site.repository }}/issues/1657))
-- Replace the commander command line parser with a more robust
- solution for our needs called `mercenary` ([#1706]({{ site.repository }}/issues/1706))
+- Replace the commander command line parser with a more robust solution for our needs called `mercenary` ([#1706]({{ site.repository }}/issues/1706))
- Remove support for Ruby 1.8.x ([#1780]({{ site.repository }}/issues/1780))
- Move to jekyll/jekyll from mojombo/jekyll ([#1817]({{ site.repository }}/issues/1817))
- Allow custom markdown processors ([#1872]({{ site.repository }}/issues/1872))
- Provide support for the Rouge syntax highlighter ([#1859]({{ site.repository }}/issues/1859))
- Provide support for Sass ([#1932]({{ site.repository }}/issues/1932))
-- Provide a 300% improvement when generating sites that use
- `Post#next` or `Post#previous` ([#1983]({{ site.repository }}/issues/1983))
+- Provide a 300% improvement when generating sites that use `Post#next` or `Post#previous` ([#1983]({{ site.repository }}/issues/1983))
- Provide support for CoffeeScript ([#1991]({{ site.repository }}/issues/1991))
- Replace Maruku with Kramdown as Default Markdown Processor ([#1988]({{ site.repository }}/issues/1988))
- Expose `site.static_files` to Liquid ([#2075]({{ site.repository }}/issues/2075))
@@ -504,10 +998,9 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v2-0-0}
-- Move the EntryFilter class into the Jekyll module to avoid polluting the
- global namespace ([#1800]({{ site.repository }}/issues/1800))
-- Add `group_by` Liquid filter create lists of items grouped by a common
- property's value ([#1788]({{ site.repository }}/issues/1788))
+
+- Move the EntryFilter class into the Jekyll module to avoid polluting the global namespace ([#1800]({{ site.repository }}/issues/1800))
+- Add `group_by` Liquid filter create lists of items grouped by a common property's value ([#1788]({{ site.repository }}/issues/1788))
- Add support for Maruku's `fenced_code_blocks` option ([#1799]({{ site.repository }}/issues/1799))
- Update Redcarpet dependency to ~> 3.0 ([#1815]({{ site.repository }}/issues/1815))
- Automatically sort all pages by name ([#1848]({{ site.repository }}/issues/1848))
@@ -518,12 +1011,10 @@ permalink: "/docs/history/"
- Bump dependency `safe_yaml` to `~> 1.0` ([#1886]({{ site.repository }}/issues/1886))
- Allow sorting of content by custom properties ([#1849]({{ site.repository }}/issues/1849))
- Add `--quiet` flag to silence output during build and serve ([#1898]({{ site.repository }}/issues/1898))
-- Add a `where` filter to filter arrays based on a key/value pair
- ([#1875]({{ site.repository }}/issues/1875))
+- Add a `where` filter to filter arrays based on a key/value pair ([#1875]({{ site.repository }}/issues/1875))
- Route 404 errors to a custom 404 page in development ([#1899]({{ site.repository }}/issues/1899))
- Excludes are now relative to the site source ([#1916]({{ site.repository }}/issues/1916))
-- Bring MIME Types file for `jekyll serve` to complete parity with GH Pages
- servers ([#1993]({{ site.repository }}/issues/1993))
+- Bring MIME Types file for `jekyll serve` to complete parity with GH Pages servers ([#1993]({{ site.repository }}/issues/1993))
- Adding Breakpoint to make new site template more responsive ([#2038]({{ site.repository }}/issues/2038))
- Default to using the UTF-8 encoding when reading files. ([#2031]({{ site.repository }}/issues/2031))
- Update Redcarpet dependency to ~> 3.1 ([#2044]({{ site.repository }}/issues/2044))
@@ -541,13 +1032,11 @@ permalink: "/docs/history/"
- Add support for unpublished drafts ([#2164]({{ site.repository }}/issues/2164))
- Add `force_polling` option to the `serve` command ([#2165]({{ site.repository }}/issues/2165))
- Clean up the `` in the site template ([#2186]({{ site.repository }}/issues/2186))
-- Permit YAML blocks to end with three dots to better conform with the
- YAML spec ([#2110]({{ site.repository }}/issues/2110))
+- Permit YAML blocks to end with three dots to better conform with the YAML spec ([#2110]({{ site.repository }}/issues/2110))
- Use `File.exist?` instead of deprecated `File.exists?` ([#2214]({{ site.repository }}/issues/2214))
- Require newline after start of YAML Front Matter header ([#2211]({{ site.repository }}/issues/2211))
- Add the ability for pages to be marked as `published: false` ([#1492]({{ site.repository }}/issues/1492))
-- Add `Jekyll::LiquidExtensions` with `.lookup_variable` method for easy
- looking up of variable values in a Liquid context. ([#2253]({{ site.repository }}/issues/2253))
+- Add `Jekyll::LiquidExtensions` with `.lookup_variable` method for easy looking up of variable values in a Liquid context. ([#2253]({{ site.repository }}/issues/2253))
- Remove literal lang name from class ([#2292]({{ site.repository }}/issues/2292))
- Return `utf-8` encoding in header for webrick error page response ([#2289]({{ site.repository }}/issues/2289))
- Make template site easier to customize ([#2268]({{ site.repository }}/issues/2268))
@@ -557,13 +1046,12 @@ permalink: "/docs/history/"
### Bug Fixes
{: #bug-fixes-v2-0-0}
+
- Don't allow nil entries when loading posts ([#1796]({{ site.repository }}/issues/1796))
-- Remove the scrollbar that's always displayed in new sites generated
- from the site template ([#1805]({{ site.repository }}/issues/1805))
+- Remove the scrollbar that's always displayed in new sites generated from the site template ([#1805]({{ site.repository }}/issues/1805))
- Add `#path` to required methods in `Jekyll::Convertible` ([#1866]({{ site.repository }}/issues/1866))
- Default Maruku fenced code blocks to ON for 2.0.0-dev ([#1831]({{ site.repository }}/issues/1831))
-- Change short opts for host and port for `jekyll docs` to be consistent with
- other subcommands ([#1877]({{ site.repository }}/issues/1877))
+- Change short opts for host and port for `jekyll docs` to be consistent with other subcommands ([#1877]({{ site.repository }}/issues/1877))
- Fix typos ([#1910]({{ site.repository }}/issues/1910))
- Lock Maruku at 0.7.0 to prevent bugs caused by Maruku 0.7.1 ([#1958]({{ site.repository }}/issues/1958))
- Fixes full path leak to source directory when using include tag ([#1951]({{ site.repository }}/issues/1951))
@@ -575,9 +1063,8 @@ permalink: "/docs/history/"
- Patch a couple show-stopping security vulnerabilities ([#1946]({{ site.repository }}/issues/1946))
- Sanitize paths uniformly, in a Windows-friendly way ([#2065]({{ site.repository }}/issues/2065), [#2109]({{ site.repository }}/issues/2109))
- Update gem build steps to work correctly on Windows ([#2118]({{ site.repository }}/issues/2118))
-- Remove obsolete `normalize_options` method call from `bin/jekyll` ([#2121]({{ site.repository }}/issues/2121)).
-- Remove `+` characters from Pygments lexer names when adding as a CSS
- class ([#994]({{ site.repository }}/issues/994))
+- Remove obsolete `normalize_options` method call from `bin/jekyll` ([#2121]({{ site.repository }}/issues/2121))
+- Remove `+` characters from Pygments lexer names when adding as a CSS class ([#994]({{ site.repository }}/issues/994))
- Remove some code that caused Ruby interpreter warnings ([#2178]({{ site.repository }}/issues/2178))
- Only strip the drive name if it begins the string ([#2175]({{ site.repository }}/issues/2175))
- Remove default post with invalid date from site template ([#2200]({{ site.repository }}/issues/2200))
@@ -593,14 +1080,14 @@ permalink: "/docs/history/"
### Development Fixes
{: #development-fixes-v2-0-0}
+
- Add a link to the site in the README.md file ([#1795]({{ site.repository }}/issues/1795))
- Add in History and site changes from `v1-stable` branch ([#1836]({{ site.repository }}/issues/1836))
- Testing additions on the Excerpt class ([#1893]({{ site.repository }}/issues/1893))
- Fix the `highlight` tag feature ([#1859]({{ site.repository }}/issues/1859))
- Test Jekyll under Ruby 2.1.0 ([#1900]({{ site.repository }}/issues/1900))
- Add script/cibuild for fun and profit ([#1912]({{ site.repository }}/issues/1912))
-- Use `Forwardable` for delegation between `Excerpt` and `Post`
- ([#1927]({{ site.repository }}/issues/1927))
+- Use `Forwardable` for delegation between `Excerpt` and `Post` ([#1927]({{ site.repository }}/issues/1927))
- Rename `read_things` to `read_content` ([#1928]({{ site.repository }}/issues/1928))
- Add `script/branding` script for ASCII art lovin' ([#1936]({{ site.repository }}/issues/1936))
- Update the README to reflect the repo move ([#1943]({{ site.repository }}/issues/1943))
@@ -629,11 +1116,11 @@ permalink: "/docs/history/"
### Site Enhancements
{: #site-enhancements-v2-0-0}
+
- Document Kramdown's GFM parser option ([#1791]({{ site.repository }}/issues/1791))
- Move CSS to includes & update normalize.css to v2.1.3 ([#1787]({{ site.repository }}/issues/1787))
- Minify CSS only in production ([#1803]({{ site.repository }}/issues/1803))
-- Fix broken link to installation of Ruby on Mountain Lion blog post on
- Troubleshooting docs page ([#1797]({{ site.repository }}/issues/1797))
+- Fix broken link to installation of Ruby on Mountain Lion blog post on Troubleshooting docs page ([#1797]({{ site.repository }}/issues/1797))
- Fix issues with 1.4.1 release blog post ([#1804]({{ site.repository }}/issues/1804))
- Add note about deploying to OpenShift ([#1812]({{ site.repository }}/issues/1812))
- Collect all Windows-related docs onto one page ([#1818]({{ site.repository }}/issues/1818))
@@ -648,8 +1135,7 @@ permalink: "/docs/history/"
- Add jekyll-compass to the plugin list ([#1923]({{ site.repository }}/issues/1923))
- Add note in Posts docs about stripping `
` tags from excerpt ([#1933]({{ site.repository }}/issues/1933))
- Add additional info about the new exclude behavior ([#1938]({{ site.repository }}/issues/1938))
-- Linkify 'awesome contributors' to point to the contributors graph on
- GitHub ([#1940]({{ site.repository }}/issues/1940))
+- Linkify 'awesome contributors' to point to the contributors graph on GitHub ([#1940]({{ site.repository }}/issues/1940))
- Update `docs/sites.md` link to GitHub Training materials ([#1949]({{ site.repository }}/issues/1949))
- Update `master` with the release info from 1.4.3 ([#1947]({{ site.repository }}/issues/1947))
- Define docs nav in datafile ([#1953]({{ site.repository }}/issues/1953))
@@ -666,8 +1152,7 @@ permalink: "/docs/history/"
- Update link to rack-jekyll on "Deployment Methods" page ([#2047]({{ site.repository }}/issues/2047))
- Fix typo in /docs/configuration ([#2073]({{ site.repository }}/issues/2073))
- Fix count in docs for `site.static_files` ([#2077]({{ site.repository }}/issues/2077))
-- Update configuration docs to indicate utf-8 is the default for 2.0.0
- and ASCII for 1.9.3 ([#2074]({{ site.repository }}/issues/2074))
+- Update configuration docs to indicate utf-8 is the default for 2.0.0 and ASCII for 1.9.3 ([#2074]({{ site.repository }}/issues/2074))
- Add info about unreleased feature to the site ([#2061]({{ site.repository }}/issues/2061))
- Add whitespace to liquid example in GitHub Pages docs ([#2084]({{ site.repository }}/issues/2084))
- Clarify the way Sass and CoffeeScript files are read in and output ([#2067]({{ site.repository }}/issues/2067))
@@ -684,8 +1169,7 @@ permalink: "/docs/history/"
- Some HTML tidying ([#2130]({{ site.repository }}/issues/2130))
- Remove modernizr and use html5shiv.js directly for IE less than v9 ([#2131]({{ site.repository }}/issues/2131))
- Remove unused images ([#2187]({{ site.repository }}/issues/2187))
-- Use `array_to_sentence_string` filter when outputting news item
- categories ([#2191]({{ site.repository }}/issues/2191))
+- Use `array_to_sentence_string` filter when outputting news item categories ([#2191]({{ site.repository }}/issues/2191))
- Add link to Help repo in primary navigation bar ([#2177]({{ site.repository }}/issues/2177))
- Switch to using an ico file for the shortcut icon ([#2193]({{ site.repository }}/issues/2193))
- Use numbers to specify font weights and only bring in font weights used ([#2185]({{ site.repository }}/issues/2185))
@@ -746,6 +1230,7 @@ permalink: "/docs/history/"
### Bug Fixes
{: #bug-fixes-v1-4-3}
+
- Patch show-stopping security vulnerabilities ([#1944]({{ site.repository }}/issues/1944))
@@ -754,6 +1239,7 @@ permalink: "/docs/history/"
### Bug Fixes
{: #bug-fixes-v1-4-2}
+
- Turn on Maruku fenced code blocks by default ([#1830]({{ site.repository }}/issues/1830))
@@ -762,6 +1248,7 @@ permalink: "/docs/history/"
### Bug Fixes
{: #bug-fixes-v1-4-1}
+
- Don't allow nil entries when loading posts ([#1796]({{ site.repository }}/issues/1796))
@@ -770,25 +1257,30 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v1-4-0}
+
- Add support for TOML config files ([#1765]({{ site.repository }}/issues/1765))
### Minor Enhancements
{: #minor-enhancements-v1-4-0}
+
- 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
{: #bug-fixes-v1-4-0}
+
- 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
{: #development-fixes-v1-4-0}
+
- 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
{: #site-enhancements-v1-4-0}
+
- 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))
@@ -798,19 +1290,20 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v1-3-1}
+
- 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))
+- Push the paginator plugin lower in the plugin priority order so other plugins run before it ([#1759]({{ site.repository }}/issues/1759))
### Bug Fixes
{: #bug-fixes-v1-3-1}
+
- 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))
+- Specify where the include is called from if an included file is missing ([#1746]({{ site.repository }}/issues/1746))
### Development Fixes
{: #development-fixes-v1-3-1}
+
- 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))
@@ -818,11 +1311,10 @@ permalink: "/docs/history/"
### Site Enhancements
{: #site-enhancements-v1-3-1}
+
- 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))
+- 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))
@@ -837,47 +1329,43 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v1-3-0}
-- Add support for adding data as YAML files under a site's `_data`
- directory ([#1003]({{ site.repository }}/issues/1003))
+
+- 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
{: #minor-enhancements-v1-3-0}
+
- 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))
+- 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))
+- Point people to the migration docs when the `jekyll-import` gem is missing ([#1662]({{ site.repository }}/issues/1662))
### Bug Fixes
{: #bug-fixes-v1-3-0}
-- Fix up matching against source and destination when the two
- locations are similar ([#1556]({{ site.repository }}/issues/1556))
+
+- 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))
+- 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))
+- Fix an error with the new file watching code due to library version incompatibilities ([#1687]({{ site.repository }}/issues/1687))
### Development Fixes
{: #development-fixes-v1-3-0}
+
- 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))
@@ -895,6 +1383,7 @@ permalink: "/docs/history/"
### Site Enhancements
{: #site-enhancements-v1-3-0}
+
- 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))
@@ -902,8 +1391,7 @@ permalink: "/docs/history/"
- 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))
+- 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))
@@ -918,6 +1406,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v1-2-1}
+
- 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))
@@ -925,17 +1414,20 @@ permalink: "/docs/history/"
### Bug Fixes
{: #bug-fixes-v1-2-1}
+
- Fix file discrepancy in gemspec ([#1522]({{ site.repository }}/issues/1522))
- Force rendering of Include tag ([#1525]({{ site.repository }}/issues/1525))
### Development Fixes
{: #development-fixes-v1-2-1}
+
- 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
{: #site-enhancements-v1-2-1}
+
- 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.
@@ -948,45 +1440,41 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v1-2-0}
+
- 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
{: #minor-enhancements-v1-2-0}
+
- 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))
+- 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))
+- 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))
+- Expose the current Jekyll version to posts and pages via a new `jekyll.version` variable ([#1481]({{ site.repository }}/issues/1481))
### Bug Fixes
{: #bug-fixes-v1-2-0}
+
- 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))
+- 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))
+- 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))
+- Provide proper error handling for invalid file names in the include tag ([#1494]({{ site.repository }}/issues/1494))
### Development Fixes
{: #development-fixes-v1-2-0}
-- Remove redundant argument to
- Jekyll::Commands::New#scaffold_post_content ([#1356]({{ site.repository }}/issues/1356))
+
+- 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))
@@ -997,6 +1485,7 @@ permalink: "/docs/history/"
### Site Enhancements
{: #site-enhancements-v1-2-0}
+
- 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))
@@ -1024,6 +1513,7 @@ permalink: "/docs/history/"
### Bug Fixes
{: #bug-fixes-v1-1-2}
+
- Require Liquid 2.5.1 ([#1349]({{ site.repository }}/issues/1349))
@@ -1032,26 +1522,26 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v1-1-1}
+
- 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
{: #bug-fixes-v1-1-1}
+
- Fix up the rendering of excerpts ([#1339]({{ site.repository }}/issues/1339))
### Site Enhancements
{: #site-enhancements-v1-1-1}
+
- 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 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))
+- 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))
@@ -1060,34 +1550,33 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v1-1-0}
+
- 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
{: #minor-enhancements-v1-1-0}
-- Search the hierarchy of pagination path up to site root to determine template page for
- pagination. ([#1198]({{ site.repository }}/issues/1198))
+
+- 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))
+- 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
{: #bug-fixes-v1-1-0}
+
- 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))
+- 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
{: #development-fixes-v1-1-0}
+
- 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))
@@ -1096,22 +1585,20 @@ permalink: "/docs/history/"
### Site Enhancements
{: #site-enhancements-v1-1-0}
+
- 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))
+- 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))
+- 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))
+- 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))
@@ -1125,13 +1612,11 @@ permalink: "/docs/history/"
- 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 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))
+- Add information about time zones to the documentation for a page's date ([#1304]({{ site.repository }}/issues/1304))
## 1.0.3 / 2013-06-07
@@ -1139,6 +1624,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v1-0-3}
+
- 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))
@@ -1148,17 +1634,17 @@ permalink: "/docs/history/"
### Bug Fixes
{: #bug-fixes-v1-0-3}
+
- 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))
+- 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))
+- Fix the application of Pygments' Generic Output style to Go code ([#1156]({{ site.repository }}/issues/1156))
### Site Enhancements
{: #site-enhancements-v1-0-3}
+
- 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))
@@ -1172,13 +1658,13 @@ permalink: "/docs/history/"
- 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))
+- 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
{: #development-fixes-v1-0-3}
+
- 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))
@@ -1190,11 +1676,13 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v1-0-2}
+
- 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
{: #minor-enhancements-v1-0-2}
+
- Add a `data-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))
@@ -1202,11 +1690,13 @@ permalink: "/docs/history/"
### Bug Fixes
{: #bug-fixes-v1-0-2}
+
- 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
{: #site-enhancements-v1-0-2}
+
- 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))
@@ -1218,12 +1708,14 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v1-0-1}
+
- 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
{: #bug-fixes-v1-0-1}
+
- 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))
@@ -1231,6 +1723,7 @@ permalink: "/docs/history/"
### Site Enhancements
{: #site-enhancements-v1-0-1}
+
- 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))
@@ -1238,6 +1731,7 @@ permalink: "/docs/history/"
### Development Fixes
{: #development-fixes-v1-0-1}
+
- Markdownify history file ([#1027]({{ site.repository }}/issues/1027))
- Update links on README to point to new jekyllrb.com ([#1018]({{ site.repository }}/issues/1018))
@@ -1247,6 +1741,7 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v1-0-0}
+
- 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))
@@ -1255,6 +1750,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v1-0-0}
+
- 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))
@@ -1294,8 +1790,7 @@ permalink: "/docs/history/"
- 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))
+- 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))
@@ -1321,8 +1816,7 @@ permalink: "/docs/history/"
- 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))
+- 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))
@@ -1330,6 +1824,7 @@ permalink: "/docs/history/"
### Site Enhancements
{: #site-enhancements-v1-0-0}
+
- 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))
@@ -1341,15 +1836,14 @@ permalink: "/docs/history/"
### Development Fixes
{: #development-fixes-v1-0-0}
+
- 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))
+- 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))
+- 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))
@@ -1358,6 +1852,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v0-12-1}
+
- 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))
@@ -1370,6 +1865,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v0-12-0}
+
- 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))
@@ -1391,12 +1887,14 @@ permalink: "/docs/history/"
## 0.11.2 / 2011-12-27
{: #v0-11-2}
+
- Bug Fixes
- Fix gemspec
## 0.11.1 / 2011-12-27
{: #v0-11-1}
+
- Bug Fixes
- Fix extra blank line in highlight blocks ([#409]({{ site.repository }}/issues/409))
- Update dependencies
@@ -1407,6 +1905,7 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v0-11-0}
+
- 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))
@@ -1414,6 +1913,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v0-11-0}
+
- Switch to Albino gem
- Bundler support
- Use English library to avoid hoops ([#292]({{ site.repository }}/issues/292))
@@ -1429,6 +1929,7 @@ permalink: "/docs/history/"
## 0.10.0 / 2010-12-16
{: #v0-10-0}
+
- Bug Fixes
- Add `--no-server` option.
@@ -1438,6 +1939,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v0-9-0}
+
- 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))
@@ -1450,6 +1952,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v0-8-0}
+
- 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))
@@ -1467,6 +1970,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v0-7-0}
+
- Add support for rdiscount extensions ([#173]({{ site.repository }}/issues/173))
- Bug Fixes
- Highlight should not be able to render local files
@@ -1475,6 +1979,7 @@ permalink: "/docs/history/"
## 0.6.2 / 2010-06-25
{: #v0-6-2}
+
- 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))
@@ -1484,6 +1989,7 @@ permalink: "/docs/history/"
## 0.6.1 / 2010-06-24
{: #v0-6-1}
+
- Bug Fixes
- Fix Markdown Pygments prefix and suffix ([#178]({{ site.repository }}/issues/178))
@@ -1493,19 +1999,18 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v0-6-0}
+
- 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))
+- 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
{: #minor-enhancements-v0-6-0}
+
- 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
+- 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))
@@ -1525,24 +2030,26 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v0-5-7}
+
- 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
+- Cucumber features no longer use site.posts.first where a better alternative is available
## 0.5.6 / 2010-01-08
{: #v0-5-6}
+
- Bug Fixes
- Require redcloth >= 4.2.1 in tests ([#92]({{ site.repository }}/issues/92))
- Don't break on triple dashes in yaml front matter ([#93]({{ site.repository }}/issues/93))
### Minor Enhancements
{: #minor-enhancements-v0-5-6}
+
- 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))
@@ -1551,52 +2058,42 @@ permalink: "/docs/history/"
## 0.5.5 / 2010-01-08
{: #v0-5-5}
+
- 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.
+- 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
{: #v0-5-4}
+
- Bug Fixes
- Do not allow symlinks (security vulnerability)
## 0.5.3 / 2009-07-14
{: #v0-5-3}
+
- Bug Fixes
-- Solving the permalink bug where non-html files wouldn't work
- ([@jeffrydegrande](https://github.com/jeffrydegrande))
+- Solving the permalink bug where non-html files wouldn't work ([@jeffrydegrande](https://github.com/jeffrydegrande))
## 0.5.2 / 2009-06-24
{: #v0-5-2}
+
- 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 `` 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)
+- 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 `` 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)
- Bug Fixes
-- Fixing Ruby 1.9 issue that requires `#to_s` on the err object
- ([@Chrononaut](https://github.com/Chrononaut))
+- 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)
+- 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)
- Allow CRLFs in yaml front matter ([@juretta](https://github.com/juretta))
- Added Date#xmlschema for Ruby versions < 1.9
@@ -1606,16 +2103,15 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v0-5-1}
+
- 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))
+- 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))
+- 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))
@@ -1624,6 +2120,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v0-5-0}
+
- 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))
@@ -1645,6 +2142,7 @@ permalink: "/docs/history/"
### Minor Enhancements
{: #minor-enhancements-v--}
+
- 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))
@@ -1655,10 +2153,12 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v0-4-0}
+
- Switch to Jeweler for packaging tasks
### Minor Enhancements
{: #minor-enhancements-v0-4-0}
+
- 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))
@@ -1680,43 +2180,46 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v0-3-0}
-- Added `--server` option to start a simple WEBrick server on destination
- directory ([@johnreilly](https://github.com/johnreilly) and [@mchung](https://github.com/mchung))
+
+- 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
{: #minor-enhancements-v0-3-0}
+
- 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))
+- 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
{: #v0-2-1}
+
- Major Changes
- Use Maruku (pure Ruby) for Markdown by default ([@mreid](https://github.com/mreid))
- Allow use of RDiscount with `--rdiscount` flag
### Minor Enhancements
{: #minor-enhancements-v0-2-1}
+
- Don't load directory_watcher unless it's needed ([@pjhyett](https://github.com/pjhyett))
## 0.2.0 / 2008-12-14
{: #v0-2-0}
+
- Major Changes
- related_posts is now found in `site.related_posts`
## 0.1.6 / 2008-12-13
{: #v0-1-6}
+
- Major Features
- Include files in `_includes` with {% raw %}`{% include x.textile %}`{% endraw %}
@@ -1726,11 +2229,13 @@ permalink: "/docs/history/"
### Major Enhancements
{: #major-enhancements-v0-1-5}
+
- Code highlighting with Pygments if `--pygments` is specified
- Disable true LSI by default, enable with `--lsi`
### Minor Enhancements
{: #minor-enhancements-v0-1-5}
+
- 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))
@@ -1739,12 +2244,14 @@ permalink: "/docs/history/"
## 0.1.4 / 2008-12-08
{: #v0-1-4}
+
- Bug Fixes
- DATA does not work properly with rubygems
## 0.1.3 / 2008-12-06
{: #v0-1-3}
+
- Major Features
- Markdown support ([@vanpelt](https://github.com/vanpelt))
- Mephisto and CSV converters ([@vanpelt](https://github.com/vanpelt))
@@ -1756,21 +2263,23 @@ permalink: "/docs/history/"
## 0.1.2 / 2008-11-22
{: #v0-1-2}
+
- 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
+- Allow cli to be called with 0, 1, or 2 args intuiting dir paths if they are omitted
## 0.1.1 / 2008-11-22
{: #v0-1-1}
+
- Minor Additions
- Posts now support introspectional data e.g. {% raw %}`{{ page.url }}`{% endraw %}
## 0.1.0 / 2008-11-05
{: #v0-1-0}
+
- First release
- Converts posts written in Textile
- Converts regular site pages
@@ -1779,4 +2288,5 @@ permalink: "/docs/history/"
## 0.0.0 / 2008-10-19
{: #v0-0-0}
+
- Birthday!
diff --git a/site/_docs/index.md b/site/_docs/index.md
index bbb18087..5e08d760 100644
--- a/site/_docs/index.md
+++ b/site/_docs/index.md
@@ -2,6 +2,7 @@
layout: docs
title: Welcome
permalink: /docs/home/
+redirect_from: /docs/index.html
---
This site aims to be a comprehensive guide to Jekyll. We’ll cover topics such
@@ -14,11 +15,11 @@ development of Jekyll itself.
Jekyll is a simple, blog-aware, static site generator. It takes a template
directory containing raw text files in various formats, runs it through
-a converter (like [Markdown](http://daringfireball.net/projects/markdown/))
+a converter (like [Markdown](https://daringfireball.net/projects/markdown/))
and our [Liquid](https://github.com/Shopify/liquid/wiki) renderer, 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
+behind [GitHub Pages](https://pages.github.com), which means you can use Jekyll
to host your project’s page, blog, or website from GitHub’s servers **for
free**.
diff --git a/site/_docs/installation.md b/site/_docs/installation.md
index aee4b594..e557cb76 100644
--- a/site/_docs/installation.md
+++ b/site/_docs/installation.md
@@ -4,22 +4,23 @@ title: Installation
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.
+Getting Jekyll installed and ready-to-go should only take a few minutes.
+If it ever becomes a pain, 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/) (including development
- headers)
-- [RubyGems](http://rubygems.org/pages/download)
+- [Ruby](https://www.ruby-lang.org/en/downloads/) (including development
+ headers, v1.9.3 or above for Jekyll 2 and v2 or above for Jekyll 3)
+- [RubyGems](https://rubygems.org/pages/download)
- Linux, Unix, or Mac OS X
-- [NodeJS](http://nodejs.org), or another JavaScript runtime (for
- CoffeeScript support).
+- [NodeJS](https://nodejs.org/), or another JavaScript runtime (Jekyll 2 and
+earlier, for CoffeeScript support).
+- [Python 2.7](https://www.python.org/downloads/) (for Jekyll 2 and earlier)
Running Jekyll on Windows
diff --git a/site/_docs/migrations.md b/site/_docs/migrations.md
index 0544341a..961762f7 100644
--- a/site/_docs/migrations.md
+++ b/site/_docs/migrations.md
@@ -6,4 +6,4 @@ 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/docs/home/).
+visit our [`jekyll-import` docs site](https://import.jekyllrb.com/docs/home/).
diff --git a/site/_docs/pages.md b/site/_docs/pages.md
index fa76a9fb..aaed2e14 100644
--- a/site/_docs/pages.md
+++ b/site/_docs/pages.md
@@ -27,12 +27,14 @@ homepage of your Jekyll-generated site.
## Where additional pages live
-Where you put HTML files for pages depends on how you want the pages to work.
+Where you put HTML or [Markdown](https://daringfireball.net/projects/markdown/)
+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.
+- Place named HTML or [Markdown](https://daringfireball.net/projects/markdown/)
+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.
+or index.md 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.
@@ -53,6 +55,7 @@ and associated URLs might look like:
|-- _site/
|-- about.html # => http://example.com/about.html
|-- index.html # => http://example.com/
+|-- other.md # => http://example.com/other.html
└── contact.html # => http://example.com/contact.html
{% endhighlight %}
@@ -77,8 +80,21 @@ might look like:
| └── index.html # => http://example.com/about/
├── contact/
| └── index.html # => http://example.com/contact/
+|── other/
+| └── index.md # => http://example.com/other/
└── 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!
+simple and it works. In the end, the decision is yours!
+
+
+
ProTip™: Use permalink Front Matter Variable
+
+ Clean URLs can also be achieved using the permalink front
+ matter variable. In the example above, using the first method, you can
+ get URL http://example.com/other for the file
+ other.md by setting this at the top of the file:
+ permalink: /other
+
+
diff --git a/site/_docs/pagination.md b/site/_docs/pagination.md
index 2c0ae2b4..25482d01 100644
--- a/site/_docs/pagination.md
+++ b/site/_docs/pagination.md
@@ -4,10 +4,13 @@ title: Pagination
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.
+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 offers a pagination plugin, so you can automatically
+generate the appropriate files and folders you need for paginated listings.
+
+For Jekyll 3, include the `jekyll-paginate` plugin in your Gemfile and in
+your `_config.yml` under `gems`. For Jekyll 2, this is standard.
Pagination only works within HTML files
diff --git a/site/_docs/permalinks.md b/site/_docs/permalinks.md
index 962d4fe7..9ccf2706 100644
--- a/site/_docs/permalinks.md
+++ b/site/_docs/permalinks.md
@@ -73,14 +73,57 @@ permalink is defined according to the format `/:categories/:year/:month/:day/:ti
Year from the Post’s filename without the century.
+
+
+
hour
+
+
+
+ Hour of the day, 24-hour clock, zero-padded from the post’s date front matter. (00..23)
+
+
+
+
+
+
minute
+
+
+
+ Minute of the hour from the post’s date front matter. (00..59)
+
+
+
+
+
+
second
+
+
+
+ Second of the minute from the post’s date front matter. (00..59)
+
+
+
+
title
- Title from the document’s filename. May be overridden via the
- document’s slug YAML front matter.
+ Title from the document’s filename. May be overridden via
+ the document’s slug YAML front matter.
+
+
+
+
+
+
slug
+
+
+
+ Slugified title from the document’s filename ( any character
+ except numbers and letters is replaced as hyphen ). May be
+ overridden via the document’s slug YAML front matter.
@@ -153,14 +196,6 @@ Jekyll also provides the following built-in styles for convenience.
## Pages and collections
-
-
Support for improved page and collection permalinks is currently unreleased.
-
The `permalink` configuration setting specifies the permalink style used for
posts. Pages and collections each have their own default permalink style; the
default style for pages is `/:path/:basename` and the default for collections is
@@ -204,7 +239,7 @@ Given a post named: `/2009-04-29-slap-chop.md`
pretty
-
/2009/04/29/slap-chop/index.html
+
/2009/04/29/slap-chop/
@@ -238,14 +273,6 @@ Given a post named: `/2009-04-29-slap-chop.md`
## Extensionless permalinks
-
-
Support for extensionless permalink is currently unreleased.
-
Jekyll supports permalinks that contain neither a trailing slash nor a file
extension, but this requires additional support from the web server to properly
serve. When using extensionless permalinks, output files written to disk will
diff --git a/site/_docs/plugins.md b/site/_docs/plugins.md
index 023bc572..8a14fc15 100644
--- a/site/_docs/plugins.md
+++ b/site/_docs/plugins.md
@@ -11,7 +11,7 @@ having to modify the Jekyll source itself.
Plugins on GitHub Pages
- GitHub Pages is powered by Jekyll.
+ GitHub Pages is powered by Jekyll.
However, all Pages sites are generated using the --safe option
to disable custom plugins for security reasons. Unfortunately, this means
your plugins won’t work if you’re deploying to GitHub Pages.
@@ -31,15 +31,23 @@ 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]
+
+ gems: [jekyll-coffeescript, jekyll-watch, jekyll-assets]
# This will require each of these gems automatically.
+
+ Then install your plugins using `gem install jekyll-coffeescript jekyll-watch jekyll-assets`
+
3. Add the relevant plugins to a Bundler group in your `Gemfile`. An
example:
group :jekyll_plugins do
gem "my-jekyll-plugin"
+ gem "another-jekyll-plugin"
end
+ Now you need to install all plugins from your Bundler group by running single command `bundle install`
+
+
_plugins, _config.yml and Gemfile
@@ -52,12 +60,13 @@ values of the gem names of the plugins you'd like to use. An example:
-In general, plugins you make will fall into one of four categories:
+In general, plugins you make will fall into one of five categories:
1. [Generators](#generators)
2. [Converters](#converters)
3. [Commands](#commands)
4. [Tags](#tags)
+5. [Hooks](#hooks)
## Generators
@@ -302,7 +311,7 @@ Commands should implement this single class method:
This method accepts one parameter, the
- Mercenary::Program
+ Mercenary::Program
instance, which is the Jekyll program itself. Upon the program,
commands may be created using the above syntax. For more details,
visit the Mercenary repository on GitHub.com.
@@ -472,14 +481,6 @@ end
## Hooks
-
-
Using hooks, your plugin can exercise fine-grained control over various aspects
of the build process. If your plugin defines any hooks, Jekyll will call them
at pre-defined points.
@@ -491,13 +492,13 @@ custom functionality every time Jekyll renders a post, you could register a
hook like this:
{% highlight ruby %}
-Jekyll::Hooks.register :post, :post_render do |post|
+Jekyll::Hooks.register :posts, :post_render do |post|
# code to call after Jekyll renders a post
end
{% endhighlight %}
-Jekyll provides hooks for :site, :page,
-:post, and :document. In all cases, Jekyll calls your
+Jekyll provides hooks for :site, :pages,
+:posts, and :documents. In all cases, Jekyll calls your
hooks with the container object as the first callback parameter. But in the
case of :pre_render, your hook will also receive a payload hash as
a second parameter which allows you full control over the variables that are
@@ -526,6 +527,17 @@ The complete list of available hooks is below:
Just after site reset
+
+
+
:site
+
+
+
:post_read
+
+
+
After site data has been read and loaded from disk
+
+
:site
@@ -561,7 +573,7 @@ The complete list of available hooks is below:
-
:page
+
:pages
:post_init
@@ -572,7 +584,7 @@ The complete list of available hooks is below:
-
:page
+
:pages
:pre_render
@@ -583,7 +595,7 @@ The complete list of available hooks is below:
-
:page
+
:pages
:post_render
@@ -594,7 +606,7 @@ The complete list of available hooks is below:
-
:page
+
:pages
:post_write
@@ -605,7 +617,7 @@ The complete list of available hooks is below:
-
:post
+
:posts
:post_init
@@ -616,7 +628,7 @@ The complete list of available hooks is below:
-
:post
+
:posts
:pre_render
@@ -627,7 +639,7 @@ The complete list of available hooks is below:
-
:post
+
:posts
:post_render
@@ -638,7 +650,7 @@ The complete list of available hooks is below:
-
:post
+
:posts
:post_write
@@ -649,7 +661,18 @@ The complete list of available hooks is below:
-
:document
+
:documents
+
+
+
:post_init
+
+
+
Whenever a document is initialized
+
+
+
+
+
:documents
:pre_render
@@ -660,7 +683,7 @@ The complete list of available hooks is below:
-
:document
+
:documents
:post_render
@@ -671,7 +694,7 @@ The complete list of available hooks is below:
-
:document
+
:documents
:post_write
@@ -711,6 +734,11 @@ LESS.js files during generation.
- [Jekyll::GitMetadata by Ivan Tse](https://github.com/ivantsepp/jekyll-git_metadata): Expose Git metadata for your templates.
- [Jekyll Http Basic Auth Plugin](https://gist.github.com/snrbrnjna/422a4b7e017192c284b3): Plugin to manage http basic auth for jekyll generated pages and directories.
- [Jekyll Auto Image by Merlos](https://github.com/merlos/jekyll-auto-image): Gets the first image of a post. Useful to list your posts with images or to add [twitter cards](https://dev.twitter.com/cards/overview) to your site.
+- [Jekyll Portfolio Generator by Shannon Babincsak](https://github.com/codeinpink/jekyll-portfolio-generator): Generates project pages and computes related projects out of project data files.
+- [Jekyll-Umlauts by Arne Gockeln](https://github.com/webchef/jekyll-umlauts): This generator replaces all german umlauts (äöüß) case sensitive with html.
+- [Jekyll Flickr Plugin](https://github.com/lawmurray/indii-jekyll-flickr) by [Lawrence Murray](http://www.indii.org): Generates posts for photos uploaded to a Flickr photostream.
+- [Jekyll::Paginate::Category](https://github.com/midnightSuyama/jekyll-paginate-category): Pagination Generator for Jekyll Category.
+- [AMP-Jekyll by Juuso Mikkonen](https://github.com/juusaw/amp-jekyll): Generate [Accelerated Mobile Pages](https://www.ampproject.org) of Jekyll posts.
#### Converters
@@ -734,6 +762,8 @@ LESS.js files during generation.
- [Customized Kramdown Converter](https://github.com/mvdbos/kramdown-with-pygments): Enable Pygments syntax highlighting for Kramdown-parsed fenced code blocks.
- [Bigfootnotes Plugin](https://github.com/TheFox/jekyll-bigfootnotes): Enables big footnotes for Kramdown.
- [AsciiDoc Plugin](https://github.com/asciidoctor/jekyll-asciidoc): AsciiDoc convertor for Jekyll using [Asciidoctor](http://asciidoctor.org/).
+- [Lazy Tweet Embedding](https://github.com/takuti/jekyll-lazy-tweet-embedding): Automatically convert tweet urls into twitter cards.
+- [jekyll-commonmark](https://github.com/pathawks/jekyll-commonmark): Markdown converter that uses [libcmark](https://github.com/jgm/CommonMark), the reference parser for CommonMark.
#### Filters
@@ -744,9 +774,10 @@ LESS.js files during generation.
- [Smilify](https://github.com/SaswatPadhi/jekyll_smilify) by [SaswatPadhi](https://github.com/SaswatPadhi): Convert text emoticons in your content to themeable smiley pics.
- [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**”.
+- [pluralize](https://github.com/bdesham/pluralize): Easily combine a number and a word into a grammatically-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.
+- [jekyll-toc](https://github.com/toshimaru/jekyll-toc): A liquid filter plugin for Jekyll which generates a table of contents.
- [jekyll-humanize](https://github.com/23maverick23/jekyll-humanize): This is a port of the Django app humanize which adds a "human touch" to data. Each method represents a Fluid type filter that can be used in your Jekyll site templates. Given that Jekyll produces static sites, some of the original methods do not make logical sense to port (e.g. naturaltime).
- [Jekyll-Ordinal](https://github.com/PatrickC8t/Jekyll-Ordinal): Jekyll liquid filter to output a date ordinal such as "st", "nd", "rd", or "th".
- [Deprecated articles keeper](https://github.com/kzykbys/JekyllPlugins) by [Kazuya Kobayashi](http://blog.kazuya.co/): A simple Jekyll filter which monitor how old an article is.
@@ -754,6 +785,9 @@ LESS.js files during generation.
- [Jekyll Thumbnail Filter](https://github.com/matallo/jekyll-thumbnail-filter): Related posts thumbnail filter.
- [Jekyll-Smartify](https://github.com/pathawks/jekyll-smartify): SmartyPants filter. Make "quotes" “curly”
- [liquid-md5](https://github.com/pathawks/liquid-md5): Returns an MD5 hash. Helpful for generating Gravatars in templates.
+- [jekyll-roman](https://github.com/paulrobertlloyd/jekyll-roman): A liquid filter for Jekyll that converts numbers into Roman numerals.
+- [jekyll-typogrify](https://github.com/myles/jekyll-typogrify): A Jekyll plugin that brings the functions of [typogruby](http://avdgaag.github.io/typogruby/).
+- [Jekyll Email Protect](https://github.com/vwochnik/jekyll-email-protect): Email protection liquid filter for Jekyll
#### Tags
@@ -787,6 +821,7 @@ LESS.js files during generation.
- [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 [``](https://html.spec.whatwg.org/multipage/embedded-content.html#the-picture-element) 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.
+- [Jekyll Responsive Image](https://github.com/wildlyinaccurate/jekyll-responsive-image): Responsive images for Jekyll. Automatically resizes images, supports all responsive methods (``, `srcset`, Imager.js, etc), super-flexible configuration.
- [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.
- [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.
@@ -796,7 +831,7 @@ LESS.js files during generation.
- [Lychee Gallery Tag](https://gist.github.com/tobru/9171700) by [tobru](https://github.com/tobru): Include [Lychee](http://lychee.electerious.com/) albums into a post. For an introduction, see [Jekyll meets Lychee - A Liquid Tag plugin](https://tobrunet.ch/articles/jekyll-meets-lychee-a-liquid-tag-plugin/)
- [Image Set/Gallery Tag](https://github.com/callmeed/jekyll-image-set) by [callmeed](https://github.com/callmeed): Renders HTML for an image gallery from a folder in your Jekyll site. Just pass it a folder name and class/tag options.
- [jekyll_figure](https://github.com/lmullen/jekyll_figure): Generate figures and captions with links to the figure in a variety of formats
-- [Jekyll Github Sample Tag](https://github.com/bwillis/jekyll-github-sample): A liquid tag to include a sample of a github repo file in your Jekyll site.
+- [Jekyll GitHub Sample Tag](https://github.com/bwillis/jekyll-github-sample): A liquid tag to include a sample of a github repo file in your Jekyll site.
- [Jekyll Project Version Tag](https://github.com/rob-murray/jekyll-version-plugin): A Liquid tag plugin that renders a version identifier for your Jekyll site sourced from the git repository containing your code.
- [Piwigo Gallery](https://github.com/AlessandroLorenzi/piwigo_gallery) by [Alessandro Lorenzi](http://www.alorenzi.eu/): Jekyll plugin to generate thumbnails from a Piwigo gallery and display them with a Liquid tag
- [mathml.rb](https://github.com/tmthrgd/jekyll-plugins) by Tom Thorogood: A plugin to convert TeX mathematics into MathML for display.
@@ -805,9 +840,12 @@ LESS.js files during generation.
- [inline\_highlight](https://github.com/bdesham/inline_highlight): A tag for inline syntax highlighting.
- [jekyll-mermaid](https://github.com/jasonbellamy/jekyll-mermaid): Simplify the creation of mermaid diagrams and flowcharts in your posts and pages.
- [twa](https://github.com/Ezmyrelda/twa): Twemoji Awesome plugin for Jekyll. Liquid tag allowing you to use twitter emoji in your jekyll pages.
-- [jekyll-files](https://github.com/x43x61x69/jekyll-files) by [Zhi-Wei Cai](http://vox.vg/): Output relative path strings and other info regarding specific assets.
- [Fetch remote file content](https://github.com/dimitri-koenig/jekyll-plugins) by [Dimitri König](https://www.dimitrikoenig.net/): Using `remote_file_content` tag you can fetch the content of a remote file and include it as if you would put the content right into your markdown file yourself. Very useful for including code from github repo's to always have a current repo version.
- [jekyll-asciinema](https://github.com/mnuessler/jekyll-asciinema): A tag for embedding asciicasts recorded with [asciinema](https://asciinema.org) in your Jekyll pages.
+- [Jekyll-Youtube](https://github.com/dommmel/jekyll-youtube) A Liquid tag that embeds Youtube videos. The default emded markup is responsive but you can also specify your own by using an include/partial.
+- [Jekyll Flickr Plugin](https://github.com/lawmurray/indii-jekyll-flickr) by [Lawrence Murray](http://www.indii.org): Embeds Flickr photosets (albums) as a gallery of thumbnails, with lightbox links to larger images.
+- [jekyll-figure](https://github.com/paulrobertlloyd/jekyll-figure): A liquid tag for Jekyll that generates `` elements.
+- [Jekyll Video Embed](https://github.com/eug/jekyll-video-embed): It provides several tags to easily embed videos (e.g. Youtube, Vimeo, UStream and Ted Talks)
#### Collections
@@ -823,6 +861,7 @@ LESS.js files during generation.
- [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.
+- [jekyll-tagging-related_posts](https://github.com/toshimaru/jekyll-tagging-related_posts): Jekyll related_posts function based on tags (works on Jekyll3).
- [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.
@@ -835,13 +874,18 @@ LESS.js files during generation.
- [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.
+- [generator-jekyllrb](https://github.com/robwierzbowski/generator-jekyllrb): A generator that wraps Jekyll in [Yeoman](http://yeoman.io/), a tool collection and workflow for building 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.
-- [A layout that compresses HTML](http://jch.penibelst.de/): Github Pages compatible, configurable way to compress HTML files on site build.
+- [A layout that compresses HTML](http://jch.penibelst.de/): GitHub Pages compatible, configurable way to compress HTML files on site build.
- [Jekyll CO₂](https://github.com/wdenton/jekyll-co2): Generates HTML showing the monthly change in atmospheric CO₂ at the Mauna Loa observatory in Hawaii.
- [remote-include](http://www.northfieldx.co.uk/remote-include/): Includes files using remote URLs
- [jekyll-minifier](https://github.com/digitalsparky/jekyll-minifier): Minifies HTML, XML, CSS, and Javascript both inline and as separate files utilising yui-compressor and htmlcompressor.
+- [Jekyll views router](https://bitbucket.org/nyufac/jekyll-views-router): Simple router between generator plugins and templates.
+- [Jekyll Language Plugin](https://github.com/vwochnik/jekyll-language-plugin): Jekyll 3.0-compatible multi-language plugin for posts, pages and includes.
+- [Jekyll Deploy](https://github.com/vwochnik/jekyll-deploy): Adds a `deploy` sub-command to Jekyll.
+- [Official Contentful Jekyll Plugin](https://github.com/contentful/jekyll-contentful-data-import): Adds a `contentful` sub-command to Jekyll to import data from Contentful.
+- [jekyll-paspagon](https://github.com/KrzysiekJ/jekyll-paspagon): Sell your posts in various formats for cryptocurrencies.
#### Editors
@@ -849,6 +893,7 @@ LESS.js files during generation.
- [vim-jekyll](https://github.com/parkr/vim-jekyll): A vim plugin to generate
new posts and run `jekyll build` all without leaving vim.
- [markdown-writer](https://atom.io/packages/markdown-writer): An Atom package for Jekyll. It can create new posts/drafts, manage tags/categories, insert link/images and add many useful key mappings.
+- [Wordpress2Jekyll](https://wordpress.org/plugins/wp2jekyll/): A Wordpress plugin that allows you to use Wordpress as your editor and (automatically) export content in to Jekyll. WordPress2Jekyll attempts to marry these two systems together in order to make a site that can be easily managed from all devices.
Jekyll Plugins Wanted
diff --git a/site/_docs/posts.md b/site/_docs/posts.md
index ee02d06b..33710b53 100644
--- a/site/_docs/posts.md
+++ b/site/_docs/posts.md
@@ -6,16 +6,16 @@ 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!
+functionality. If you write articles and publish them online, 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 are generally
-[Markdown](http://daringfireball.net/projects/markdown/) or HTML, but can
+[Markdown](https://daringfireball.net/projects/markdown/) or HTML, but can
be other formats with the proper converter installed.
All posts must have [YAML Front Matter](../frontmatter/), and they will be
converted from their source format into an HTML page that is part of your
@@ -23,7 +23,7 @@ static site.
### Creating Post Files
-To create a new post, all you need to do is create a new file in the `_posts`
+To create a new post, all you need to do is create a 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:
@@ -53,7 +53,7 @@ file. For example, the following are examples of valid post filenames:
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
-[Markdown](http://daringfireball.net/projects/markdown/) out of the box,
+[Markdown](https://daringfireball.net/projects/markdown/) out of the box,
and has [myriad extensions for other formats as well](/docs/plugins/#converters-1),
including the popular [Textile](http://redcloth.org/textile) format. These
formats each have their own way of marking up different types of content
@@ -84,21 +84,21 @@ 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
+depend on the way your site’s (sub)domain and path are configured, but here are
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:
+... 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.
+... you can [get the PDF]({% raw %}{{ site.url }}{% endraw %}/assets/mydoc.pdf) directly.
{% endhighlight %}
@@ -116,8 +116,8 @@ Linking to a PDF for readers to download:
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:
+language](https://docs.shopify.com/themes/liquid/basics) and its tags. Here’s a
+basic example of how to create a list of links to your blog posts:
{% highlight html %}
diff --git a/site/_docs/quickstart.md b/site/_docs/quickstart.md
index d8ad5511..8a63cb33 100644
--- a/site/_docs/quickstart.md
+++ b/site/_docs/quickstart.md
@@ -14,8 +14,7 @@ For the impatient, here's how to get a boilerplate Jekyll site up and running.
# => Now browse to http://localhost:4000
{% endhighlight %}
-If you wish to install jekyll into the current directory, you can do so by
-alternatively running `jekyll new .` instead of a new directory name.
+If you wish to install jekyll into an existing directory, you can do so by running `jekyll new .` from within the directory instead of creating a new one. If the existing directory isn't empty, you'll also have to pass the `--force` option like so `jekyll new . --force`.
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
diff --git a/site/_docs/resources.md b/site/_docs/resources.md
index a730067a..0e403986 100644
--- a/site/_docs/resources.md
+++ b/site/_docs/resources.md
@@ -6,43 +6,33 @@ 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 FormKeep for Jekyll form backend and webhooks](https://formkeep.com/)
-- [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
+### Useful Guides
+- [“Creating and Hosting a Personal Site on GitHub”](http://jmcglone.com/guides/github-pages/)
+- [‘Build A Blog With Jekyll And GitHub Pages’ on Smashing Magazine](http://www.smashingmagazine.com/2014/08/01/build-blog-jekyll-github-pages/)
+- Publishing to GitHub Pages? [Check out our documentation page for just that purpose](/docs/github-pages/).
- [Blogging with Git, Emacs and Jekyll](http://metajack.im/2009/01/23/blogging-with-git-emacs-and-jekyll/)
+- [Tips for working with GitHub Pages Integration](https://gist.github.com/jedschneider/2890453)
-#### Other hacks
+### Integrations
+- [Use FormKeep as a backend for forms (contact forms, hiring forms, etc.)](https://formkeep.com/guides/how-to-make-a-contact-form-in-jekyll?utm_source=github&utm_medium=jekyll-docs&utm_campaign=contact-form-jekyll)
+- [Use Simple Form to add a simple contact form](http://getsimpleform.com/)
+- [Jekyll Bootstrap](http://jekyllbootstrap.com), 0 to Blog in 3 minutes. Provides detailed explanations, examples, and helper-code to make getting started with Jekyll easier.
- [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)
+
+### Other commentary
+
+- [‘My Jekyll Fork’, by Mike West](https://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 peace with the world.”
-- [‘Build A Blog With Jekyll And GitHub Pages’, by Barry Clark](http://www.smashingmagazine.com/2014/08/01/build-blog-jekyll-github-pages/)
- > “I recently migrated my blog from WordPress to Jekyll, a fantastic website generator that’s designed for building minimal, static blogs to be hosted on GitHub Pages. The simplicity of Jekyll’s theming layer and writing workflow is fantastic; however, setting up my website took a lot longer than expected. In this article we'll walk through: the quickest way to set up a Jekyll powered blog, how to avoid common problems with using Jekyll, how to import your content from Wordpress, and more.”
-- [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.
+- [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.
- A way to [extend Jekyll](https://github.com/rfelix/jekyll_ext) without forking and modifying the Jekyll gem codebase and some [portable Jekyll extensions](https://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)
-
-- [Adding Ajax pagination to Jekyll](https://eduardoboucas.com/blog/2014/11/10/adding-ajax-pagination-to-jekyll.html)
-
-- [Using Jekyll’s Data Files to build a dynamic navbar](http://blog.jordanthornquest.com/post/119506660470/building-dynamic-navbars-in-jekyll)
+- [Adding Ajax pagination to Jekyll](https://eduardoboucas.com/blog/2014/11/05/adding-ajax-pagination-to-jekyll.html)
diff --git a/site/_docs/sites.md b/site/_docs/sites.md
index c11da820..f0b1a9b2 100644
--- a/site/_docs/sites.md
+++ b/site/_docs/sites.md
@@ -10,16 +10,12 @@ learning purposes.
- [Tom Preston-Werner](http://tom.preston-werner.com/)
([source](https://github.com/mojombo/mojombo.github.io))
-- [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://training.github.com)
- ([source](https://github.com/github/training.github.com/tree/7049d7532a6856411e34046aedfce43a4afaf424))
+ ([source](https://github.com/github/training-kit))
- [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))
+- [Leonard Lamprecht](http://leo.im)
+ ([source](https://github.com/leo/leo.github.io))
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].
diff --git a/site/_docs/structure.md b/site/_docs/structure.md
index 53a48951..d4ba3ade 100644
--- a/site/_docs/structure.md
+++ b/site/_docs/structure.md
@@ -7,9 +7,9 @@ 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
+or a 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
+is all done through editing text files; the static web site is the final
product.
A basic Jekyll site usually looks something like this:
@@ -132,12 +132,13 @@ An overview of what each of these does:
- Well-formatted site data should be placed here. The jekyll engine
- will autoload all yaml files (ends with
- .yml or .yaml) in this directory. If
- there's a file members.yml under the directory,
- then you can access contents of the file
- through site.data.members.
+ Well-formatted site data should be placed here. The Jekyll engine
+ will autoload all YAML files in this directory (using either the
+ .yml, .yaml, .json or
+ .csv formats and extensions) and they will be
+ accessible via `site.data`. If there's a file
+ members.yml under the directory, then you can access
+ contents of the file through site.data.members.
diff --git a/site/_docs/templates.md b/site/_docs/templates.md
index 3e4cd8d0..60892505 100644
--- a/site/_docs/templates.md
+++ b/site/_docs/templates.md
@@ -186,6 +186,17 @@ common tasks easier.
@@ -317,16 +375,16 @@ such as using variables.
### 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 `highlighter` to `pygments` in your site's configuration
-file.
+Jekyll has built in support for syntax highlighting of over 60 languages
+thanks to [Rouge](http://rouge.jneen.net). Rouge is the default highlighter
+in Jekyll 3 and above. To use it in Jekyll 2, set `highlighter` to `rouge`
+and ensure the `rouge` gem is installed properly.
-Alternatively, you can use [Rouge](https://github.com/jayferd/rouge) to highlight
-your code snippets. It doesn't support as many languages as Pygments, however it
-should suit most use cases. Also, since [Rouge](https://github.com/jayferd/rouge)
-is written in pure Ruby, you don't need Python on your system!
+Alternatively, you can use [Pygments](http://pygments.org) to highlight
+your code snippets. To use Pygments, you must have Python installed on your
+system, have the `pygments.rb` gem installed and set `highlighter` to
+`pygments` in your site's configuration file. Pygments supports [over 100
+languages](http://pygments.org/languages/)
To render a code block with syntax highlighting, surround your code as follows:
@@ -342,9 +400,9 @@ end
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 [Pygments' Lexers
-page](http://pygments.org/docs/lexers/) or the [Rouge
-wiki](https://github.com/jayferd/rouge/wiki/List-of-supported-languages-and-lexers).
+you want to highlight, look for the “short name” on the [Rouge
+wiki](https://github.com/jayferd/rouge/wiki/List-of-supported-languages-and-lexers)
+or the [Pygments' Lexers page](http://pygments.org/docs/lexers/).
#### Line numbers
@@ -421,3 +479,6 @@ You may also optionally specify the filename in the gist to display:
{% gist parkr/931c1c8d465a04042403 jekyll-private-gist.markdown %}
{% endraw %}
{% endhighlight %}
+
+To use the `gist` tag, you'll need to add the
+[jekyll-gist](https://github.com/jekyll/jekyll-gist) gem to your project.
diff --git a/site/_docs/troubleshooting.md b/site/_docs/troubleshooting.md
index ee49c782..899f129e 100644
--- a/site/_docs/troubleshooting.md
+++ b/site/_docs/troubleshooting.md
@@ -30,6 +30,13 @@ On Red Hat, CentOS, and Fedora systems you can do this by running:
sudo yum install ruby-devel
{% endhighlight %}
+If you installed the above - specifically on Fedora 23 - but the extensions would still not compile, you are probably running a Fedora image that misses the `redhat-rpm-config` package. To solve this, simply run:
+
+{% highlight bash %}
+sudo dnf install redhat-rpm-config
+{% endhighlight %}
+
+
On [NearlyFreeSpeech](https://www.nearlyfreespeech.net/) you need to run the
following commands before installing Jekyll:
@@ -40,20 +47,6 @@ export PATH=$PATH:/home/private/gems/bin
export RB_USER_INSTALL='true'
{% endhighlight %}
-On Mac OS X, 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/ruby/os%20x/gem/mountain%20lion/2012/02/21/install-native-ruby-gem-in-mountain-lion-preview.html)
-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 %}
@@ -63,6 +56,85 @@ sudo emerge -av dev-ruby/rubygems
On Windows, you may need to install [RubyInstaller
DevKit](https://wiki.github.com/oneclick/rubyinstaller/development-kit).
+On Mac OS X, you may need to update RubyGems (using `sudo` only if necessary):
+
+{% highlight bash %}
+sudo gem update --system
+{% endhighlight %}
+
+If you still have issues, you can download and install new Command Line
+Tools (such as `gcc`) using the command
+
+{% highlight bash %}
+xcode-select --install
+{% endhighlight %}
+
+which may allow you to install native gems using this command (again using
+`sudo` only if necessary):
+
+{% highlight bash %}
+sudo gem install jekyll
+{% endhighlight %}
+
+Note that upgrading Mac OS X does not automatically upgrade Xcode itself
+(that can be done separately via the App Store), and having an out-of-date
+Xcode.app can interfere with the command line tools downloaded above. If
+you run into this issue, upgrade Xcode and install the upgraded Command
+Line Tools.
+
+### Jekyll & Mac OS X 10.11
+
+With the introduction of System Integrity Protection, several directories
+that were previously writable are now considered system locations and are no
+longer available. Given these changes, there are a couple of simple ways to get
+up and running. One option is to change the location where the gem will be
+installed (again using `sudo` only if necessary):
+
+{% highlight bash %}
+sudo gem install -n /usr/local/bin jekyll
+{% endhighlight %}
+
+Alternatively, Homebrew can be installed and used to set up Ruby. This can be
+done as follows:
+
+{% highlight bash %}
+ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+{% endhighlight %}
+
+Once Homebrew is installed, the second step is easy:
+
+{% highlight bash %}
+brew install ruby
+{% endhighlight %}
+
+Advanced users (with more complex needs) may find it helpful to choose one of a
+number of Ruby version managers ([RVM][], [rbenv][], [chruby][], [etc][].) in
+which to install Jekyll.
+
+[RVM]: https://rvm.io
+[rbenv]: http://rbenv.org
+[chruby]: https://github.com/postmodern/chruby
+[etc]: https://github.com/rvm/rvm/blob/master/docs/alt.md
+
+If you elect to use one of the above methods to install Ruby, it might be
+necessary to modify your `$PATH` variable using the following command:
+
+{% highlight bash %}
+export PATH=/usr/local/bin:$PATH
+{% endhighlight %}
+
+GUI apps can modify the `$PATH` as follows:
+
+{% highlight bash %}
+launchctl setenv PATH "/usr/local/bin:$PATH"
+{% endhighlight %}
+
+Either of these approaches are useful because `/usr/local` is considered a
+"safe" location on systems which have SIP enabled, they avoid potential
+conflicts with the version of Ruby included by Apple, and it keeps Jekyll and
+its dependencies in a sandboxed environment. This also has the added
+benefit of not requiring `sudo` when you want to add or remove a gem.
+
### Could not find a JavaScript runtime. (ExecJS::RuntimeUnavailable)
This error can occur during the installation of `jekyll-coffeescript` when
diff --git a/site/_docs/upgrading.md b/site/_docs/upgrading.md
index 51fe67a1..a1280672 100644
--- a/site/_docs/upgrading.md
+++ b/site/_docs/upgrading.md
@@ -4,137 +4,7 @@ title: Upgrading
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.
+Upgrading from an older version of Jekyll? Upgrading to a new major version of Jekyll (e.g. from v2.x to v3.x) may cause some headaches. Take the following guides to aid your upgrade:
-Before we dive in, go ahead and fetch the latest version of Jekyll:
-
-{% highlight bash %}
-$ gem update jekyll
-{% endhighlight %}
-
-
-
Diving in
-
Want to get a new Jekyll site up and running quickly? Simply
- run jekyll new SITENAME to create a new folder with a bare bones
- Jekyll site.
-
-
-### 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, in v2.0 (and later) you should
-use the subcommands `jekyll build` and `jekyll serve` to build and preview
-your site.
-
-
-
Watching and Serving
-
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 holds true for
- `watch: true`. Instead, use the `--watch` flag with either `jekyll serve`
- or `jekyll build`.
-
-
-### Absolute Permalinks
-
-In Jekyll v1.0, we introduced absolute permalinks for pages in
-subdirectories. Starting with v2.0, absolute permalinks are opt-out,
-meaning Jekyll will default to using absolute permalinks instead of
-relative permalinks. Relative permalink backwards-compatibility was removed in v3.0.
-
-
-
Absolute permalinks will be required in v3.0 and on
-
- Starting with Jekyll v3.0, relative permalinks functionality will be removed and thus unavailable for use.
-
-
-
-### 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.
-
-
-
Drafts don't have dates
-
- 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`.
-
-
-### 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` (now `--no-watch`)
-* `--auto` (now `--watch`)
-* `--server`
-* `--url=`
-* `--maruku`, `--rdiscount`, and `--redcarpet`
-* `--pygments`
-* `--permalink=`
-* `--paginate`
-
-
-
The config flag explicitly specifies your configuration file(s)
-
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.
-
-
-### 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.
-
-
-
-
All page and post URLs contain leading slashes
-
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 `/`.
-
+- [From 0.x to 1.x and 2.x](/docs/upgrading/0-to-2/)
+- [From 2.x to 3.x](/docs/upgrading/2-to-3/)
diff --git a/site/_docs/upgrading/0-to-2.md b/site/_docs/upgrading/0-to-2.md
new file mode 100644
index 00000000..84ec90e7
--- /dev/null
+++ b/site/_docs/upgrading/0-to-2.md
@@ -0,0 +1,140 @@
+---
+layout: docs
+title: Upgrading from 0.x to 2.x
+permalink: /docs/upgrading/0-to-2/
+---
+
+Upgrading from an older version of Jekyll? A few things have changed in 1.0
+and 2.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 %}
+
+
+
Diving in
+
Want to get a new Jekyll site up and running quickly? Simply
+ run jekyll new SITENAME to create a new folder with a bare bones
+ Jekyll site.
+
+
+### 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, in v2.0 (and later) you should
+use the subcommands `jekyll build` and `jekyll serve` to build and preview
+your site.
+
+
+
Watching and Serving
+
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 holds true for
+ `watch: true`. Instead, use the `--watch` flag with either `jekyll serve`
+ or `jekyll build`.
+
+
+### Absolute Permalinks
+
+In Jekyll v1.0, we introduced absolute permalinks for pages in
+subdirectories. Starting with v2.0, absolute permalinks are opt-out,
+meaning Jekyll will default to using absolute permalinks instead of
+relative permalinks. Relative permalink backwards-compatibility was removed in v3.0.
+
+
+
Absolute permalinks will be required in v3.0 and on
+
+ Starting with Jekyll v3.0, relative permalinks functionality will be removed and thus unavailable for use.
+
+
+
+### 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.
+
+
+
Drafts don't have dates
+
+ 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`.
+
+
+### 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` (now `--no-watch`)
+* `--auto` (now `--watch`)
+* `--server`
+* `--url=`
+* `--maruku`, `--rdiscount`, and `--redcarpet`
+* `--pygments`
+* `--permalink=`
+* `--paginate`
+
+
+
The config flag explicitly specifies your configuration file(s)
+
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.
+
+
+### 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.
+
+
+
+
All page and post URLs contain leading slashes
+
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 `/`.
+
diff --git a/site/_docs/upgrading/2-to-3.md b/site/_docs/upgrading/2-to-3.md
new file mode 100644
index 00000000..e6fb2366
--- /dev/null
+++ b/site/_docs/upgrading/2-to-3.md
@@ -0,0 +1,130 @@
+---
+layout: docs
+title: Upgrading from 2.x to 3.x
+permalink: /docs/upgrading/2-to-3/
+---
+
+Upgrading from an older version of Jekyll? A few things have changed in 3.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 %}
+
+Please note: Jekyll 3 requires Ruby version >= 2.0.0.
+
+
+
Diving in
+
Want to get a new Jekyll site up and running quickly? Simply
+ run jekyll new SITENAME to create a new folder with a bare bones
+ Jekyll site.
+
+
+### site.collections has changed
+
+In 2.x, your iterations over `site.collections` yielded an array with the collection
+label and the collection object as the first and second items, respectively. In 3.x,
+this complication has been removed and iterations now yield simply the collection object.
+A simple conversion must be made in your templates:
+
+- `collection[0]` becomes `collection.label`
+- `collection[1]` becomes `collection`
+
+When iterating over `site.collections`, ensure the above conversions are made.
+
+For `site.collections.myCollection` in Jekyll 2, you now do:
+
+{% highlight liquid %}
+{% raw %}
+{% assign myCollection = site.collections | where: "label", "myCollection" | first %}
+{% endraw %}
+{% endhighlight %}
+
+This is a bit cumbersome at first, but is easier than a big `for` loop.
+
+### Dropped dependencies
+
+We dropped a number of dependencies the Core Team felt were optional. As such, in 3.0, they must be explicitly installed and included if you use any of the features. They are:
+
+- jekyll-paginate – Jekyll's pagination solution from days past
+- jekyll-coffeescript – processing of CoffeeScript
+- jekyll-gist – the `gist` Liquid tag
+- pygments.rb – the Pygments highlighter
+- redcarpet – the Markdown processor
+- toml – an alternative to YAML for configuration files
+- classifier-reborn – for `site.related_posts`
+
+### Future posts
+
+A seeming feature regression in 2.x, the `--future` flag was automatically _enabled_.
+The future flag allows post authors to give the post a date in the future and to have
+it excluded from the build until the system time is equal or after the post time.
+In Jekyll 3, this has been corrected. **Now, `--future` is disabled by default.**
+This means you will need to include `--future` if you want your future-dated posts to
+generate when running `jekyll build` or `jekyll serve`.
+
+### Layout metadata
+
+Introducing: `layout`. In Jekyll 2 and below, any metadata in the layout was merged onto
+the `page` variable in Liquid. This caused a lot of confusion in the way the data was
+merged and some unexpected behaviour. In Jekyll 3, all layout data is accessible via `layout`
+in Liquid. For example, if your layout has `class: my-layout` in its YAML front matter,
+then the layout can access that via `{% raw %}{{ layout.class }}{% endraw %}`.
+
+### Syntax highlighter changed
+
+For the first time, the default syntax highlighter has changed for the
+`highlight` tag and for backtick code blocks. Instead of [Pygments.rb](https://github.com/tmm1/pygments.rb),
+it's now [Rouge](http://rouge.jneen.net/). If you were using the `highlight` tag with certain
+options, such as `hl_lines`, they may not be available when using Rouge. To
+go back to using Pygments, set `highlighter: pygments` in your
+`_config.yml` file and run `gem install pygments.rb` or add
+`gem 'pygments.rb'` to your project's `Gemfile`.
+
+### Relative Permalink support removed
+
+In Jekyll 3 and above, relative permalinks have been deprecated. If you
+created your site using Jekyll 2 and below, you may receive the following
+error when trying to **serve** or **build**:
+
+{% highlight text %}
+Since v3.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.
+{% endhighlight %}
+
+This can be fixed by removing the following line from your `_config.yml` file:
+
+{% highlight yaml %}
+relative_permalinks: true
+{% endhighlight %}
+
+### Permalinks no longer automatically add a trailing slash
+
+In Jekyll 2, any URL constructed from the `permalink:` field had a trailing slash (`/`) added to it automatically. Jekyll 3 no longer adds a trailing slash automatically to `permalink:` URLs. This can potentially result in old links to pages returning a 404 error. For example, suppose a page previously contained the YAML `permalink: /:year-:month-:day-:title` that resulted in the URL `example.com/2016-02-01-test/` (notice the trailing slash), Jekyll internally generates a folder named `2016-02-01-test`. In Jekyll 3, the same `permalink:` generate the file `2016-02-01-test.html` and the URL for the same page will be `example.com/2016-02-01-test`, and consequently any links to the old URL will result in a 404 error. In order to maintain the same URLs and avoid this problem, a trailing slash should be added to the `permalink:` field, for example `permalink: /:year-:month-:day-:title/`.
+
+### All my posts are gone! Where'd they go!
+
+Try adding `future: true` to your `_config.yml` file. Are they showing up now? If they are, then you were ensnared by an issue with the way Ruby parses times. Each of your posts is being read in a different timezone than you might expect and, when compared to the computer's current time, is "in the future." The fix for this is to add [a timezone offset](https://en.wikipedia.org/wiki/List_of_UTC_time_offsets) to each post (and make sure you remove `future: true` from your `_config.yml` file). If you're writing from California, for example, you would change this:
+
+{% highlight yaml %}
+---
+date: 2016-02-06 19:32:10
+---
+{% endhighlight %}
+
+to this (note the offset):
+
+{% highlight yaml %}
+---
+date: 2016-02-06 19:32:10 -0800
+---
+{% endhighlight %}
+
+### My categories have stopped working!
+
+If you organized your categories as `/_posts/code/2008-12-24-closures.md`, you will need to restructure your directories to put the categories _above_ the `_posts` directories, as follows: `/code/_posts/2008-12-24-closures.md`.
+
+_Did we miss something? Please click "Improve this page" above and add a section. Thanks!_
diff --git a/site/_docs/usage.md b/site/_docs/usage.md
index 7a424bd4..28c4efb0 100644
--- a/site/_docs/usage.md
+++ b/site/_docs/usage.md
@@ -22,6 +22,18 @@ $ jekyll build --watch
# watched for changes, and regenerated automatically.
{% endhighlight %}
+
+
Changes to _config.yml are not included during automatic regeneration.
+
+ The _config.yml master configuration file contains global configurations
+ and variable definitions that are read once at execution time. Changes made to _config.yml
+ during automatic regeneration are not loaded until the next execution.
+
+
+ Note Data Files are included and reloaded during automatic regeneration.
+
+
+
Destination folders are cleaned on site builds
diff --git a/site/_docs/variables.md b/site/_docs/variables.md
index d3c5d946..33b99fa5 100644
--- a/site/_docs/variables.md
+++ b/site/_docs/variables.md
@@ -106,7 +106,7 @@ following is a reference of the available data.
related Posts. By default, these are the ten most recent posts.
For high quality but slow to compute results, run the
jekyll command with the --lsi (latent semantic
- indexing) option. Also note Github pages does not support the lsi option when generating sites.
+ indexing) option. Also note GitHub Pages does not support the lsi option when generating sites.
@@ -125,7 +125,15 @@ following is a reference of the available data.
site.html_pages
- A list of all HTML Pages.
+ A subset of `site.pages` listing those which end in `.html`.
+
+
+
+
+
site.html_files
+
+
+ A subset of `site.static_files` listing those which end in `.html`.
diff --git a/site/_docs/windows.md b/site/_docs/windows.md
index a3e6b5f0..c573747d 100644
--- a/site/_docs/windows.md
+++ b/site/_docs/windows.md
@@ -11,9 +11,11 @@ knowledge and lessons that have been unearthed by Windows users.
## Installation
Julian Thilo has written up instructions to get
-[Jekyll running on Windows][windows-installation] and it seems to work for most.
-The instructions were written for Ruby 2.0.0, but should work for later versions
-[prior to 2.2][hitimes-issue].
+[Jekyll running on Windows][windows-installation] and it seems to work for most
+people. The instructions were written for Ruby 2.0.0, but should work for later
+versions [prior to 2.2][hitimes-issue].
+
+Alternatively David Burela has written instructions on [how to install Jekyll via Chocolatey with 3 command prompt entries](https://davidburela.wordpress.com/2015/11/28/easily-install-jekyll-on-windows-with-3-command-prompt-entries-and-chocolatey/).
## Encoding
diff --git a/site/_includes/docs_ul.html b/site/_includes/docs_ul.html
index 7cc54174..34b6278a 100644
--- a/site/_includes/docs_ul.html
+++ b/site/_includes/docs_ul.html
@@ -10,12 +10,8 @@
{% assign c = "" %}
{% endif %}
- {% for p in site.docs %}
- {% if p.url == item_url %}
-